@spfn/auth 0.2.0-beta.8 → 0.2.0-beta.80

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.
Files changed (42) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +549 -1819
  3. package/dist/authenticate-ofdEmk6x.d.ts +1109 -0
  4. package/dist/config.d.ts +359 -41
  5. package/dist/config.js +186 -30
  6. package/dist/config.js.map +1 -1
  7. package/dist/errors.d.ts +117 -3
  8. package/dist/errors.js +83 -1
  9. package/dist/errors.js.map +1 -1
  10. package/dist/index.d.ts +351 -109
  11. package/dist/index.js +124 -7
  12. package/dist/index.js.map +1 -1
  13. package/dist/nextjs/api.js +591 -61
  14. package/dist/nextjs/api.js.map +1 -1
  15. package/dist/nextjs/client.d.ts +28 -0
  16. package/dist/nextjs/client.js +80 -0
  17. package/dist/nextjs/client.js.map +1 -0
  18. package/dist/nextjs/server.d.ts +92 -3
  19. package/dist/nextjs/server.js +288 -24
  20. package/dist/nextjs/server.js.map +1 -1
  21. package/dist/server.d.ts +2015 -513
  22. package/dist/server.js +4198 -1086
  23. package/dist/server.js.map +1 -1
  24. package/dist/session-CGxgH3C9.d.ts +53 -0
  25. package/dist/types-1BMx0OX1.d.ts +84 -0
  26. package/migrations/0001_smooth_the_fury.sql +3 -0
  27. package/migrations/0002_deep_iceman.sql +11 -0
  28. package/migrations/0003_perfect_deathbird.sql +3 -0
  29. package/migrations/0004_concerned_rawhide_kid.sql +5 -0
  30. package/migrations/0005_lethal_lifeguard.sql +32 -0
  31. package/migrations/0006_easy_hardball.sql +24 -0
  32. package/migrations/0007_glossy_major_mapleleaf.sql +1 -0
  33. package/migrations/meta/0001_snapshot.json +1660 -0
  34. package/migrations/meta/0002_snapshot.json +1660 -0
  35. package/migrations/meta/0003_snapshot.json +1689 -0
  36. package/migrations/meta/0004_snapshot.json +1721 -0
  37. package/migrations/meta/0005_snapshot.json +1721 -0
  38. package/migrations/meta/0006_snapshot.json +1921 -0
  39. package/migrations/meta/0007_snapshot.json +1916 -0
  40. package/migrations/meta/_journal.json +49 -0
  41. package/package.json +43 -39
  42. package/dist/dto-lZmWuObc.d.ts +0 -645
