fix(desktop+supabase): OAuth 로그인 완주 + RLS 재귀 픽스 (빅뱅 Phase 5 Part 1)
빅뱅 Phase 5 실증 중 발견한 3개 버그 해결:
1. implicit flow 응답 무시:
- supabase-js가 persistSession:false 일 때 PKCE code_verifier 저장 못해
implicit flow로 fallback, fragment(#access_token=...&refresh_token=...)로
토큰 전달. handleDeepLink는 ?code=만 파싱하고 있어 무시됨.
- handleDeepLink에 fragment parser 추가 (access_token + refresh_token)
- CloudSyncService.handleAuthTokens() 신규 — setSession() 후
기존 _onAuthenticated SSOT로 수렴
- 에러 query/fragment(error, error_description) 상세 로깅
- 토큰 값은 로그에 안 찍히도록 (query=yes/no, fragment=yes/no 만)
2. Supabase RLS 무한 재귀:
- team_members_read_same_team 정책이 자기 테이블 재조회 →
Postgres RLS 엔진 무한 재귀 탐지 에러
- meetings / meeting_memos / meeting_documents / team_invites 정책이
team_members 서브쿼리 경유해서 전부 같이 터짐 + Realtime TIMED_OUT
- migration 20260411000001: SECURITY DEFINER 함수 2개
(user_team_ids, user_admin_team_ids) 신규 — Supabase 권장 패턴
- 영향 정책: team_members(4) + meetings(2) + meeting_memos(1) +
meeting_documents(2) + team_invites(1) 전부 함수 기반으로 재작성
- supabase db push 완료
3. LoginScreen stale 번들:
- Phase 1.5에서 import 제거했는데도 vite HMR/cache 어딘가에서
stale state 유지해서 렌더러에 계속 뜸
- LoginScreen.tsx 파일 자체 삭제 (vite 컴파일 대상 제거)
로그인 성공 확인: yunchan8804@gmail.com 으로 Google OAuth 완주 →
users/7da3dd02-9f2f-4ee9-a9b3-1c2c24875a93/d3ro.db 생성 → Initial sync 시작.
This commit is contained in:
parent
817b4a2580
commit
9498380f7f
5 changed files with 305 additions and 125 deletions
|
|
@ -447,7 +447,7 @@ class CloudSyncService extends EventEmitter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deep link 콜백 처리 — code를 session으로 교환.
|
||||
* Deep link 콜백 처리 — PKCE flow code를 session으로 교환.
|
||||
* 성공 시 _onAuthenticated(단일 진입점)로 수렴.
|
||||
*/
|
||||
async handleAuthCallback(code: string): Promise<void> {
|
||||
|
|
@ -469,6 +469,40 @@ class CloudSyncService extends EventEmitter {
|
|||
await this._onAuthenticated(data.session, { reason: 'signin' })
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep link 콜백 처리 — Implicit flow로 받은 access/refresh token을
|
||||
* client.auth.setSession()에 주입하여 세션 복원.
|
||||
*
|
||||
* supabase-js가 `persistSession: false`로 떠 있을 때 PKCE code_verifier 저장이
|
||||
* 없어서 PKCE가 제대로 동작하지 않는다. Supabase가 implicit flow로 떨어져
|
||||
* fragment(#access_token=...&refresh_token=...)에 토큰을 담아 보내는데, 이때
|
||||
* 이 메서드를 사용한다.
|
||||
*/
|
||||
async handleAuthTokens(params: {
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
}): Promise<void> {
|
||||
if (!this._client) {
|
||||
throw new D3ROError(ErrorCode.LLMServerUnreachable, 'Cloud Sync가 설정되지 않았습니다')
|
||||
}
|
||||
|
||||
const { data, error } = await this._client.auth.setSession({
|
||||
access_token: params.accessToken,
|
||||
refresh_token: params.refreshToken,
|
||||
})
|
||||
if (error || !data.session) {
|
||||
throw new D3ROError(
|
||||
ErrorCode.LLMProcessingFailed,
|
||||
`세션 설정 실패: ${error?.message ?? 'unknown'}`
|
||||
)
|
||||
}
|
||||
|
||||
this._saveRefreshToken(data.session.refresh_token)
|
||||
logger.info(`Signed in (implicit): ${data.session.user.email ?? data.session.user.id}`)
|
||||
|
||||
await this._onAuthenticated(data.session, { reason: 'signin' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 로그아웃 — 단일 진입점 _onSignOut에서 세션/DB/녹음 모두 안전하게 정리.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue