feat(auth): migrate Flutter IAuthPlatform to Next.js 16 SDK service layer

Adds the third-party social login SDK integration layer (Google + Facebook),
mirroring the Flutter `IAuthPlatform` interface from
`lib/data/services/auth/`. The platform produces identity tokens only; callers
use the existing `authRepository.googleLogin / facebookLogin /
facebookIdLogin` (already migrated) to complete the login.

Architecture (event-bridge pattern):
  - `IAuthPlatform` is plain TypeScript (no React dependency)
  - `WebAuthPlatform` dispatches DOM `CustomEvent`s; `AuthPlatformBridge`
    ("use client" component) hosts the React SDK hooks and resolves promises
  - `MockAuthPlatform` returns hardcoded tokens when
    `NEXT_PUBLIC_USE_MOCK_AUTH=true` (mirrors Dart `kDebugMode` branch)

SDK choices:
  - `@react-oauth/google@0.13.5` for Google
  - `@greatsumini/react-facebook-login@3.4.0` (maintained fork of
    archived `react-facebook`, React 19 compatible) for Facebook
  - For Google: uses raw GIS `google.accounts.id.initialize` + `prompt` API
    since `@react-oauth/google` does not expose an `id_token` flow variant
    (existing `GoogleLoginRequest.idToken` field expects JWT id_token)

Files added:
  - src/data/services/auth/{auth_platform,web_auth_platform,
    mock_auth_platform,auth_event_bridge,auth_bridge_component,
    initialize_google_auth,initialize_facebook_auth,global.d.ts,index}.ts(x)
  - src/data/schemas/auth/facebook_user_data.ts (Zod schema)
  - src/data/dto/auth/facebook_user_data.ts (DTO class)

Files modified:
  - package.json, pnpm-lock.yaml: added 2 deps
  - .env.example: 4 new NEXT_PUBLIC_* env vars
  - barrelsby.json: registered src/data/services[/auth] directories
  - implementation_plan.md: appended third-party auth section
  - src/data/dto/{auth,chat,metrics,user}/index.ts: regenerated barrels
  - src/data/schemas/{auth,chat,metrics,user}/index.ts: regenerated barrels

Files deleted:
  - src/data/storage/index.ts: pre-existing TS2308 conflict (sync + async
    `AuthStorage` both re-exported from auto-generated barrel; no consumer
    uses the barrel — all imports use direct paths)

Scope (per user direction):
  - Client SDK integration only; no React hook/context, no UI, no Apple
  - Platform produces tokens; caller drives `authRepository` / `authApi`
  - v1 single-popup semantics (concurrent popups overwrite)
  - Bridge component is code-ready but NOT mounted in
    `src/app/layout.tsx`; next-step UI migration wires the provider chain

Verified: `npx tsc --noEmit` (0 errors), `pnpm lint` (0 errors),
`pnpm build` (Next.js 16.2.7 + Turbopack compiled successfully).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2026-06-09 11:02:55 +08:00
committed by chenhang
parent 904cb3638a
commit b362945195
26 changed files with 1118 additions and 20 deletions
+26
View File
@@ -11,6 +11,12 @@ importers:
'@fingerprintjs/fingerprintjs':
specifier: ^5.2.0
version: 5.2.0
'@greatsumini/react-facebook-login':
specifier: ^3.4.0
version: 3.4.0(react@19.2.4)
'@react-oauth/google':
specifier: ^0.13.5
version: 0.13.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
dexie:
specifier: ^4.4.3
version: 4.4.3
@@ -181,6 +187,11 @@ packages:
'@fingerprintjs/fingerprintjs@5.2.0':
resolution: {integrity: sha512-j+2nInkwCQNTJcNhOjvkGM/nLRTuGJTC6xai4quqvUpjob2ssrGwBZjS7k55nOmKvge7qvJT2nS3i/IRvQSTQA==}
'@greatsumini/react-facebook-login@3.4.0':
resolution: {integrity: sha512-NJYqTOcDghZ6zLppC+LJVLep7Xi3gfx9ssQFRd7EhDTU07lC15SG/eZ3ZyvUPsuPBkbhVl6E/Py0w4M5m7Lh9Q==}
peerDependencies:
react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0
'@humanfs/core@0.19.2':
resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
engines: {node: '>=18.18.0'}
@@ -450,6 +461,12 @@ packages:
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
engines: {node: '>=12.4.0'}
'@react-oauth/google@0.13.5':
resolution: {integrity: sha512-xQWri2s/3nNekZJ4uuov2aAfQYu83bN3864KcFqw2pK1nNbFurQIjPFDXhWaKH3IjYJ2r/9yyIIpsn5lMqrheQ==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@@ -2317,6 +2334,10 @@ snapshots:
'@fingerprintjs/fingerprintjs@5.2.0': {}
'@greatsumini/react-facebook-login@3.4.0(react@19.2.4)':
dependencies:
react: 19.2.4
'@humanfs/core@0.19.2':
dependencies:
'@humanfs/types': 0.15.0
@@ -2500,6 +2521,11 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
'@react-oauth/google@0.13.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
'@rtsao/scc@1.1.0': {}
'@swc/helpers@0.5.15':