@@ -0,0 +1,1109 @@
1
+ import * as _spfn_core_route from '@spfn/core/route';
2
+ import { K as KeyAlgorithmType, e as SocialProvider } from './types-1BMx0OX1.js';
3
+ import * as _sinclair_typebox from '@sinclair/typebox';
4
+ import { Static } from '@sinclair/typebox';
5
+ import { User } from '@spfn/auth/server';
6
+
7
+ /**
8
+ * Role information for client/API responses
9
+ */
10
+ interface Role {
11
+ id: number;
12
+ name: string;
13
+ displayName: string;
14
+ description: string | null;
15
+ isBuiltin: boolean;
16
+ isSystem: boolean;
17
+ isActive: boolean;
18
+ priority: number;
19
+ createdAt: Date;
20
+ updatedAt: Date;
21
+ }
22
+ /**
23
+ * Permission information for client/API responses
24
+ */
25
+ interface Permission {
26
+ id: number;
27
+ name: string;
28
+ displayName: string;
29
+ description: string | null;
30
+ category: string | null;
31
+ isBuiltin: boolean;
32
+ isSystem: boolean;
33
+ isActive: boolean;
34
+ metadata: Record<string, any> | null;
35
+ createdAt: Date;
36
+ updatedAt: Date;
37
+ }
38
+ interface AuthSession {
39
+ userId: number;
40
+ publicId: string;
41
+ email: string | null;
42
+ emailVerified: boolean;
43
+ phoneVerified: boolean;
44
+ hasPassword: boolean;
45
+ role: Role;
46
+ permissions: Permission[];
47
+ }
48
+ interface ProfileInfo {
49
+ profileId: number;
50
+ displayName: string | null;
51
+ firstName: string | null;
52
+ lastName: string | null;
53
+ avatarUrl: string | null;
54
+ bio: string | null;
55
+ locale: string;
56
+ timezone: string;
57
+ website: string | null;
58
+ location: string | null;
59
+ company: string | null;
60
+ jobTitle: string | null;
61
+ metadata: Record<string, any> | null;
62
+ createdAt: Date;
63
+ updatedAt: Date;
64
+ }
65
+ /**
66
+ * User Profile Response
67
+ *
68
+ * Complete user data including:
69
+ * - User fields at top level (userId, email, etc.)
70
+ * - Profile data as nested field (optional)
71
+ *
72
+ * Excludes:
73
+ * - Role and permissions (use auth session API)
74
+ */
75
+ interface UserProfile {
76
+ userId: number;
77
+ publicId: string;
78
+ email: string | null;
79
+ username: string | null;
80
+ emailVerified: boolean;
81
+ phoneVerified: boolean;
82
+ lastLoginAt: Date | null;
83
+ createdAt: Date;
84
+ updatedAt: Date;
85
+ profile: ProfileInfo | null;
86
+ }
87
+
88
+ /**
89
+ * @spfn/auth - Auth Service
90
+ *
91
+ * Core authentication logic: registration, login, logout, password management
92
+ */
93
+
94
+ interface RegisterParams {
95
+ email?: string;
96
+ phone?: string;
97
+ verificationToken: string;
98
+ password: string;
99
+ publicKey: string;
100
+ keyId: string;
101
+ fingerprint: string;
102
+ algorithm?: KeyAlgorithmType;
103
+ metadata?: Record<string, unknown>;
104
+ }
105
+ interface RegisterResult {
106
+ userId: string;
107
+ publicId: string;
108
+ email?: string;
109
+ phone?: string;
110
+ }
111
+ interface LoginParams {
112
+ email?: string;
113
+ phone?: string;
114
+ password: string;
115
+ publicKey: string;
116
+ keyId: string;
117
+ fingerprint: string;
118
+ oldKeyId?: string;
119
+ algorithm?: KeyAlgorithmType;
120
+ }
121
+ interface LoginResult {
122
+ userId: string;
123
+ publicId: string;
124
+ email?: string;
125
+ phone?: string;
126
+ passwordChangeRequired: boolean;
127
+ }
128
+ interface LogoutParams {
129
+ userId: number;
130
+ keyId: string;
131
+ }
132
+ interface ChangePasswordParams {
133
+ userId: number;
134
+ currentPassword?: string;
135
+ newPassword: string;
136
+ passwordHash?: string;
137
+ }
138
+ /**
139
+ * Register a new user account
140
+ */
141
+ declare function registerService(params: RegisterParams): Promise<RegisterResult>;
142
+ /**
143
+ * Authenticate user and create session
144
+ */
145
+ declare function loginService(params: LoginParams): Promise<LoginResult>;
146
+ /**
147
+ * Logout user (revoke current key)
148
+ */
149
+ declare function logoutService(params: LogoutParams): Promise<void>;
150
+ /**
151
+ * Change user password
152
+ */
153
+ declare function changePasswordService(params: ChangePasswordParams): Promise<void>;
154
+
155
+ declare const EmailSchema: _sinclair_typebox.TString;
156
+ declare const PhoneSchema: _sinclair_typebox.TString;
157
+ declare const PasswordSchema: _sinclair_typebox.TString;
158
+ declare const TargetTypeSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
159
+ type VerificationTargetType = Static<typeof TargetTypeSchema>;
160
+ declare const VERIFICATION_TARGET_TYPES: readonly ["email", "phone"];
161
+ declare const VerificationPurposeSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"registration">, _sinclair_typebox.TLiteral<"login">, _sinclair_typebox.TLiteral<"password_reset">, _sinclair_typebox.TLiteral<"email_change">, _sinclair_typebox.TLiteral<"phone_change">, _sinclair_typebox.TLiteral<"account_deletion">]>;
162
+ type VerificationPurpose = Static<typeof VerificationPurposeSchema>;
163
+ declare const VERIFICATION_PURPOSES: readonly ["registration", "login", "password_reset", "email_change", "phone_change", "account_deletion"];
164
+
165
+ /**
166
+ * @spfn/auth - Verification Service
167
+ *
168
+ * Handles OTP code generation, validation, and delivery
169
+ */
170
+
171
+ interface SendVerificationCodeParams {
172
+ target: string;
173
+ targetType: VerificationTargetType;
174
+ purpose: VerificationPurpose;
175
+ }
176
+ interface SendVerificationCodeResult {
177
+ success: boolean;
178
+ expiresAt: string;
179
+ }
180
+ interface VerifyCodeParams {
181
+ target: string;
182
+ targetType: VerificationTargetType;
183
+ code: string;
184
+ purpose: VerificationPurpose;
185
+ }
186
+ interface VerifyCodeResult {
187
+ valid: boolean;
188
+ verificationToken: string;
189
+ }
190
+ /**
191
+ * Send verification code via email or SMS
192
+ */
193
+ declare function sendVerificationCodeService(params: SendVerificationCodeParams): Promise<SendVerificationCodeResult>;
194
+ /**
195
+ * Verify OTP code and return verification token
196
+ */
197
+ declare function verifyCodeService(params: VerifyCodeParams): Promise<{
198
+ valid: boolean;
199
+ verificationToken: string;
200
+ }>;
201
+
202
+ /**
203
+ * @spfn/auth - Key Service
204
+ *
205
+ * Handles public key registration, rotation, and revocation
206
+ */
207
+
208
+ interface RegisterPublicKeyParams {
209
+ userId: number;
210
+ keyId: string;
211
+ publicKey: string;
212
+ fingerprint: string;
213
+ algorithm?: KeyAlgorithmType;
214
+ }
215
+ interface RotateKeyParams {
216
+ userId: number;
217
+ oldKeyId: string;
218
+ newKeyId: string;
219
+ newPublicKey: string;
220
+ fingerprint: string;
221
+ algorithm?: KeyAlgorithmType;
222
+ }
223
+ interface RotateKeyResult {
224
+ success: boolean;
225
+ keyId: string;
226
+ }
227
+ interface RevokeKeyParams {
228
+ userId: number;
229
+ keyId: string;
230
+ reason: string;
231
+ }
232
+ /**
233
+ * Register a new public key for a user
234
+ */
235
+ declare function registerPublicKeyService(params: RegisterPublicKeyParams): Promise<void>;
236
+ /**
237
+ * Rotate user's public key (revoke old, register new)
238
+ */
239
+ declare function rotateKeyService(params: RotateKeyParams): Promise<RotateKeyResult>;
240
+ /**
241
+ * Revoke a user's public key
242
+ */
243
+ declare function revokeKeyService(params: RevokeKeyParams): Promise<void>;
244
+
245
+ /**
246
+ * @spfn/auth - RBAC Type Definitions
247
+ *
248
+ * Type definitions for role and permission configuration
249
+ */
250
+ /**
251
+ * Permission category enum values
252
+ * Single source of truth for permission categories
253
+ */
254
+ declare const PERMISSION_CATEGORIES: readonly ["auth", "user", "rbac", "system", "custom"];
255
+ /**
256
+ * Permission category type derived from the const array
257
+ */
258
+ type PermissionCategory = typeof PERMISSION_CATEGORIES[number];
259
+ interface RoleConfig {
260
+ name: string;
261
+ displayName: string;
262
+ description?: string;
263
+ priority?: number;
264
+ isSystem?: boolean;
265
+ isBuiltin?: boolean;
266
+ }
267
+ interface PermissionConfig {
268
+ name: string;
269
+ displayName: string;
270
+ description?: string;
271
+ category?: PermissionCategory;
272
+ isSystem?: boolean;
273
+ isBuiltin?: boolean;
274
+ }
275
+ interface AuthInitOptions {
276
+ /**
277
+ * Additional roles to create
278
+ * Built-in roles (user, admin, superadmin) are automatically included
279
+ */
280
+ roles?: RoleConfig[];
281
+ /**
282
+ * Additional permissions to create
283
+ * Built-in permissions are automatically included
284
+ */
285
+ permissions?: PermissionConfig[];
286
+ /**
287
+ * Role-Permission mappings
288
+ * Built-in mappings are automatically included
289
+ * You can extend built-in roles or define mappings for custom roles
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * {
294
+ * // Extend built-in admin role
295
+ * admin: ['project:create', 'project:delete'],
296
+ *
297
+ * // Define custom role permissions
298
+ * 'project-manager': ['project:create', 'task:assign'],
299
+ * }
300
+ * ```
301
+ */
302
+ rolePermissions?: Record<string, string[]>;
303
+ /**
304
+ * Default role name for new users
305
+ * Must be a valid role name that exists after initialization
306
+ * @default 'user'
307
+ */
308
+ defaultRole?: string;
309
+ /**
310
+ * Default session TTL (Time To Live)
311
+ *
312
+ * Supports:
313
+ * - Number: seconds (e.g., 2592000)
314
+ * - String: duration format ('30d', '12h', '45m', '3600s')
315
+ *
316
+ * Can be overridden at runtime with `remember` parameter.
317
+ *
318
+ * @default '7d' (7 days)
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * {
323
+ * sessionTtl: '30d', // 30 days
324
+ * }
325
+ * ```
326
+ */
327
+ sessionTtl?: string | number;
328
+ }
329
+
330
+ /**
331
+ * One-Time Token Service
332
+ *
333
+ * Issues and verifies one-time tokens for direct API access.
334
+ */
335
+ interface IssueOneTimeTokenResult {
336
+ token: string;
337
+ expiresAt: string;
338
+ }
339
+ /**
340
+ * Issue a one-time token for the authenticated user
341
+ *
342
+ * @param userId - Authenticated user's ID
343
+ * @returns Token string and ISO expiration timestamp
344
+ */
345
+ declare function issueOneTimeTokenService(userId: string): Promise<IssueOneTimeTokenResult>;
346
+ /**
347
+ * Verify and consume a one-time token
348
+ *
349
+ * @param token - The one-time token to verify
350
+ * @returns userId if valid, null if invalid/expired/consumed
351
+ */
352
+ declare function verifyOneTimeTokenService(token: string): Promise<string | null>;
353
+
354
+ /**
355
+ * OAuth Provider 추상화
356
+ *
357
+ * Provider별로 하드코딩된 분기를 제거하기 위한 공통 인터페이스와 registry.
358
+ * - 내장 provider(google)는 패키지 로드 시점에 자기 등록(dogfood)
359
+ * - 외부 패키지(@superself/auth 등)는 registerOAuthProvider()로 런타임 등록
360
+ *
361
+ * @spfn/auth는 토큰 issuer가 아니라 소비(client) 측이므로, 이 추상화는
362
+ * web 흐름("authorize URL 생성 → code 교환 → 사용자 정보 정규화")과
363
+ * native 흐름(네이티브/웹 SDK가 받은 id_token 직접 검증)을 다룬다.
364
+ */
365
+
366
+ /**
367
+ * Provider 사용자 정보를 공통 형태로 정규화한 신원
368
+ *
369
+ * provider별 응답 형태(snake_case 등)를 service에 노출하지 않기 위한 경계.
370
+ */
371
+ interface NormalizedIdentity {
372
+ providerUserId: string;
373
+ email: string | null;
374
+ emailVerified: boolean;
375
+ name?: string;
376
+ avatar?: string;
377
+ }
378
+ /**
379
+ * 정규화된 OAuth 토큰 응답
380
+ *
381
+ * @property expiresIn - access token 만료까지 남은 초(seconds)
382
+ */
383
+ interface OAuthTokens {
384
+ accessToken: string;
385
+ refreshToken?: string;
386
+ expiresIn: number;
387
+ }
388
+ /**
389
+ * 네이티브 id_token 검증 옵션
390
+ */
391
+ interface NativeVerifyOptions {
392
+ /** 클라이언트가 생성한 raw nonce. provider별 규약(raw 또는 SHA-256 해시)으로 대조된다. */
393
+ nonce: string;
394
+ }
395
+ interface OAuthCodeExchangeOptions {
396
+ /** Provider가 callback에 돌려준 원본 state. 일부 provider는 token 교환에도 요구한다. */
397
+ state: string;
398
+ }
399
+ /**
400
+ * OAuth provider 구현 인터페이스
401
+ *
402
+ * google, superself 등 모든 provider가 이 형태를 만족해야 registry에 등록된다.
403
+ */
404
+ interface OAuthProvider {
405
+ id: SocialProvider;
406
+ /**
407
+ * provider가 사용 가능한 상태인지(필수 env 등) 확인
408
+ */
409
+ isEnabled(): boolean;
410
+ /**
411
+ * provider 로그인 페이지로 보낼 authorization URL 생성
412
+ *
413
+ * @param state - CSRF 방지용 암호화 state
414
+ * @param scopes - 요청할 scope (미지정 시 provider 기본값)
415
+ */
416
+ getAuthUrl(state: string, scopes?: string[]): string;
417
+ /**
418
+ * authorization code를 토큰으로 교환
419
+ */
420
+ exchangeCodeForTokens(code: string, options: OAuthCodeExchangeOptions): Promise<OAuthTokens>;
421
+ /**
422
+ * access token으로 사용자 정보를 조회하고 공통 형태로 정규화
423
+ */
424
+ getUserInfo(accessToken: string): Promise<NormalizedIdentity>;
425
+ /**
426
+ * refresh token으로 access token 갱신 (provider가 지원하는 경우)
427
+ *
428
+ * 저장된 provider 토큰을 이후 API 호출에 재사용할 때 사용한다.
429
+ * 미구현 provider는 갱신 불가로 간주한다.
430
+ */
431
+ refreshTokens?(refreshToken: string): Promise<OAuthTokens>;
432
+ /**
433
+ * 네이티브/웹 SDK가 받은 id_token을 직접 검증하고 신원을 정규화한다.
434
+ *
435
+ * authorization code 교환 없이 provider JWKS로 서명을 검증하므로 client secret이
436
+ * 필요 없다. native sign-in을 지원하는 provider만 구현한다(Apple은 web SDK 부재로
437
+ * Android·웹도 이 경로를 쓴다).
438
+ */
439
+ verifyNativeIdToken?(idToken: string, options: NativeVerifyOptions): Promise<NormalizedIdentity>;
440
+ }
441
+ /**
442
+ * OAuth provider 등록 (public)
443
+ *
444
+ * 동일 id로 다시 등록하면 덮어쓴다(외부 패키지의 override 허용).
445
+ */
446
+ declare function registerOAuthProvider(provider: OAuthProvider): void;
447
+ /**
448
+ * 등록된 provider 조회. 미등록이면 undefined.
449
+ */
450
+ declare function getOAuthProvider(id: SocialProvider): OAuthProvider | undefined;
451
+ /**
452
+ * 등록된 모든 provider 목록
453
+ */
454
+ declare function getRegisteredProviders(): OAuthProvider[];
455
+
456
+ /**
457
+ * @spfn/auth - OAuth Service
458
+ *
459
+ * OAuth 인증 비즈니스 로직
460
+ * - Google OAuth Authorization Code Flow
461
+ * - 소셜 계정 연결/생성
462
+ * - publicKey는 state에서 추출하여 등록
463
+ */
464
+
465
+ interface OAuthStartParams {
466
+ provider: SocialProvider;
467
+ returnUrl: string;
468
+ publicKey: string;
469
+ keyId: string;
470
+ fingerprint: string;
471
+ algorithm: KeyAlgorithmType;
472
+ metadata?: Record<string, unknown>;
473
+ /** CSRF nonce bound into the state; the route sets the matching oauth_csrf cookie. */
474
+ nonce?: string;
475
+ }
476
+ interface OAuthStartResult {
477
+ authUrl: string;
478
+ }
479
+ interface OAuthCallbackParams {
480
+ provider: SocialProvider;
481
+ code: string;
482
+ state: string;
483
+ /**
484
+ * Value(s) of the oauth_csrf cookie from the callback request. One of them
485
+ * must equal the nonce bound into the (encrypted) state — otherwise the flow
486
+ * wasn't initiated by this browser (login CSRF). An array arises because the
487
+ * cookie name carries the PORT suffix of the process that set it (the Next.js
488
+ * web process), which differs from the API process in a split deployment, so
489
+ * the callback collects every spfn_oauth_csrf* candidate. Pass `undefined` or
490
+ * an empty array when absent; verification then fails closed.
491
+ */
492
+ expectedNonce: string | string[] | undefined;
493
+ }
494
+ interface OAuthCallbackResult {
495
+ redirectUrl: string;
496
+ userId: string;
497
+ keyId: string;
498
+ isNewUser: boolean;
499
+ }
500
+ /**
501
+ * registry에서 provider를 찾아 사용 가능한지 검증 후 반환
502
+ *
503
+ * 미등록과 비활성을 구분해 디버깅 신호를 남긴다.
504
+ * 라우트 레이어에서도 재사용한다(중복 조회/non-null 단언 제거).
505
+ */
506
+ declare function requireEnabledProvider(provider: SocialProvider): OAuthProvider;
507
+ /**
508
+ * OAuth 로그인 시작 - Provider 로그인 페이지로 리다이렉트할 URL 생성
509
+ *
510
+ * Next.js에서 키쌍을 생성한 후, publicKey를 state에 포함하여 호출
511
+ */
512
+ declare function oauthStartService(params: OAuthStartParams): Promise<OAuthStartResult>;
513
+ /**
514
+ * OAuth 콜백 처리 - Code를 Token으로 교환하고 사용자 생성/연결
515
+ *
516
+ * state에서 publicKey를 추출하여 서버에 등록
517
+ * Next.js는 반환된 userId, keyId로 세션을 구성
518
+ */
519
+ declare function oauthCallbackService(params: OAuthCallbackParams): Promise<OAuthCallbackResult>;
520
+ /**
521
+ * OAuth 에러 리다이렉트 URL 생성
522
+ */
523
+ declare function buildOAuthErrorUrl(error: string): string;
524
+ /**
525
+ * OAuth provider가 등록되어 있고 활성화되어 있는지 확인
526
+ */
527
+ declare function isOAuthProviderEnabled(provider: SocialProvider): boolean;
528
+ /**
529
+ * 활성화된 모든 OAuth provider 목록 (registry 기반)
530
+ */
531
+ declare function getEnabledOAuthProviders(): SocialProvider[];
532
+ /**
533
+ * Google access token 조회 (만료 시 자동 리프레시)
534
+ *
535
+ * 저장된 토큰이 만료 임박(5분 이내) 또는 만료 상태이면
536
+ * refresh token으로 자동 갱신 후 DB 업데이트하여 유효한 토큰 반환.
537
+ *
538
+ * @param userId - 사용자 ID
539
+ * @returns 유효한 Google access token
540
+ */
541
+ declare function getGoogleAccessToken(userId: number): Promise<string>;
542
+
543
+ /**
544
+ * @spfn/auth - Native Social Login Service
545
+ *
546
+ * 네이티브/웹 SDK가 받은 id_token을 JWKS로 검증하고, 검증된 신원에 클라이언트가 만든
547
+ * 공개키를 등록한다. 토큰은 발급하지 않는다 — 클라이언트가 등록한 키로 client token을
548
+ * 직접 서명해 Bearer로 사용한다(client-signs / server-verifies 모델).
549
+ *
550
+ * 흐름은 두 단계로 분리한다:
551
+ * 1) id_token 검증 — 외부 JWKS 네트워크 조회. DB 트랜잭션 밖에서 수행한다.
552
+ * 2) persist — 사용자 link/create + 공개키 등록을 한 트랜잭션으로. 이벤트는 커밋 후 발행.
553
+ */
554
+
555
+ interface OAuthNativeParams {
556
+ provider: SocialProvider;
557
+ idToken: string;
558
+ nonce: string;
559
+ publicKey: string;
560
+ keyId: string;
561
+ fingerprint: string;
562
+ algorithm: KeyAlgorithmType;
563
+ /** Apple은 첫 로그인에만 이름을 별도로 주므로 클라이언트가 전달할 수 있다. */
564
+ profile?: {
565
+ name?: string;
566
+ };
567
+ metadata?: Record<string, unknown>;
568
+ }
569
+ interface OAuthNativeResult {
570
+ userId: string;
571
+ keyId: string;
572
+ isNewUser: boolean;
573
+ }
574
+ /**
575
+ * native id_token 로그인 처리
576
+ *
577
+ * @throws ValidationError provider가 native sign-in을 지원하지 않을 때
578
+ * @throws InvalidSocialTokenError id_token 검증 실패 시
579
+ */
580
+ declare function oauthNativeService(params: OAuthNativeParams): Promise<OAuthNativeResult>;
581
+
582
+ /**
583
+ * @spfn/auth - Main Router
584
+ *
585
+ * Combines all auth-related routes into a single router
586
+ */
587
+ /**
588
+ * Main auth router
589
+ * Exports all authentication-related routes
590
+ *
591
+ * Routes:
592
+ * - Auth: /_auth/codes, /_auth/login, /_auth/logout, etc.
593
+ * - OAuth: /_auth/oauth/google, /_auth/oauth/google/callback, etc.
594
+ * - Invitations: /_auth/invitations/*
595
+ * - Users: /_auth/users/*
596
+ * - Deletion: /_auth/deletion/request, /_auth/deletion/cancel
597
+ * - Admin: /_auth/admin/* (superadmin only)
598
+ */
599
+ declare const mainAuthRouter: _spfn_core_route.Router<{
600
+ sendVerificationCode: _spfn_core_route.RouteDef<{
601
+ body: _sinclair_typebox.TObject<{
602
+ target: _sinclair_typebox.TString;
603
+ targetType: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
604
+ purpose: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"registration">, _sinclair_typebox.TLiteral<"login">, _sinclair_typebox.TLiteral<"password_reset">, _sinclair_typebox.TLiteral<"email_change">, _sinclair_typebox.TLiteral<"phone_change">, _sinclair_typebox.TLiteral<"account_deletion">]>;
605
+ }>;
606
+ }, {}, SendVerificationCodeResult>;
607
+ verifyCode: _spfn_core_route.RouteDef<{
608
+ body: _sinclair_typebox.TObject<{
609
+ target: _sinclair_typebox.TString;
610
+ targetType: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
611
+ code: _sinclair_typebox.TString;
612
+ purpose: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"registration">, _sinclair_typebox.TLiteral<"login">, _sinclair_typebox.TLiteral<"password_reset">, _sinclair_typebox.TLiteral<"email_change">, _sinclair_typebox.TLiteral<"phone_change">, _sinclair_typebox.TLiteral<"account_deletion">]>;
613
+ }>;
614
+ }, {}, {
615
+ valid: boolean;
616
+ verificationToken: string;
617
+ }>;
618
+ register: _spfn_core_route.RouteDef<{
619
+ body: _sinclair_typebox.TObject<{
620
+ email: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
621
+ phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
622
+ verificationToken: _sinclair_typebox.TString;
623
+ password: _sinclair_typebox.TString;
624
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
625
+ }>;
626
+ }, {
627
+ body: _sinclair_typebox.TObject<{
628
+ publicKey: _sinclair_typebox.TString;
629
+ keyId: _sinclair_typebox.TString;
630
+ fingerprint: _sinclair_typebox.TString;
631
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
632
+ }>;
633
+ }, RegisterResult>;
634
+ login: _spfn_core_route.RouteDef<{
635
+ body: _sinclair_typebox.TObject<{
636
+ email: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
637
+ phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
638
+ password: _sinclair_typebox.TString;
639
+ }>;
640
+ }, {
641
+ body: _sinclair_typebox.TObject<{
642
+ publicKey: _sinclair_typebox.TString;
643
+ keyId: _sinclair_typebox.TString;
644
+ fingerprint: _sinclair_typebox.TString;
645
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
646
+ oldKeyId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
647
+ }>;
648
+ }, LoginResult>;
649
+ logout: _spfn_core_route.RouteDef<{}, {}, void>;
650
+ rotateKey: _spfn_core_route.RouteDef<{}, {
651
+ body: _sinclair_typebox.TObject<{
652
+ publicKey: _sinclair_typebox.TString;
653
+ keyId: _sinclair_typebox.TString;
654
+ fingerprint: _sinclair_typebox.TString;
655
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
656
+ }>;
657
+ }, RotateKeyResult>;
658
+ changePassword: _spfn_core_route.RouteDef<{
659
+ body: _sinclair_typebox.TObject<{
660
+ currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
661
+ newPassword: _sinclair_typebox.TString;
662
+ }>;
663
+ }, {}, void>;
664
+ getAuthSession: _spfn_core_route.RouteDef<{}, {}, {
665
+ role: {
666
+ id: number;
667
+ name: string;
668
+ displayName: string;
669
+ priority: number;
670
+ };
671
+ permissions: {
672
+ id: number;
673
+ name: string;
674
+ displayName: string;
675
+ category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
676
+ }[];
677
+ userId: number;
678
+ publicId: string;
679
+ email: string | null;
680
+ emailVerified: boolean;
681
+ phoneVerified: boolean;
682
+ hasPassword: boolean;
683
+ }>;
684
+ issueOneTimeToken: _spfn_core_route.RouteDef<{}, {}, IssueOneTimeTokenResult>;
685
+ requestAccountDeletion: _spfn_core_route.RouteDef<{
686
+ body: _sinclair_typebox.TObject<{
687
+ password: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
688
+ verificationToken: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
689
+ reason: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
690
+ immediate: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
691
+ }>;
692
+ }, {}, {
693
+ purgeScheduledAt: string;
694
+ }>;
695
+ cancelAccountDeletion: _spfn_core_route.RouteDef<{
696
+ body: _sinclair_typebox.TObject<{
697
+ email: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
698
+ phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
699
+ password: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
700
+ verificationToken: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
701
+ }>;
702
+ }, {}, void>;
703
+ oauthGoogleStart: _spfn_core_route.RouteDef<{
704
+ query: _sinclair_typebox.TObject<{
705
+ state: _sinclair_typebox.TString;
706
+ }>;
707
+ }, {}, Response>;
708
+ oauthGoogleCallback: _spfn_core_route.RouteDef<{
709
+ query: _sinclair_typebox.TObject<{
710
+ code: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
711
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
712
+ error: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
713
+ error_description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
714
+ }>;
715
+ }, {}, Response>;
716
+ oauthStart: _spfn_core_route.RouteDef<{
717
+ body: _sinclair_typebox.TObject<{
718
+ provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "apple" | "github" | "kakao" | "naver" | "superself">[]>;
719
+ returnUrl: _sinclair_typebox.TString;
720
+ publicKey: _sinclair_typebox.TString;
721
+ keyId: _sinclair_typebox.TString;
722
+ fingerprint: _sinclair_typebox.TString;
723
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
724
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
725
+ }>;
726
+ }, {}, OAuthStartResult>;
727
+ oauthProviders: _spfn_core_route.RouteDef<{}, {}, {
728
+ providers: ("google" | "apple" | "github" | "kakao" | "naver" | "superself")[];
729
+ }>;
730
+ getGoogleOAuthUrl: _spfn_core_route.RouteDef<{
731
+ body: _sinclair_typebox.TObject<{
732
+ returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
733
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
734
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
735
+ }>;
736
+ }, {}, {
737
+ authUrl: string;
738
+ }>;
739
+ oauthFinalize: _spfn_core_route.RouteDef<{
740
+ body: _sinclair_typebox.TObject<{
741
+ userId: _sinclair_typebox.TString;
742
+ keyId: _sinclair_typebox.TString;
743
+ returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
744
+ }>;
745
+ }, {}, {
746
+ success: boolean;
747
+ userId: string;
748
+ keyId: string;
749
+ returnUrl: string;
750
+ }>;
751
+ oauthProviderStart: _spfn_core_route.RouteDef<{
752
+ params: _sinclair_typebox.TObject<{
753
+ provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "apple" | "github" | "kakao" | "naver" | "superself">[]>;
754
+ }>;
755
+ query: _sinclair_typebox.TObject<{
756
+ state: _sinclair_typebox.TString;
757
+ }>;
758
+ }, {}, Response>;
759
+ oauthProviderCallback: _spfn_core_route.RouteDef<{
760
+ params: _sinclair_typebox.TObject<{
761
+ provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "apple" | "github" | "kakao" | "naver" | "superself">[]>;
762
+ }>;
763
+ query: _sinclair_typebox.TObject<{
764
+ code: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
765
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
766
+ error: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
767
+ error_description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
768
+ }>;
769
+ }, {}, Response>;
770
+ getProviderOAuthUrl: _spfn_core_route.RouteDef<{
771
+ params: _sinclair_typebox.TObject<{
772
+ provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "apple" | "github" | "kakao" | "naver" | "superself">[]>;
773
+ }>;
774
+ body: _sinclair_typebox.TObject<{
775
+ returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
776
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
777
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
778
+ }>;
779
+ }, {}, {
780
+ authUrl: string;
781
+ }>;
782
+ oauthNative: _spfn_core_route.RouteDef<{
783
+ params: _sinclair_typebox.TObject<{
784
+ provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "apple" | "github" | "kakao" | "naver" | "superself">[]>;
785
+ }>;
786
+ body: _sinclair_typebox.TObject<{
787
+ idToken: _sinclair_typebox.TString;
788
+ nonce: _sinclair_typebox.TString;
789
+ publicKey: _sinclair_typebox.TString;
790
+ keyId: _sinclair_typebox.TString;
791
+ fingerprint: _sinclair_typebox.TString;
792
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
793
+ profile: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
794
+ name: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
795
+ }>>;
796
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
797
+ }>;
798
+ }, {}, OAuthNativeResult>;
799
+ getInvitation: _spfn_core_route.RouteDef<{
800
+ params: _sinclair_typebox.TObject<{
801
+ token: _sinclair_typebox.TString;
802
+ }>;
803
+ }, {}, {
804
+ email: string;
805
+ role: string;
806
+ roleDisplayName: string;
807
+ invitedBy: string;
808
+ expiresAt: string;
809
+ metadata: Record<string, any> | undefined;
810
+ }>;
811
+ acceptInvitation: _spfn_core_route.RouteDef<{
812
+ body: _sinclair_typebox.TObject<{
813
+ token: _sinclair_typebox.TString;
814
+ password: _sinclair_typebox.TString;
815
+ }>;
816
+ }, {
817
+ body: _sinclair_typebox.TObject<{
818
+ publicKey: _sinclair_typebox.TString;
819
+ keyId: _sinclair_typebox.TString;
820
+ fingerprint: _sinclair_typebox.TString;
821
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
822
+ }>;
823
+ }, {
824
+ userId: number;
825
+ email: string;
826
+ role: string;
827
+ }>;
828
+ createInvitation: _spfn_core_route.RouteDef<{
829
+ body: _sinclair_typebox.TObject<{
830
+ email: _sinclair_typebox.TString;
831
+ roleId: _sinclair_typebox.TNumber;
832
+ expiresInDays: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
833
+ expiresAt: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
834
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TAny>;
835
+ }>;
836
+ }, {}, {
837
+ id: number;
838
+ email: string;
839
+ token: string;
840
+ roleId: number;
841
+ expiresAt: string;
842
+ invitationUrl: string;
843
+ }>;
844
+ listInvitations: _spfn_core_route.RouteDef<{
845
+ query: _sinclair_typebox.TObject<{
846
+ status: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"pending" | "accepted" | "expired" | "cancelled">[]>>;
847
+ page: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
848
+ limit: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
849
+ }>;
850
+ }, {}, {
851
+ invitations: {
852
+ id: number;
853
+ email: string;
854
+ token: string;
855
+ roleId: number;
856
+ invitedBy: number;
857
+ status: "pending" | "accepted" | "expired" | "cancelled";
858
+ expiresAt: Date;
859
+ acceptedAt: Date | null;
860
+ cancelledAt: Date | null;
861
+ metadata: Record<string, any> | null;
862
+ createdAt: Date;
863
+ updatedAt: Date;
864
+ role: {
865
+ id: number;
866
+ name: string;
867
+ displayName: string;
868
+ };
869
+ inviter: {
870
+ id: number;
871
+ email: string | null;
872
+ };
873
+ }[];
874
+ total: number;
875
+ page: number;
876
+ limit: number;
877
+ totalPages: number;
878
+ }>;
879
+ cancelInvitation: _spfn_core_route.RouteDef<{
880
+ body: _sinclair_typebox.TObject<{
881
+ id: _sinclair_typebox.TNumber;
882
+ reason: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
883
+ }>;
884
+ }, {}, {
885
+ cancelledAt: string;
886
+ }>;
887
+ resendInvitation: _spfn_core_route.RouteDef<{
888
+ body: _sinclair_typebox.TObject<{
889
+ id: _sinclair_typebox.TNumber;
890
+ expiresInDays: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
891
+ }>;
892
+ }, {}, {
893
+ expiresAt: string;
894
+ }>;
895
+ deleteInvitation: _spfn_core_route.RouteDef<{
896
+ body: _sinclair_typebox.TObject<{
897
+ id: _sinclair_typebox.TNumber;
898
+ }>;
899
+ }, {}, void>;
900
+ getUserProfile: _spfn_core_route.RouteDef<{}, {}, UserProfile>;
901
+ updateUserProfile: _spfn_core_route.RouteDef<{
902
+ body: _sinclair_typebox.TObject<{
903
+ displayName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
904
+ firstName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
905
+ lastName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
906
+ avatarUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
907
+ bio: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
908
+ locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
909
+ timezone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
910
+ dateOfBirth: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
911
+ gender: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
912
+ website: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
913
+ location: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
914
+ company: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
915
+ jobTitle: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
916
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
917
+ }>;
918
+ }, {}, ProfileInfo>;
919
+ checkUsername: _spfn_core_route.RouteDef<{
920
+ query: _sinclair_typebox.TObject<{
921
+ username: _sinclair_typebox.TString;
922
+ }>;
923
+ }, {}, {
924
+ available: boolean;
925
+ }>;
926
+ updateUsername: _spfn_core_route.RouteDef<{
927
+ body: _sinclair_typebox.TObject<{
928
+ username: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
929
+ }>;
930
+ }, {}, {
931
+ deletedAt: Date | null;
932
+ deletedBy: string | null;
933
+ createdAt: Date;
934
+ updatedAt: Date;
935
+ id: number;
936
+ publicId: string;
937
+ email: string | null;
938
+ phone: string | null;
939
+ username: string | null;
940
+ passwordHash: string | null;
941
+ passwordChangeRequired: boolean;
942
+ roleId: number;
943
+ status: "active" | "inactive" | "suspended" | "pending_deletion" | "deleted";
944
+ emailVerifiedAt: Date | null;
945
+ phoneVerifiedAt: Date | null;
946
+ lastLoginAt: Date | null;
947
+ }>;
948
+ updateLocale: _spfn_core_route.RouteDef<{
949
+ body: _sinclair_typebox.TObject<{
950
+ locale: _sinclair_typebox.TString;
951
+ }>;
952
+ }, {}, {
953
+ locale: string;
954
+ }>;
955
+ listRoles: _spfn_core_route.RouteDef<{
956
+ query: _sinclair_typebox.TObject<{
957
+ includeInactive: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
958
+ }>;
959
+ }, {}, {
960
+ roles: {
961
+ description: string | null;
962
+ id: number;
963
+ name: string;
964
+ displayName: string;
965
+ isBuiltin: boolean;
966
+ isSystem: boolean;
967
+ isActive: boolean;
968
+ priority: number;
969
+ createdAt: Date;
970
+ updatedAt: Date;
971
+ }[];
972
+ }>;
973
+ createAdminRole: _spfn_core_route.RouteDef<{
974
+ body: _sinclair_typebox.TObject<{
975
+ name: _sinclair_typebox.TString;
976
+ displayName: _sinclair_typebox.TString;
977
+ description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
978
+ priority: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
979
+ permissionIds: _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TNumber>>;
980
+ }>;
981
+ }, {}, {
982
+ role: {
983
+ description: string | null;
984
+ id: number;
985
+ name: string;
986
+ displayName: string;
987
+ isBuiltin: boolean;
988
+ isSystem: boolean;
989
+ isActive: boolean;
990
+ priority: number;
991
+ createdAt: Date;
992
+ updatedAt: Date;
993
+ };
994
+ }>;
995
+ updateAdminRole: _spfn_core_route.RouteDef<{
996
+ params: _sinclair_typebox.TObject<{
997
+ id: _sinclair_typebox.TNumber;
998
+ }>;
999
+ body: _sinclair_typebox.TObject<{
1000
+ displayName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
1001
+ description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
1002
+ priority: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
1003
+ isActive: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
1004
+ }>;
1005
+ }, {}, {
1006
+ role: {
1007
+ description: string | null;
1008
+ id: number;
1009
+ name: string;
1010
+ displayName: string;
1011
+ isBuiltin: boolean;
1012
+ isSystem: boolean;
1013
+ isActive: boolean;
1014
+ priority: number;
1015
+ createdAt: Date;
1016
+ updatedAt: Date;
1017
+ };
1018
+ }>;
1019
+ deleteAdminRole: _spfn_core_route.RouteDef<{
1020
+ params: _sinclair_typebox.TObject<{
1021
+ id: _sinclair_typebox.TNumber;
1022
+ }>;
1023
+ }, {}, void>;
1024
+ updateUserRole: _spfn_core_route.RouteDef<{
1025
+ params: _sinclair_typebox.TObject<{
1026
+ userId: _sinclair_typebox.TNumber;
1027
+ }>;
1028
+ body: _sinclair_typebox.TObject<{
1029
+ roleId: _sinclair_typebox.TNumber;
1030
+ }>;
1031
+ }, {}, {
1032
+ userId: number;
1033
+ roleId: number;
1034
+ }>;
1035
+ }>;
1036
+
1037
+ interface AuthContext {
1038
+ user: User;
1039
+ userId: string;
1040
+ keyId: string;
1041
+ role: string | null;
1042
+ locale: string;
1043
+ }
1044
+ declare module 'hono' {
1045
+ interface ContextVariableMap {
1046
+ auth: AuthContext;
1047
+ }
1048
+ }
1049
+ /**
1050
+ * Authentication middleware
1051
+ *
1052
+ * Verifies client-signed JWT token using stored public key
1053
+ * Must be applied to routes that require authentication
1054
+ *
1055
+ * @example
1056
+ * ```typescript
1057
+ * // In server.config.ts
1058
+ * import { authenticate } from '@spfn/auth/server/middleware';
1059
+ *
1060
+ * export default defineServerConfig()
1061
+ * .middlewares([authenticate])
1062
+ * .routes(appRouter)
1063
+ * .build();
1064
+ *
1065
+ * // In route file - skip auth for public routes
1066
+ * export const publicRoute = route.get('/health')
1067
+ * .skip(['auth']) // Type-safe skip
1068
+ * .handler(async (c) => c.success({ status: 'ok' }));
1069
+ *
1070
+ * // Protected route - auth applied automatically
1071
+ * export const protectedRoute = route.get('/profile')
1072
+ * .handler(async (c) => {
1073
+ * const auth = c.get('auth'); // Get auth context
1074
+ * const { user, userId, keyId } = auth;
1075
+ * // Or access directly: c.get('auth').user
1076
+ * });
1077
+ * ```
1078
+ */
1079
+ declare const authenticate: _spfn_core_route.NamedMiddleware<"auth">;
1080
+ /**
1081
+ * Optional authentication middleware
1082
+ *
1083
+ * Same as `authenticate` but does NOT reject unauthenticated requests.
1084
+ * - No token → continues without auth context
1085
+ * - Invalid token → continues without auth context
1086
+ * - Valid token → sets auth context normally
1087
+ *
1088
+ * Auto-skips the global 'auth' middleware when used at route level.
1089
+ *
1090
+ * @example
1091
+ * ```typescript
1092
+ * // No need for .skip(['auth']) — handled automatically
1093
+ * export const getProducts = route.get('/products')
1094
+ * .use([optionalAuth])
1095
+ * .handler(async (c) => {
1096
+ * const auth = getOptionalAuth(c); // AuthContext | undefined
1097
+ *
1098
+ * if (auth)
1099
+ * {
1100
+ * return getPersonalizedProducts(auth.userId);
1101
+ * }
1102
+ *
1103
+ * return getPublicProducts();
1104
+ * });
1105
+ * ```
1106
+ */
1107
+ declare const optionalAuth: _spfn_core_route.NamedMiddleware<"optionalAuth">;
1108
+
1109
+ export { oauthNativeService as $, type AuthSession as A, rotateKeyService as B, type ChangePasswordParams as C, revokeKeyService as D, type RegisterPublicKeyParams as E, type RotateKeyParams as F, type RevokeKeyParams as G, issueOneTimeTokenService as H, type IssueOneTimeTokenResult as I, verifyOneTimeTokenService as J, oauthStartService as K, type LoginResult as L, oauthCallbackService as M, buildOAuthErrorUrl as N, type OAuthStartResult as O, type PermissionConfig as P, isOAuthProviderEnabled as Q, type RoleConfig as R, type SendVerificationCodeResult as S, requireEnabledProvider as T, type UserProfile as U, type VerificationTargetType as V, getEnabledOAuthProviders as W, getGoogleAccessToken as X, type OAuthStartParams as Y, type OAuthCallbackParams as Z, type OAuthCallbackResult as _, type RegisterResult as a, type OAuthNativeParams as a0, authenticate as a1, optionalAuth as a2, EmailSchema as a3, PhoneSchema as a4, PasswordSchema as a5, TargetTypeSchema as a6, VerificationPurposeSchema as a7, type NormalizedIdentity as a8, type OAuthTokens as a9, type NativeVerifyOptions as aa, type OAuthCodeExchangeOptions as ab, registerOAuthProvider as ac, getOAuthProvider as ad, getRegisteredProviders as ae, type RotateKeyResult as b, type OAuthNativeResult as c, type ProfileInfo as d, type VerificationPurpose as e, VERIFICATION_TARGET_TYPES as f, VERIFICATION_PURPOSES as g, PERMISSION_CATEGORIES as h, type PermissionCategory as i, type AuthInitOptions as j, type OAuthProvider as k, type AuthContext as l, mainAuthRouter as m, loginService as n, logoutService as o, changePasswordService as p, type RegisterParams as q, registerService as r, type LoginParams as s, type LogoutParams as t, sendVerificationCodeService as u, verifyCodeService as v, type SendVerificationCodeParams as w, type VerifyCodeParams as x, type VerifyCodeResult as y, registerPublicKeyService as z };