@spfn/auth 0.2.0-beta.11 → 0.2.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @spfn/auth - Technical Documentation
2
2
 
3
- **Version:** 0.2.0-beta.11
3
+ **Version:** 0.2.0-beta.12
4
4
  **Status:** Alpha - Internal Development
5
5
 
6
6
  > **Note:** This is a technical documentation for developers working on the @spfn/auth package.
@@ -18,6 +18,7 @@
18
18
  - [Module Exports](#module-exports)
19
19
  - [Email & SMS Services](#email--sms-services)
20
20
  - [Server-Side API](#server-side-api)
21
+ - [OAuth Authentication](#oauth-authentication)
21
22
  - [Database Schema](#database-schema)
22
23
  - [RBAC System](#rbac-system)
23
24
  - [Next.js Adapter](#nextjs-adapter)
@@ -34,10 +35,11 @@
34
35
 
35
36
  - **Asymmetric JWT Authentication** - Client-signed tokens using ES256/RS256
36
37
  - **User Management** - Email/phone-based identity with bcrypt hashing
38
+ - **OAuth Authentication** - Google OAuth 2.0 (Authorization Code Flow), extensible to other providers
37
39
  - **Multi-Factor Authentication** - OTP verification via email/SMS
38
40
  - **Session Management** - Public key rotation with 90-day expiry
39
41
  - **Role-Based Access Control** - Flexible RBAC with runtime role/permission management
40
- - **Next.js Integration** - Session helpers and server-side guards
42
+ - **Next.js Integration** - Session helpers, server-side guards, and OAuth interceptors
41
43
 
42
44
  ### Design Principles
43
45
 
@@ -130,6 +132,16 @@ SPFN_AUTH_JWT_EXPIRES_IN=7d
130
132
  SPFN_AUTH_BCRYPT_SALT_ROUNDS=10
131
133
  SPFN_AUTH_SESSION_TTL=7d
132
134
 
135
+ # Google OAuth
136
+ SPFN_AUTH_GOOGLE_CLIENT_ID=123456789-abc.apps.googleusercontent.com
137
+ SPFN_AUTH_GOOGLE_CLIENT_SECRET=GOCSPX-...
138
+ SPFN_APP_URL=http://localhost:3000
139
+
140
+ # Google OAuth (Optional)
141
+ SPFN_AUTH_GOOGLE_REDIRECT_URI=http://localhost:8790/_auth/oauth/google/callback
142
+ SPFN_AUTH_OAUTH_SUCCESS_URL=/auth/callback
143
+ SPFN_AUTH_OAUTH_ERROR_URL=http://localhost:3000/auth/error?error={error}
144
+
133
145
  # AWS SES (Email)
134
146
  SPFN_AUTH_AWS_REGION=ap-northeast-2
135
147
  SPFN_AUTH_AWS_SES_ACCESS_KEY_ID=AKIA...
@@ -719,9 +731,11 @@ import {
719
731
  loginRegisterInterceptor,
720
732
  generalAuthInterceptor,
721
733
  keyRotationInterceptor,
734
+ oauthUrlInterceptor,
735
+ oauthFinalizeInterceptor,
722
736
  } from '@spfn/auth/nextjs/api';
723
737
 
724
- // Auto-registers interceptors on import
738
+ // Auto-registers interceptors on import (including OAuth)
725
739
  import '@spfn/auth/nextjs/api';
726
740
  ```
727
741
 
@@ -1019,6 +1033,266 @@ Change password.
1019
1033
 
1020
1034
  ---
1021
1035
 
1036
+ ## OAuth Authentication
1037
+
1038
+ ### Overview
1039
+
1040
+ `@spfn/auth`는 OAuth 2.0 Authorization Code Flow를 지원합니다. 현재 Google OAuth가 구현되어 있으며, 다른 provider (GitHub, Kakao, Naver)는 동일한 패턴으로 확장 가능합니다.
1041
+
1042
+ **핵심 설계:**
1043
+ - 환경 변수만으로 설정 (`SPFN_AUTH_GOOGLE_CLIENT_ID`, `SPFN_AUTH_GOOGLE_CLIENT_SECRET`)
1044
+ - Next.js 인터셉터 기반 자동 세션 관리 (키쌍 생성 → pending session → full session)
1045
+ - 기존 이메일 계정과 자동 연결 (Google verified_email 확인 시에만)
1046
+
1047
+ ---
1048
+
1049
+ ### Authentication Flow
1050
+
1051
+ ```
1052
+ ┌──────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
1053
+ │ Client │ │ Next.js RPC │ │ Backend │ │ Google │
1054
+ │ (Browser)│ │ (Interceptor)│ │ (SPFN) │ │ OAuth │
1055
+ └────┬─────┘ └──────┬───────┘ └────┬─────┘ └────┬─────┘
1056
+ │ │ │ │
1057
+ │ 1. Click Login │ │ │
1058
+ ├──────────────────>│ │ │
1059
+ │ │ │ │
1060
+ │ 2. Generate keypair (ES256) │ │
1061
+ │ 3. Create encrypted state │ │
1062
+ │ (publicKey, keyId in JWE) │ │
1063
+ │ 4. Save privateKey to │ │
1064
+ │ pending session cookie │ │
1065
+ │ │ │ │
1066
+ │ │ 5. Forward with │ │
1067
+ │ │ state in body │ │
1068
+ │ ├─────────────────>│ │
1069
+ │ │ │ │
1070
+ │ │ 6. Return Google │ │
1071
+ │ │ Auth URL │ │
1072
+ │ │<─────────────────┤ │
1073
+ │ │ │ │
1074
+ │ 7. Redirect to Google │ │
1075
+ │<──────────────────┤ │ │
1076
+ │ │ │ │
1077
+ │ 8. User consents │ │ │
1078
+ ├───────────────────┼──────────────────┼────────────────>│
1079
+ │ │ │ │
1080
+ │ │ 9. Callback with code + state │
1081
+ │ │ │<────────────────┤
1082
+ │ │ │ │
1083
+ │ │ 10. Verify state, exchange code │
1084
+ │ │ Create/link user account │
1085
+ │ │ Register publicKey │
1086
+ │ │ │ │
1087
+ │ 11. Redirect to /auth/callback │ │
1088
+ │ ?userId=X&keyId=Y&returnUrl=/ │ │
1089
+ │<─────────────────────────────────────┤ │
1090
+ │ │ │ │
1091
+ │ 12. OAuthCallback │ │ │
1092
+ │ component │ │ │
1093
+ │ calls finalize│ │ │
1094
+ ├──────────────────>│ │ │
1095
+ │ │ │ │
1096
+ │ 13. Interceptor reads pending │ │
1097
+ │ session cookie, verifies │ │
1098
+ │ keyId match, creates full │ │
1099
+ │ session cookie │ │
1100
+ │ │ │ │
1101
+ │ 14. Session set, │ │ │
1102
+ │ redirect to │ │ │
1103
+ │ returnUrl │ │ │
1104
+ │<──────────────────┤ │ │
1105
+ │ │ │ │
1106
+ ```
1107
+
1108
+ ---
1109
+
1110
+ ### Setup
1111
+
1112
+ #### 1. Google Cloud Console
1113
+
1114
+ 1. [Google Cloud Console](https://console.cloud.google.com/) > APIs & Services > Credentials
1115
+ 2. Create OAuth 2.0 Client ID (Web application)
1116
+ 3. Add Authorized redirect URI: `http://localhost:8790/_auth/oauth/google/callback`
1117
+ 4. Copy Client ID and Client Secret
1118
+
1119
+ #### 2. Environment Variables
1120
+
1121
+ ```bash
1122
+ # Required
1123
+ SPFN_AUTH_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
1124
+ SPFN_AUTH_GOOGLE_CLIENT_SECRET=GOCSPX-your-secret
1125
+
1126
+ # Next.js app URL (for OAuth callback redirect)
1127
+ SPFN_APP_URL=http://localhost:3000
1128
+
1129
+ # Optional
1130
+ SPFN_AUTH_GOOGLE_REDIRECT_URI=http://localhost:8790/_auth/oauth/google/callback # default
1131
+ SPFN_AUTH_OAUTH_SUCCESS_URL=/auth/callback # default
1132
+ ```
1133
+
1134
+ #### 3. Next.js Callback Page
1135
+
1136
+ ```tsx
1137
+ // app/auth/callback/page.tsx
1138
+ export { OAuthCallback as default } from '@spfn/auth/nextjs/client';
1139
+ ```
1140
+
1141
+ #### 4. Login Button
1142
+
1143
+ ```typescript
1144
+ import { authApi } from '@spfn/auth';
1145
+
1146
+ const handleGoogleLogin = async () =>
1147
+ {
1148
+ const response = await authApi.getGoogleOAuthUrl.call({
1149
+ body: { returnUrl: '/dashboard' },
1150
+ });
1151
+ window.location.href = response.authUrl;
1152
+ };
1153
+ ```
1154
+
1155
+ ---
1156
+
1157
+ ### OAuth Routes
1158
+
1159
+ #### `GET /_auth/oauth/google`
1160
+
1161
+ Google OAuth 시작 (리다이렉트 방식). 브라우저를 Google 로그인 페이지로 직접 리다이렉트합니다.
1162
+
1163
+ **Query:**
1164
+ ```typescript
1165
+ {
1166
+ state: string; // Encrypted OAuth state (JWE)
1167
+ }
1168
+ ```
1169
+
1170
+ ---
1171
+
1172
+ #### `POST /_auth/oauth/google/url`
1173
+
1174
+ Google OAuth URL 획득 (인터셉터 방식). 인터셉터가 state를 자동 생성하여 주입합니다.
1175
+
1176
+ **Request:**
1177
+ ```typescript
1178
+ {
1179
+ returnUrl?: string; // Default: '/'
1180
+ }
1181
+ ```
1182
+
1183
+ **Response:**
1184
+ ```typescript
1185
+ {
1186
+ authUrl: string; // Google OAuth URL
1187
+ }
1188
+ ```
1189
+
1190
+ ---
1191
+
1192
+ #### `GET /_auth/oauth/google/callback`
1193
+
1194
+ Google에서 리다이렉트되는 콜백. code를 token으로 교환하고 사용자를 생성/연결합니다.
1195
+
1196
+ **Query (from Google):**
1197
+ ```typescript
1198
+ {
1199
+ code?: string; // Authorization code
1200
+ state?: string; // OAuth state
1201
+ error?: string; // Error code
1202
+ error_description?: string; // Error description
1203
+ }
1204
+ ```
1205
+
1206
+ **Result:** Next.js 콜백 페이지로 리다이렉트 (`/auth/callback?userId=X&keyId=Y&returnUrl=/`)
1207
+
1208
+ ---
1209
+
1210
+ #### `POST /_auth/oauth/finalize`
1211
+
1212
+ OAuth 세션 완료. 인터셉터가 pending session에서 full session을 생성합니다.
1213
+
1214
+ **Request:**
1215
+ ```typescript
1216
+ {
1217
+ userId: string;
1218
+ keyId: string;
1219
+ returnUrl?: string;
1220
+ }
1221
+ ```
1222
+
1223
+ **Response:**
1224
+ ```typescript
1225
+ {
1226
+ success: boolean;
1227
+ returnUrl: string;
1228
+ }
1229
+ ```
1230
+
1231
+ ---
1232
+
1233
+ #### `GET /_auth/oauth/providers`
1234
+
1235
+ 활성화된 OAuth provider 목록을 반환합니다.
1236
+
1237
+ **Response:**
1238
+ ```typescript
1239
+ {
1240
+ providers: ('google' | 'github' | 'kakao' | 'naver')[];
1241
+ }
1242
+ ```
1243
+
1244
+ ---
1245
+
1246
+ ### Security
1247
+
1248
+ - **State 암호화**: JWE (A256GCM)로 state 파라미터 암호화. CSRF 방지용 nonce 포함.
1249
+ - **Pending Session**: OAuth 리다이렉트 중 privateKey를 JWE로 암호화한 HttpOnly 쿠키에 저장. 10분 TTL.
1250
+ - **KeyId 검증**: finalize 시 pending session의 keyId와 응답의 keyId 일치 확인.
1251
+ - **Email 검증**: `verified_email`이 true인 경우에만 기존 계정에 자동 연결. 미검증 이메일로 기존 계정 연결 시도 시 에러.
1252
+ - **Session Cookie**: `HttpOnly`, `Secure` (production), `SameSite=strict`.
1253
+
1254
+ ---
1255
+
1256
+ ### OAuthCallback Component
1257
+
1258
+ `@spfn/auth/nextjs/client`에서 제공하는 클라이언트 컴포넌트입니다.
1259
+
1260
+ ```tsx
1261
+ import { OAuthCallback } from '@spfn/auth/nextjs/client';
1262
+
1263
+ // 기본 사용
1264
+ export default function CallbackPage()
1265
+ {
1266
+ return <OAuthCallback />;
1267
+ }
1268
+
1269
+ // 커스터마이징
1270
+ export default function CallbackPage()
1271
+ {
1272
+ return (
1273
+ <OAuthCallback
1274
+ apiBasePath="/api/rpc"
1275
+ loadingComponent={<MySpinner />}
1276
+ errorComponent={(error) => <MyError message={error} />}
1277
+ onSuccess={(userId) => console.log('Logged in:', userId)}
1278
+ onError={(error) => console.error(error)}
1279
+ />
1280
+ );
1281
+ }
1282
+ ```
1283
+
1284
+ **Props:**
1285
+
1286
+ | Prop | Type | Default | Description |
1287
+ |------|------|---------|-------------|
1288
+ | `apiBasePath` | `string` | `'/api/rpc'` | RPC API base path |
1289
+ | `loadingComponent` | `ReactNode` | Built-in | 로딩 중 표시할 컴포넌트 |
1290
+ | `errorComponent` | `(error: string) => ReactNode` | Built-in | 에러 표시 컴포넌트 |
1291
+ | `onSuccess` | `(userId: string) => void` | - | 성공 콜백 |
1292
+ | `onError` | `(error: string) => void` | - | 에러 콜백 |
1293
+
1294
+ ---
1295
+
1022
1296
  ## Database Schema
1023
1297
 
1024
1298
  ### Core Tables
@@ -1252,7 +1526,7 @@ CREATE TABLE user_profiles (
1252
1526
 
1253
1527
  #### `user_social_accounts`
1254
1528
 
1255
- OAuth provider accounts (future feature).
1529
+ OAuth provider accounts (Google, GitHub, etc.).
1256
1530
 
1257
1531
  ```sql
1258
1532
  CREATE TABLE user_social_accounts (
@@ -1469,10 +1743,22 @@ import '@spfn/auth/nextjs/api';
1469
1743
  **Target Routes:**
1470
1744
  - `/_auth/login`, `/_auth/register` - Login/register interceptor
1471
1745
  - `/_auth/keys/rotate` - Key rotation interceptor
1746
+ - `/_auth/oauth/:provider/url` - OAuth URL interceptor (keypair + state generation)
1747
+ - `/_auth/oauth/finalize` - OAuth finalize interceptor (pending session → full session)
1472
1748
  - All other authenticated routes - General auth interceptor
1473
1749
 
1474
1750
  ---
1475
1751
 
1752
+ ### OAuth Client Component (`@spfn/auth/nextjs/client`)
1753
+
1754
+ ```typescript
1755
+ import { OAuthCallback, type OAuthCallbackProps } from '@spfn/auth/nextjs/client';
1756
+ ```
1757
+
1758
+ OAuth 콜백 페이지용 `'use client'` 컴포넌트. 자세한 사용법은 [OAuth Authentication](#oauth-authentication) 섹션 참조.
1759
+
1760
+ ---
1761
+
1476
1762
  ## Testing
1477
1763
 
1478
1764
  ### Setup Test Environment
@@ -1818,7 +2104,7 @@ ls migrations/
1818
2104
 
1819
2105
  - [ ] **React hooks** - useAuth, useSession, usePermissions
1820
2106
  - [ ] **UI components** - LoginForm, RegisterForm, AuthProvider
1821
- - [ ] **OAuth integration** - Google, GitHub, etc.
2107
+ - [x] **OAuth integration** - Google (implemented), GitHub/Kakao/Naver (planned)
1822
2108
  - [ ] **2FA support** - TOTP/authenticator apps
1823
2109
  - [ ] **Password reset flow** - Complete email-based reset
1824
2110
  - [ ] **Email change flow** - Verification for email updates
@@ -1958,6 +2244,6 @@ MIT License - See LICENSE file for details.
1958
2244
 
1959
2245
  ---
1960
2246
 
1961
- **Last Updated:** 2026-01-25
1962
- **Document Version:** 2.3.0 (Technical Documentation)
1963
- **Package Version:** 0.2.0-beta.11
2247
+ **Last Updated:** 2026-01-27
2248
+ **Document Version:** 2.4.0 (Technical Documentation)
2249
+ **Package Version:** 0.2.0-beta.12
@@ -376,6 +376,63 @@ interface AuthInitOptions {
376
376
  sessionTtl?: string | number;
377
377
  }
378
378
 
379
+ /**
380
+ * @spfn/auth - OAuth Service
381
+ *
382
+ * OAuth 인증 비즈니스 로직
383
+ * - Google OAuth Authorization Code Flow
384
+ * - 소셜 계정 연결/생성
385
+ * - publicKey는 state에서 추출하여 등록
386
+ */
387
+
388
+ interface OAuthStartParams {
389
+ provider: SocialProvider;
390
+ returnUrl: string;
391
+ publicKey: string;
392
+ keyId: string;
393
+ fingerprint: string;
394
+ algorithm: KeyAlgorithmType;
395
+ }
396
+ interface OAuthStartResult {
397
+ authUrl: string;
398
+ }
399
+ interface OAuthCallbackParams {
400
+ provider: SocialProvider;
401
+ code: string;
402
+ state: string;
403
+ }
404
+ interface OAuthCallbackResult {
405
+ redirectUrl: string;
406
+ userId: string;
407
+ keyId: string;
408
+ isNewUser: boolean;
409
+ }
410
+ /**
411
+ * OAuth 로그인 시작 - Provider 로그인 페이지로 리다이렉트할 URL 생성
412
+ *
413
+ * Next.js에서 키쌍을 생성한 후, publicKey를 state에 포함하여 호출
414
+ */
415
+ declare function oauthStartService(params: OAuthStartParams): Promise<OAuthStartResult>;
416
+ /**
417
+ * OAuth 콜백 처리 - Code를 Token으로 교환하고 사용자 생성/연결
418
+ *
419
+ * state에서 publicKey를 추출하여 서버에 등록
420
+ * Next.js는 반환된 userId, keyId로 세션을 구성
421
+ */
422
+ declare function oauthCallbackService(params: OAuthCallbackParams): Promise<OAuthCallbackResult>;
423
+ /**
424
+ * OAuth 에러 리다이렉트 URL 생성
425
+ */
426
+ declare function buildOAuthErrorUrl(error: string): string;
427
+ /**
428
+ * OAuth provider가 활성화되어 있는지 확인
429
+ */
430
+ declare function isOAuthProviderEnabled(provider: SocialProvider): boolean;
431
+ /**
432
+ * 활성화된 모든 OAuth provider 목록
433
+ */
434
+ declare function getEnabledOAuthProviders(): SocialProvider[];
435
+
379
436
  /**
380
437
  * @spfn/auth - Main Router
381
438
  *
@@ -387,6 +444,7 @@ interface AuthInitOptions {
387
444
  *
388
445
  * Routes:
389
446
  * - Auth: /_auth/exists, /_auth/codes, /_auth/login, /_auth/logout, etc.
447
+ * - OAuth: /_auth/oauth/google, /_auth/oauth/google/callback, etc.
390
448
  * - Invitations: /_auth/invitations/*
391
449
  * - Users: /_auth/users/*
392
450
  */
@@ -479,6 +537,50 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
479
537
  emailVerified: boolean;
480
538
  phoneVerified: boolean;
481
539
  }>;
540
+ oauthGoogleStart: _spfn_core_route.RouteDef<{
541
+ query: _sinclair_typebox.TObject<{
542
+ state: _sinclair_typebox.TString;
543
+ }>;
544
+ }, {}, Response>;
545
+ oauthGoogleCallback: _spfn_core_route.RouteDef<{
546
+ query: _sinclair_typebox.TObject<{
547
+ code: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
548
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
549
+ error: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
550
+ error_description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
551
+ }>;
552
+ }, {}, Response>;
553
+ oauthStart: _spfn_core_route.RouteDef<{
554
+ body: _sinclair_typebox.TObject<{
555
+ provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "github" | "kakao" | "naver">[]>;
556
+ returnUrl: _sinclair_typebox.TString;
557
+ publicKey: _sinclair_typebox.TString;
558
+ keyId: _sinclair_typebox.TString;
559
+ fingerprint: _sinclair_typebox.TString;
560
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
561
+ }>;
562
+ }, {}, OAuthStartResult>;
563
+ oauthProviders: _spfn_core_route.RouteDef<{}, {}, {
564
+ providers: ("google" | "github" | "kakao" | "naver")[];
565
+ }>;
566
+ getGoogleOAuthUrl: _spfn_core_route.RouteDef<{
567
+ body: _sinclair_typebox.TObject<{
568
+ returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
569
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
570
+ }>;
571
+ }, {}, {
572
+ authUrl: string;
573
+ }>;
574
+ oauthFinalize: _spfn_core_route.RouteDef<{
575
+ body: _sinclair_typebox.TObject<{
576
+ userId: _sinclair_typebox.TString;
577
+ keyId: _sinclair_typebox.TString;
578
+ returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
579
+ }>;
580
+ }, {}, {
581
+ success: boolean;
582
+ returnUrl: string;
583
+ }>;
482
584
  getInvitation: _spfn_core_route.RouteDef<{
483
585
  params: _sinclair_typebox.TObject<{
484
586
  token: _sinclair_typebox.TString;
@@ -642,4 +744,4 @@ declare module 'hono' {
642
744
  */
643
745
  declare const authenticate: _spfn_core_route.NamedMiddleware<"auth">;
644
746
 
645
- export { VerificationPurposeSchema as $, type AuthSession as A, type ChangePasswordParams as B, type CheckAccountExistsResult as C, sendVerificationCodeService as D, verifyCodeService as E, type SendVerificationCodeParams as F, type VerifyCodeParams as G, type VerifyCodeResult as H, INVITATION_STATUSES as I, registerPublicKeyService as J, KEY_ALGORITHM as K, type LoginResult as L, rotateKeyService as M, revokeKeyService as N, type RegisterPublicKeyParams as O, type PermissionConfig as P, type RotateKeyParams as Q, type RoleConfig as R, type SendVerificationCodeResult as S, type RevokeKeyParams as T, type UserProfile as U, type VerificationTargetType as V, authenticate as W, EmailSchema as X, PhoneSchema as Y, PasswordSchema as Z, TargetTypeSchema as _, type RegisterResult as a, type RotateKeyResult as b, type ProfileInfo as c, USER_STATUSES as d, SOCIAL_PROVIDERS as e, type VerificationPurpose as f, VERIFICATION_TARGET_TYPES as g, VERIFICATION_PURPOSES as h, PERMISSION_CATEGORIES as i, type PermissionCategory as j, type AuthInitOptions as k, type KeyAlgorithmType as l, mainAuthRouter as m, type InvitationStatus as n, type UserStatus as o, type SocialProvider as p, type AuthContext as q, checkAccountExistsService as r, registerService as s, loginService as t, logoutService as u, changePasswordService as v, type CheckAccountExistsParams as w, type RegisterParams as x, type LoginParams as y, type LogoutParams as z };
747
+ export { getEnabledOAuthProviders as $, type AuthSession as A, type ChangePasswordParams as B, type CheckAccountExistsResult as C, sendVerificationCodeService as D, verifyCodeService as E, type SendVerificationCodeParams as F, type VerifyCodeParams as G, type VerifyCodeResult as H, INVITATION_STATUSES as I, registerPublicKeyService as J, KEY_ALGORITHM as K, type LoginResult as L, rotateKeyService as M, revokeKeyService as N, type OAuthStartResult as O, type PermissionConfig as P, type RegisterPublicKeyParams as Q, type RoleConfig as R, type SendVerificationCodeResult as S, type RotateKeyParams as T, type UserProfile as U, type VerificationTargetType as V, type RevokeKeyParams as W, oauthStartService as X, oauthCallbackService as Y, buildOAuthErrorUrl as Z, isOAuthProviderEnabled as _, type RegisterResult as a, type OAuthStartParams as a0, type OAuthCallbackParams as a1, type OAuthCallbackResult as a2, authenticate as a3, EmailSchema as a4, PhoneSchema as a5, PasswordSchema as a6, TargetTypeSchema as a7, VerificationPurposeSchema as a8, type RotateKeyResult as b, type ProfileInfo as c, USER_STATUSES as d, SOCIAL_PROVIDERS as e, type VerificationPurpose as f, VERIFICATION_TARGET_TYPES as g, VERIFICATION_PURPOSES as h, PERMISSION_CATEGORIES as i, type PermissionCategory as j, type AuthInitOptions as k, type KeyAlgorithmType as l, mainAuthRouter as m, type InvitationStatus as n, type UserStatus as o, type SocialProvider as p, type AuthContext as q, checkAccountExistsService as r, registerService as s, loginService as t, logoutService as u, changePasswordService as v, type CheckAccountExistsParams as w, type RegisterParams as x, type LoginParams as y, type LogoutParams as z };
package/dist/config.d.ts CHANGED
@@ -214,6 +214,58 @@ declare const authEnvSchema: {
214
214
  } & {
215
215
  key: "SPFN_AUTH_AWS_SES_FROM_NAME";
216
216
  };
217
+ SPFN_APP_URL: {
218
+ description: string;
219
+ default: string;
220
+ required: boolean;
221
+ examples: string[];
222
+ type: "string";
223
+ } & {
224
+ key: "SPFN_APP_URL";
225
+ };
226
+ SPFN_AUTH_GOOGLE_CLIENT_ID: {
227
+ description: string;
228
+ required: boolean;
229
+ examples: string[];
230
+ type: "string";
231
+ } & {
232
+ key: "SPFN_AUTH_GOOGLE_CLIENT_ID";
233
+ };
234
+ SPFN_AUTH_GOOGLE_CLIENT_SECRET: {
235
+ description: string;
236
+ required: boolean;
237
+ sensitive: boolean;
238
+ examples: string[];
239
+ type: "string";
240
+ } & {
241
+ key: "SPFN_AUTH_GOOGLE_CLIENT_SECRET";
242
+ };
243
+ SPFN_AUTH_GOOGLE_REDIRECT_URI: {
244
+ description: string;
245
+ required: boolean;
246
+ examples: string[];
247
+ type: "string";
248
+ } & {
249
+ key: "SPFN_AUTH_GOOGLE_REDIRECT_URI";
250
+ };
251
+ SPFN_AUTH_OAUTH_SUCCESS_URL: {
252
+ description: string;
253
+ required: boolean;
254
+ default: string;
255
+ examples: string[];
256
+ type: "string";
257
+ } & {
258
+ key: "SPFN_AUTH_OAUTH_SUCCESS_URL";
259
+ };
260
+ SPFN_AUTH_OAUTH_ERROR_URL: {
261
+ description: string;
262
+ required: boolean;
263
+ default: string;
264
+ examples: string[];
265
+ type: "string";
266
+ } & {
267
+ key: "SPFN_AUTH_OAUTH_ERROR_URL";
268
+ };
217
269
  };
218
270
 
219
271
  declare const env: _spfn_core_env.InferEnvType<{
@@ -404,6 +456,58 @@ declare const env: _spfn_core_env.InferEnvType<{
404
456
  } & {
405
457
  key: "SPFN_AUTH_AWS_SES_FROM_NAME";
406
458
  };
459
+ SPFN_APP_URL: {
460
+ description: string;
461
+ default: string;
462
+ required: boolean;
463
+ examples: string[];
464
+ type: "string";
465
+ } & {
466
+ key: "SPFN_APP_URL";
467
+ };
468
+ SPFN_AUTH_GOOGLE_CLIENT_ID: {
469
+ description: string;
470
+ required: boolean;
471
+ examples: string[];
472
+ type: "string";
473
+ } & {
474
+ key: "SPFN_AUTH_GOOGLE_CLIENT_ID";
475
+ };
476
+ SPFN_AUTH_GOOGLE_CLIENT_SECRET: {
477
+ description: string;
478
+ required: boolean;
479
+ sensitive: boolean;
480
+ examples: string[];
481
+ type: "string";
482
+ } & {
483
+ key: "SPFN_AUTH_GOOGLE_CLIENT_SECRET";
484
+ };
485
+ SPFN_AUTH_GOOGLE_REDIRECT_URI: {
486
+ description: string;
487
+ required: boolean;
488
+ examples: string[];
489
+ type: "string";
490
+ } & {
491
+ key: "SPFN_AUTH_GOOGLE_REDIRECT_URI";
492
+ };
493
+ SPFN_AUTH_OAUTH_SUCCESS_URL: {
494
+ description: string;
495
+ required: boolean;
496
+ default: string;
497
+ examples: string[];
498
+ type: "string";
499
+ } & {
500
+ key: "SPFN_AUTH_OAUTH_SUCCESS_URL";
501
+ };
502
+ SPFN_AUTH_OAUTH_ERROR_URL: {
503
+ description: string;
504
+ required: boolean;
505
+ default: string;
506
+ examples: string[];
507
+ type: "string";
508
+ } & {
509
+ key: "SPFN_AUTH_OAUTH_ERROR_URL";
510
+ };
407
511
  }>;
408
512
 
409
513
  export { env, authEnvSchema as envSchema };
package/dist/config.js CHANGED
@@ -231,6 +231,67 @@ var authEnvSchema = defineEnvSchema({
231
231
  required: false,
232
232
  examples: ["MyApp", "Your Company"]
233
233
  })
234
+ },
235
+ SPFN_APP_URL: {
236
+ ...envString({
237
+ description: "Next.js application URL. Used for OAuth callback redirects.",
238
+ default: "http://localhost:3000",
239
+ required: false,
240
+ examples: [
241
+ "https://app.example.com",
242
+ "http://localhost:3000"
243
+ ]
244
+ })
245
+ },
246
+ // ============================================================================
247
+ // OAuth Configuration - Google
248
+ // ============================================================================
249
+ SPFN_AUTH_GOOGLE_CLIENT_ID: {
250
+ ...envString({
251
+ description: "Google OAuth 2.0 Client ID. When set, Google OAuth routes are automatically enabled.",
252
+ required: false,
253
+ examples: ["123456789-abc123.apps.googleusercontent.com"]
254
+ })
255
+ },
256
+ SPFN_AUTH_GOOGLE_CLIENT_SECRET: {
257
+ ...envString({
258
+ description: "Google OAuth 2.0 Client Secret",
259
+ required: false,
260
+ sensitive: true,
261
+ examples: ["GOCSPX-abcdefghijklmnop"]
262
+ })
263
+ },
264
+ SPFN_AUTH_GOOGLE_REDIRECT_URI: {
265
+ ...envString({
266
+ description: "Google OAuth callback URL. Defaults to {SPFN_API_URL}/_auth/oauth/google/callback",
267
+ required: false,
268
+ examples: [
269
+ "https://api.example.com/_auth/oauth/google/callback",
270
+ "http://localhost:8790/_auth/oauth/google/callback"
271
+ ]
272
+ })
273
+ },
274
+ SPFN_AUTH_OAUTH_SUCCESS_URL: {
275
+ ...envString({
276
+ description: "OAuth callback page URL. This page should use OAuthCallback component to finalize session.",
277
+ required: false,
278
+ default: "/auth/callback",
279
+ examples: [
280
+ "/auth/callback",
281
+ "https://app.example.com/auth/callback"
282
+ ]
283
+ })
284
+ },
285
+ SPFN_AUTH_OAUTH_ERROR_URL: {
286
+ ...envString({
287
+ description: "URL to redirect after OAuth error. Use {error} placeholder for error message.",
288
+ required: false,
289
+ default: "http://localhost:3000/auth/error?error={error}",
290
+ examples: [
291
+ "https://app.example.com/auth/error?error={error}",
292
+ "http://localhost:3000/auth/error?error={error}"
293
+ ]
294
+ })
234
295
  }
235
296
  });
236
297