@spfn/auth 0.2.0-beta.6 → 0.2.0-beta.60
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 +831 -198
- package/dist/{dto-Bb2qFUO6.d.ts → authenticate-B_HkYBzq.d.ts} +449 -199
- package/dist/config.d.ts +176 -44
- package/dist/config.js +99 -35
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +30 -2
- package/dist/errors.js +24 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +289 -113
- package/dist/index.js +59 -1
- package/dist/index.js.map +1 -1
- package/dist/nextjs/api.js +547 -47
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/client.d.ts +28 -0
- package/dist/nextjs/client.js +80 -0
- package/dist/nextjs/client.js.map +1 -0
- package/dist/nextjs/server.d.ts +92 -3
- package/dist/nextjs/server.js +282 -22
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +860 -468
- package/dist/server.js +1454 -607
- package/dist/server.js.map +1 -1
- package/dist/session-Dbvz9Sdp.d.ts +53 -0
- package/dist/types-B1CzVZkU.d.ts +45 -0
- package/migrations/0001_smooth_the_fury.sql +3 -0
- package/migrations/0002_deep_iceman.sql +11 -0
- package/migrations/0003_perfect_deathbird.sql +3 -0
- package/migrations/0004_concerned_rawhide_kid.sql +5 -0
- package/migrations/meta/0001_snapshot.json +1660 -0
- package/migrations/meta/0002_snapshot.json +1660 -0
- package/migrations/meta/0003_snapshot.json +1689 -0
- package/migrations/meta/0004_snapshot.json +1721 -0
- package/migrations/meta/_journal.json +28 -0
- package/package.json +15 -11
|
@@ -1,51 +1,89 @@
|
|
|
1
|
+
import * as _spfn_core_route from '@spfn/core/route';
|
|
2
|
+
import { K as KeyAlgorithmType, d as SocialProvider } from './types-B1CzVZkU.js';
|
|
1
3
|
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
4
|
import { Static } from '@sinclair/typebox';
|
|
3
|
-
import * as _spfn_core_route from '@spfn/core/route';
|
|
4
5
|
import { User } from '@spfn/auth/server';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Common types and constants used across the auth package
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Supported JWT signature algorithms
|
|
13
|
-
*
|
|
14
|
-
* - ES256: ECDSA with P-256 and SHA-256 (recommended, smaller keys)
|
|
15
|
-
* - RS256: RSA with SHA-256 (fallback, larger keys)
|
|
16
|
-
*/
|
|
17
|
-
declare const KEY_ALGORITHM: readonly ["ES256", "RS256"];
|
|
18
|
-
/**
|
|
19
|
-
* Key algorithm type derived from the const array
|
|
20
|
-
*/
|
|
21
|
-
type KeyAlgorithmType = typeof KEY_ALGORITHM[number];
|
|
22
|
-
/**
|
|
23
|
-
* Invitation status enum values
|
|
24
|
-
* Single source of truth for all invitation statuses
|
|
25
|
-
*/
|
|
26
|
-
declare const INVITATION_STATUSES: readonly ["pending", "accepted", "expired", "cancelled"];
|
|
27
|
-
/**
|
|
28
|
-
* Invitation status type derived from the const array
|
|
29
|
-
*/
|
|
30
|
-
type InvitationStatus = typeof INVITATION_STATUSES[number];
|
|
31
|
-
/**
|
|
32
|
-
* User status enum values
|
|
33
|
-
* Single source of truth for all user statuses
|
|
34
|
-
*/
|
|
35
|
-
declare const USER_STATUSES: readonly ["active", "inactive", "suspended"];
|
|
36
|
-
/**
|
|
37
|
-
* User status type derived from the const array
|
|
8
|
+
* Role information for client/API responses
|
|
38
9
|
*/
|
|
39
|
-
|
|
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
|
+
}
|
|
40
22
|
/**
|
|
41
|
-
*
|
|
42
|
-
* Single source of truth for supported OAuth providers
|
|
23
|
+
* Permission information for client/API responses
|
|
43
24
|
*/
|
|
44
|
-
|
|
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
|
+
}
|
|
45
65
|
/**
|
|
46
|
-
*
|
|
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)
|
|
47
74
|
*/
|
|
48
|
-
|
|
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
|
+
}
|
|
49
87
|
|
|
50
88
|
/**
|
|
51
89
|
* @spfn/auth - Auth Service
|
|
@@ -71,9 +109,11 @@ interface RegisterParams {
|
|
|
71
109
|
keyId: string;
|
|
72
110
|
fingerprint: string;
|
|
73
111
|
algorithm?: KeyAlgorithmType;
|
|
112
|
+
metadata?: Record<string, unknown>;
|
|
74
113
|
}
|
|
75
114
|
interface RegisterResult {
|
|
76
115
|
userId: string;
|
|
116
|
+
publicId: string;
|
|
77
117
|
email?: string;
|
|
78
118
|
phone?: string;
|
|
79
119
|
}
|
|
@@ -89,6 +129,7 @@ interface LoginParams {
|
|
|
89
129
|
}
|
|
90
130
|
interface LoginResult {
|
|
91
131
|
userId: string;
|
|
132
|
+
publicId: string;
|
|
92
133
|
email?: string;
|
|
93
134
|
phone?: string;
|
|
94
135
|
passwordChangeRequired: boolean;
|
|
@@ -99,7 +140,7 @@ interface LogoutParams {
|
|
|
99
140
|
}
|
|
100
141
|
interface ChangePasswordParams {
|
|
101
142
|
userId: number;
|
|
102
|
-
currentPassword
|
|
143
|
+
currentPassword?: string;
|
|
103
144
|
newPassword: string;
|
|
104
145
|
passwordHash?: string;
|
|
105
146
|
}
|
|
@@ -299,6 +340,98 @@ interface AuthInitOptions {
|
|
|
299
340
|
sessionTtl?: string | number;
|
|
300
341
|
}
|
|
301
342
|
|
|
343
|
+
/**
|
|
344
|
+
* One-Time Token Service
|
|
345
|
+
*
|
|
346
|
+
* Issues and verifies one-time tokens for direct API access.
|
|
347
|
+
*/
|
|
348
|
+
interface IssueOneTimeTokenResult {
|
|
349
|
+
token: string;
|
|
350
|
+
expiresAt: string;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Issue a one-time token for the authenticated user
|
|
354
|
+
*
|
|
355
|
+
* @param userId - Authenticated user's ID
|
|
356
|
+
* @returns Token string and ISO expiration timestamp
|
|
357
|
+
*/
|
|
358
|
+
declare function issueOneTimeTokenService(userId: string): Promise<IssueOneTimeTokenResult>;
|
|
359
|
+
/**
|
|
360
|
+
* Verify and consume a one-time token
|
|
361
|
+
*
|
|
362
|
+
* @param token - The one-time token to verify
|
|
363
|
+
* @returns userId if valid, null if invalid/expired/consumed
|
|
364
|
+
*/
|
|
365
|
+
declare function verifyOneTimeTokenService(token: string): Promise<string | null>;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* @spfn/auth - OAuth Service
|
|
369
|
+
*
|
|
370
|
+
* OAuth 인증 비즈니스 로직
|
|
371
|
+
* - Google OAuth Authorization Code Flow
|
|
372
|
+
* - 소셜 계정 연결/생성
|
|
373
|
+
* - publicKey는 state에서 추출하여 등록
|
|
374
|
+
*/
|
|
375
|
+
|
|
376
|
+
interface OAuthStartParams {
|
|
377
|
+
provider: SocialProvider;
|
|
378
|
+
returnUrl: string;
|
|
379
|
+
publicKey: string;
|
|
380
|
+
keyId: string;
|
|
381
|
+
fingerprint: string;
|
|
382
|
+
algorithm: KeyAlgorithmType;
|
|
383
|
+
metadata?: Record<string, unknown>;
|
|
384
|
+
}
|
|
385
|
+
interface OAuthStartResult {
|
|
386
|
+
authUrl: string;
|
|
387
|
+
}
|
|
388
|
+
interface OAuthCallbackParams {
|
|
389
|
+
provider: SocialProvider;
|
|
390
|
+
code: string;
|
|
391
|
+
state: string;
|
|
392
|
+
}
|
|
393
|
+
interface OAuthCallbackResult {
|
|
394
|
+
redirectUrl: string;
|
|
395
|
+
userId: string;
|
|
396
|
+
keyId: string;
|
|
397
|
+
isNewUser: boolean;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* OAuth 로그인 시작 - Provider 로그인 페이지로 리다이렉트할 URL 생성
|
|
401
|
+
*
|
|
402
|
+
* Next.js에서 키쌍을 생성한 후, publicKey를 state에 포함하여 호출
|
|
403
|
+
*/
|
|
404
|
+
declare function oauthStartService(params: OAuthStartParams): Promise<OAuthStartResult>;
|
|
405
|
+
/**
|
|
406
|
+
* OAuth 콜백 처리 - Code를 Token으로 교환하고 사용자 생성/연결
|
|
407
|
+
*
|
|
408
|
+
* state에서 publicKey를 추출하여 서버에 등록
|
|
409
|
+
* Next.js는 반환된 userId, keyId로 세션을 구성
|
|
410
|
+
*/
|
|
411
|
+
declare function oauthCallbackService(params: OAuthCallbackParams): Promise<OAuthCallbackResult>;
|
|
412
|
+
/**
|
|
413
|
+
* OAuth 에러 리다이렉트 URL 생성
|
|
414
|
+
*/
|
|
415
|
+
declare function buildOAuthErrorUrl(error: string): string;
|
|
416
|
+
/**
|
|
417
|
+
* OAuth provider가 활성화되어 있는지 확인
|
|
418
|
+
*/
|
|
419
|
+
declare function isOAuthProviderEnabled(provider: SocialProvider): boolean;
|
|
420
|
+
/**
|
|
421
|
+
* 활성화된 모든 OAuth provider 목록
|
|
422
|
+
*/
|
|
423
|
+
declare function getEnabledOAuthProviders(): SocialProvider[];
|
|
424
|
+
/**
|
|
425
|
+
* Google access token 조회 (만료 시 자동 리프레시)
|
|
426
|
+
*
|
|
427
|
+
* 저장된 토큰이 만료 임박(5분 이내) 또는 만료 상태이면
|
|
428
|
+
* refresh token으로 자동 갱신 후 DB 업데이트하여 유효한 토큰 반환.
|
|
429
|
+
*
|
|
430
|
+
* @param userId - 사용자 ID
|
|
431
|
+
* @returns 유효한 Google access token
|
|
432
|
+
*/
|
|
433
|
+
declare function getGoogleAccessToken(userId: number): Promise<string>;
|
|
434
|
+
|
|
302
435
|
/**
|
|
303
436
|
* @spfn/auth - Main Router
|
|
304
437
|
*
|
|
@@ -310,29 +443,151 @@ interface AuthInitOptions {
|
|
|
310
443
|
*
|
|
311
444
|
* Routes:
|
|
312
445
|
* - Auth: /_auth/exists, /_auth/codes, /_auth/login, /_auth/logout, etc.
|
|
446
|
+
* - OAuth: /_auth/oauth/google, /_auth/oauth/google/callback, etc.
|
|
313
447
|
* - Invitations: /_auth/invitations/*
|
|
314
448
|
* - Users: /_auth/users/*
|
|
449
|
+
* - Admin: /_auth/admin/* (superadmin only)
|
|
315
450
|
*/
|
|
316
451
|
declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
317
|
-
|
|
318
|
-
|
|
452
|
+
checkAccountExists: _spfn_core_route.RouteDef<{
|
|
453
|
+
body: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
454
|
+
email: _sinclair_typebox.TString;
|
|
455
|
+
}>, _sinclair_typebox.TObject<{
|
|
456
|
+
phone: _sinclair_typebox.TString;
|
|
457
|
+
}>]>;
|
|
458
|
+
}, {}, CheckAccountExistsResult>;
|
|
459
|
+
sendVerificationCode: _spfn_core_route.RouteDef<{
|
|
319
460
|
body: _sinclair_typebox.TObject<{
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
avatarUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
324
|
-
bio: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
325
|
-
locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
326
|
-
timezone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
327
|
-
dateOfBirth: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
328
|
-
gender: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
329
|
-
website: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
330
|
-
location: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
331
|
-
company: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
332
|
-
jobTitle: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
333
|
-
metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
|
|
461
|
+
target: _sinclair_typebox.TString;
|
|
462
|
+
targetType: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
|
|
463
|
+
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">]>;
|
|
334
464
|
}>;
|
|
335
|
-
}, {},
|
|
465
|
+
}, {}, SendVerificationCodeResult>;
|
|
466
|
+
verifyCode: _spfn_core_route.RouteDef<{
|
|
467
|
+
body: _sinclair_typebox.TObject<{
|
|
468
|
+
target: _sinclair_typebox.TString;
|
|
469
|
+
targetType: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
|
|
470
|
+
code: _sinclair_typebox.TString;
|
|
471
|
+
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">]>;
|
|
472
|
+
}>;
|
|
473
|
+
}, {}, {
|
|
474
|
+
valid: boolean;
|
|
475
|
+
verificationToken: string;
|
|
476
|
+
}>;
|
|
477
|
+
register: _spfn_core_route.RouteDef<{
|
|
478
|
+
body: _sinclair_typebox.TObject<{
|
|
479
|
+
email: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
480
|
+
phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
481
|
+
verificationToken: _sinclair_typebox.TString;
|
|
482
|
+
password: _sinclair_typebox.TString;
|
|
483
|
+
metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
|
|
484
|
+
}>;
|
|
485
|
+
}, {
|
|
486
|
+
body: _sinclair_typebox.TObject<{
|
|
487
|
+
publicKey: _sinclair_typebox.TString;
|
|
488
|
+
keyId: _sinclair_typebox.TString;
|
|
489
|
+
fingerprint: _sinclair_typebox.TString;
|
|
490
|
+
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
491
|
+
}>;
|
|
492
|
+
}, RegisterResult>;
|
|
493
|
+
login: _spfn_core_route.RouteDef<{
|
|
494
|
+
body: _sinclair_typebox.TObject<{
|
|
495
|
+
email: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
496
|
+
phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
497
|
+
password: _sinclair_typebox.TString;
|
|
498
|
+
}>;
|
|
499
|
+
}, {
|
|
500
|
+
body: _sinclair_typebox.TObject<{
|
|
501
|
+
publicKey: _sinclair_typebox.TString;
|
|
502
|
+
keyId: _sinclair_typebox.TString;
|
|
503
|
+
fingerprint: _sinclair_typebox.TString;
|
|
504
|
+
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
505
|
+
oldKeyId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
506
|
+
}>;
|
|
507
|
+
}, LoginResult>;
|
|
508
|
+
logout: _spfn_core_route.RouteDef<{}, {}, void>;
|
|
509
|
+
rotateKey: _spfn_core_route.RouteDef<{}, {
|
|
510
|
+
body: _sinclair_typebox.TObject<{
|
|
511
|
+
publicKey: _sinclair_typebox.TString;
|
|
512
|
+
keyId: _sinclair_typebox.TString;
|
|
513
|
+
fingerprint: _sinclair_typebox.TString;
|
|
514
|
+
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
515
|
+
}>;
|
|
516
|
+
}, RotateKeyResult>;
|
|
517
|
+
changePassword: _spfn_core_route.RouteDef<{
|
|
518
|
+
body: _sinclair_typebox.TObject<{
|
|
519
|
+
currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
520
|
+
newPassword: _sinclair_typebox.TString;
|
|
521
|
+
}>;
|
|
522
|
+
}, {}, void>;
|
|
523
|
+
getAuthSession: _spfn_core_route.RouteDef<{}, {}, {
|
|
524
|
+
role: {
|
|
525
|
+
id: number;
|
|
526
|
+
name: string;
|
|
527
|
+
displayName: string;
|
|
528
|
+
priority: number;
|
|
529
|
+
};
|
|
530
|
+
permissions: {
|
|
531
|
+
id: number;
|
|
532
|
+
name: string;
|
|
533
|
+
displayName: string;
|
|
534
|
+
category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
|
|
535
|
+
}[];
|
|
536
|
+
userId: number;
|
|
537
|
+
publicId: string;
|
|
538
|
+
email: string | null;
|
|
539
|
+
emailVerified: boolean;
|
|
540
|
+
phoneVerified: boolean;
|
|
541
|
+
hasPassword: boolean;
|
|
542
|
+
}>;
|
|
543
|
+
issueOneTimeToken: _spfn_core_route.RouteDef<{}, {}, IssueOneTimeTokenResult>;
|
|
544
|
+
oauthGoogleStart: _spfn_core_route.RouteDef<{
|
|
545
|
+
query: _sinclair_typebox.TObject<{
|
|
546
|
+
state: _sinclair_typebox.TString;
|
|
547
|
+
}>;
|
|
548
|
+
}, {}, Response>;
|
|
549
|
+
oauthGoogleCallback: _spfn_core_route.RouteDef<{
|
|
550
|
+
query: _sinclair_typebox.TObject<{
|
|
551
|
+
code: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
552
|
+
state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
553
|
+
error: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
554
|
+
error_description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
555
|
+
}>;
|
|
556
|
+
}, {}, Response>;
|
|
557
|
+
oauthStart: _spfn_core_route.RouteDef<{
|
|
558
|
+
body: _sinclair_typebox.TObject<{
|
|
559
|
+
provider: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"google" | "github" | "kakao" | "naver">[]>;
|
|
560
|
+
returnUrl: _sinclair_typebox.TString;
|
|
561
|
+
publicKey: _sinclair_typebox.TString;
|
|
562
|
+
keyId: _sinclair_typebox.TString;
|
|
563
|
+
fingerprint: _sinclair_typebox.TString;
|
|
564
|
+
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
565
|
+
metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
|
|
566
|
+
}>;
|
|
567
|
+
}, {}, OAuthStartResult>;
|
|
568
|
+
oauthProviders: _spfn_core_route.RouteDef<{}, {}, {
|
|
569
|
+
providers: ("google" | "github" | "kakao" | "naver")[];
|
|
570
|
+
}>;
|
|
571
|
+
getGoogleOAuthUrl: _spfn_core_route.RouteDef<{
|
|
572
|
+
body: _sinclair_typebox.TObject<{
|
|
573
|
+
returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
574
|
+
state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
575
|
+
}>;
|
|
576
|
+
}, {}, {
|
|
577
|
+
authUrl: string;
|
|
578
|
+
}>;
|
|
579
|
+
oauthFinalize: _spfn_core_route.RouteDef<{
|
|
580
|
+
body: _sinclair_typebox.TObject<{
|
|
581
|
+
userId: _sinclair_typebox.TString;
|
|
582
|
+
keyId: _sinclair_typebox.TString;
|
|
583
|
+
returnUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
584
|
+
}>;
|
|
585
|
+
}, {}, {
|
|
586
|
+
success: boolean;
|
|
587
|
+
userId: string;
|
|
588
|
+
keyId: string;
|
|
589
|
+
returnUrl: string;
|
|
590
|
+
}>;
|
|
336
591
|
getInvitation: _spfn_core_route.RouteDef<{
|
|
337
592
|
params: _sinclair_typebox.TObject<{
|
|
338
593
|
token: _sinclair_typebox.TString;
|
|
@@ -367,6 +622,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
367
622
|
email: _sinclair_typebox.TString;
|
|
368
623
|
roleId: _sinclair_typebox.TNumber;
|
|
369
624
|
expiresInDays: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
625
|
+
expiresAt: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
370
626
|
metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TAny>;
|
|
371
627
|
}>;
|
|
372
628
|
}, {}, {
|
|
@@ -433,97 +689,138 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
|
|
|
433
689
|
id: _sinclair_typebox.TNumber;
|
|
434
690
|
}>;
|
|
435
691
|
}, {}, void>;
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
email: _sinclair_typebox.TString;
|
|
439
|
-
}>, _sinclair_typebox.TObject<{
|
|
440
|
-
phone: _sinclair_typebox.TString;
|
|
441
|
-
}>]>;
|
|
442
|
-
}, {}, CheckAccountExistsResult>;
|
|
443
|
-
sendVerificationCode: _spfn_core_route.RouteDef<{
|
|
692
|
+
getUserProfile: _spfn_core_route.RouteDef<{}, {}, UserProfile>;
|
|
693
|
+
updateUserProfile: _spfn_core_route.RouteDef<{
|
|
444
694
|
body: _sinclair_typebox.TObject<{
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
695
|
+
displayName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
696
|
+
firstName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
697
|
+
lastName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
698
|
+
avatarUrl: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
699
|
+
bio: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
700
|
+
locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
701
|
+
timezone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
702
|
+
dateOfBirth: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
703
|
+
gender: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
704
|
+
website: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
705
|
+
location: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
706
|
+
company: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
707
|
+
jobTitle: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
708
|
+
metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
|
|
448
709
|
}>;
|
|
449
|
-
}, {},
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
targetType: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">]>;
|
|
454
|
-
code: _sinclair_typebox.TString;
|
|
455
|
-
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">]>;
|
|
710
|
+
}, {}, ProfileInfo>;
|
|
711
|
+
checkUsername: _spfn_core_route.RouteDef<{
|
|
712
|
+
query: _sinclair_typebox.TObject<{
|
|
713
|
+
username: _sinclair_typebox.TString;
|
|
456
714
|
}>;
|
|
457
715
|
}, {}, {
|
|
458
|
-
|
|
459
|
-
verificationToken: string;
|
|
716
|
+
available: boolean;
|
|
460
717
|
}>;
|
|
461
|
-
|
|
718
|
+
updateUsername: _spfn_core_route.RouteDef<{
|
|
462
719
|
body: _sinclair_typebox.TObject<{
|
|
463
|
-
|
|
464
|
-
phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
465
|
-
verificationToken: _sinclair_typebox.TString;
|
|
466
|
-
password: _sinclair_typebox.TString;
|
|
720
|
+
username: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
467
721
|
}>;
|
|
468
|
-
}, {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
722
|
+
}, {}, {
|
|
723
|
+
createdAt: Date;
|
|
724
|
+
updatedAt: Date;
|
|
725
|
+
id: number;
|
|
726
|
+
publicId: string;
|
|
727
|
+
email: string | null;
|
|
728
|
+
phone: string | null;
|
|
729
|
+
username: string | null;
|
|
730
|
+
passwordHash: string | null;
|
|
731
|
+
passwordChangeRequired: boolean;
|
|
732
|
+
roleId: number;
|
|
733
|
+
status: "active" | "inactive" | "suspended";
|
|
734
|
+
emailVerifiedAt: Date | null;
|
|
735
|
+
phoneVerifiedAt: Date | null;
|
|
736
|
+
lastLoginAt: Date | null;
|
|
737
|
+
}>;
|
|
738
|
+
updateLocale: _spfn_core_route.RouteDef<{
|
|
477
739
|
body: _sinclair_typebox.TObject<{
|
|
478
|
-
|
|
479
|
-
phone: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
480
|
-
password: _sinclair_typebox.TString;
|
|
740
|
+
locale: _sinclair_typebox.TString;
|
|
481
741
|
}>;
|
|
482
|
-
}, {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
oldKeyId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
489
|
-
}>;
|
|
490
|
-
}, LoginResult>;
|
|
491
|
-
logout: _spfn_core_route.RouteDef<{
|
|
492
|
-
body: _sinclair_typebox.TObject<{}>;
|
|
493
|
-
}, {}, void>;
|
|
494
|
-
rotateKey: _spfn_core_route.RouteDef<{
|
|
495
|
-
body: _sinclair_typebox.TObject<{}>;
|
|
496
|
-
}, {
|
|
497
|
-
body: _sinclair_typebox.TObject<{
|
|
498
|
-
publicKey: _sinclair_typebox.TString;
|
|
499
|
-
keyId: _sinclair_typebox.TString;
|
|
500
|
-
fingerprint: _sinclair_typebox.TString;
|
|
501
|
-
algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
|
|
742
|
+
}, {}, {
|
|
743
|
+
locale: string;
|
|
744
|
+
}>;
|
|
745
|
+
listRoles: _spfn_core_route.RouteDef<{
|
|
746
|
+
query: _sinclair_typebox.TObject<{
|
|
747
|
+
includeInactive: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
|
|
502
748
|
}>;
|
|
503
|
-
},
|
|
504
|
-
|
|
749
|
+
}, {}, {
|
|
750
|
+
roles: {
|
|
751
|
+
description: string | null;
|
|
752
|
+
id: number;
|
|
753
|
+
name: string;
|
|
754
|
+
displayName: string;
|
|
755
|
+
isBuiltin: boolean;
|
|
756
|
+
isSystem: boolean;
|
|
757
|
+
isActive: boolean;
|
|
758
|
+
priority: number;
|
|
759
|
+
createdAt: Date;
|
|
760
|
+
updatedAt: Date;
|
|
761
|
+
}[];
|
|
762
|
+
}>;
|
|
763
|
+
createAdminRole: _spfn_core_route.RouteDef<{
|
|
505
764
|
body: _sinclair_typebox.TObject<{
|
|
506
|
-
|
|
507
|
-
|
|
765
|
+
name: _sinclair_typebox.TString;
|
|
766
|
+
displayName: _sinclair_typebox.TString;
|
|
767
|
+
description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
768
|
+
priority: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
769
|
+
permissionIds: _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TNumber>>;
|
|
508
770
|
}>;
|
|
509
|
-
}, {},
|
|
510
|
-
getAuthSession: _spfn_core_route.RouteDef<{}, {}, {
|
|
771
|
+
}, {}, {
|
|
511
772
|
role: {
|
|
773
|
+
description: string | null;
|
|
512
774
|
id: number;
|
|
513
775
|
name: string;
|
|
514
776
|
displayName: string;
|
|
777
|
+
isBuiltin: boolean;
|
|
778
|
+
isSystem: boolean;
|
|
779
|
+
isActive: boolean;
|
|
515
780
|
priority: number;
|
|
781
|
+
createdAt: Date;
|
|
782
|
+
updatedAt: Date;
|
|
516
783
|
};
|
|
517
|
-
|
|
784
|
+
}>;
|
|
785
|
+
updateAdminRole: _spfn_core_route.RouteDef<{
|
|
786
|
+
params: _sinclair_typebox.TObject<{
|
|
787
|
+
id: _sinclair_typebox.TNumber;
|
|
788
|
+
}>;
|
|
789
|
+
body: _sinclair_typebox.TObject<{
|
|
790
|
+
displayName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
791
|
+
description: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
792
|
+
priority: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
793
|
+
isActive: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
|
|
794
|
+
}>;
|
|
795
|
+
}, {}, {
|
|
796
|
+
role: {
|
|
797
|
+
description: string | null;
|
|
518
798
|
id: number;
|
|
519
799
|
name: string;
|
|
520
800
|
displayName: string;
|
|
521
|
-
|
|
522
|
-
|
|
801
|
+
isBuiltin: boolean;
|
|
802
|
+
isSystem: boolean;
|
|
803
|
+
isActive: boolean;
|
|
804
|
+
priority: number;
|
|
805
|
+
createdAt: Date;
|
|
806
|
+
updatedAt: Date;
|
|
807
|
+
};
|
|
808
|
+
}>;
|
|
809
|
+
deleteAdminRole: _spfn_core_route.RouteDef<{
|
|
810
|
+
params: _sinclair_typebox.TObject<{
|
|
811
|
+
id: _sinclair_typebox.TNumber;
|
|
812
|
+
}>;
|
|
813
|
+
}, {}, void>;
|
|
814
|
+
updateUserRole: _spfn_core_route.RouteDef<{
|
|
815
|
+
params: _sinclair_typebox.TObject<{
|
|
816
|
+
userId: _sinclair_typebox.TNumber;
|
|
817
|
+
}>;
|
|
818
|
+
body: _sinclair_typebox.TObject<{
|
|
819
|
+
roleId: _sinclair_typebox.TNumber;
|
|
820
|
+
}>;
|
|
821
|
+
}, {}, {
|
|
523
822
|
userId: number;
|
|
524
|
-
|
|
525
|
-
emailVerified: boolean;
|
|
526
|
-
phoneVerified: boolean;
|
|
823
|
+
roleId: number;
|
|
527
824
|
}>;
|
|
528
825
|
}>;
|
|
529
826
|
|
|
@@ -531,6 +828,8 @@ interface AuthContext {
|
|
|
531
828
|
user: User;
|
|
532
829
|
userId: string;
|
|
533
830
|
keyId: string;
|
|
831
|
+
role: string | null;
|
|
832
|
+
locale: string;
|
|
534
833
|
}
|
|
535
834
|
declare module 'hono' {
|
|
536
835
|
interface ContextVariableMap {
|
|
@@ -568,82 +867,33 @@ declare module 'hono' {
|
|
|
568
867
|
* ```
|
|
569
868
|
*/
|
|
570
869
|
declare const authenticate: _spfn_core_route.NamedMiddleware<"auth">;
|
|
571
|
-
|
|
572
|
-
/**
|
|
573
|
-
* Role information for client/API responses
|
|
574
|
-
*/
|
|
575
|
-
interface Role {
|
|
576
|
-
id: number;
|
|
577
|
-
name: string;
|
|
578
|
-
displayName: string;
|
|
579
|
-
description: string | null;
|
|
580
|
-
isBuiltin: boolean;
|
|
581
|
-
isSystem: boolean;
|
|
582
|
-
isActive: boolean;
|
|
583
|
-
priority: number;
|
|
584
|
-
createdAt: Date;
|
|
585
|
-
updatedAt: Date;
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* Permission information for client/API responses
|
|
589
|
-
*/
|
|
590
|
-
interface Permission {
|
|
591
|
-
id: number;
|
|
592
|
-
name: string;
|
|
593
|
-
displayName: string;
|
|
594
|
-
description: string | null;
|
|
595
|
-
category: string | null;
|
|
596
|
-
isBuiltin: boolean;
|
|
597
|
-
isSystem: boolean;
|
|
598
|
-
isActive: boolean;
|
|
599
|
-
metadata: Record<string, any> | null;
|
|
600
|
-
createdAt: Date;
|
|
601
|
-
updatedAt: Date;
|
|
602
|
-
}
|
|
603
|
-
interface AuthSession {
|
|
604
|
-
userId: number;
|
|
605
|
-
email: string | null;
|
|
606
|
-
emailVerified: boolean;
|
|
607
|
-
phoneVerified: boolean;
|
|
608
|
-
role: Role;
|
|
609
|
-
permissions: Permission[];
|
|
610
|
-
}
|
|
611
|
-
interface ProfileInfo {
|
|
612
|
-
profileId: number;
|
|
613
|
-
displayName: string;
|
|
614
|
-
firstName: string | null;
|
|
615
|
-
lastName: string | null;
|
|
616
|
-
avatarUrl: string | null;
|
|
617
|
-
bio: string | null;
|
|
618
|
-
locale: string;
|
|
619
|
-
timezone: string;
|
|
620
|
-
website: string | null;
|
|
621
|
-
location: string | null;
|
|
622
|
-
company: string | null;
|
|
623
|
-
jobTitle: string | null;
|
|
624
|
-
metadata: Record<string, any> | null;
|
|
625
|
-
createdAt: Date;
|
|
626
|
-
updatedAt: Date;
|
|
627
|
-
}
|
|
628
870
|
/**
|
|
629
|
-
*
|
|
871
|
+
* Optional authentication middleware
|
|
630
872
|
*
|
|
631
|
-
*
|
|
632
|
-
* -
|
|
633
|
-
* -
|
|
873
|
+
* Same as `authenticate` but does NOT reject unauthenticated requests.
|
|
874
|
+
* - No token → continues without auth context
|
|
875
|
+
* - Invalid token → continues without auth context
|
|
876
|
+
* - Valid token → sets auth context normally
|
|
634
877
|
*
|
|
635
|
-
*
|
|
636
|
-
*
|
|
878
|
+
* Auto-skips the global 'auth' middleware when used at route level.
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* // No need for .skip(['auth']) — handled automatically
|
|
883
|
+
* export const getProducts = route.get('/products')
|
|
884
|
+
* .use([optionalAuth])
|
|
885
|
+
* .handler(async (c) => {
|
|
886
|
+
* const auth = getOptionalAuth(c); // AuthContext | undefined
|
|
887
|
+
*
|
|
888
|
+
* if (auth)
|
|
889
|
+
* {
|
|
890
|
+
* return getPersonalizedProducts(auth.userId);
|
|
891
|
+
* }
|
|
892
|
+
*
|
|
893
|
+
* return getPublicProducts();
|
|
894
|
+
* });
|
|
895
|
+
* ```
|
|
637
896
|
*/
|
|
638
|
-
|
|
639
|
-
userId: number;
|
|
640
|
-
email: string | null;
|
|
641
|
-
emailVerified: boolean;
|
|
642
|
-
phoneVerified: boolean;
|
|
643
|
-
lastLoginAt: Date | null;
|
|
644
|
-
createdAt: Date;
|
|
645
|
-
updatedAt: Date;
|
|
646
|
-
profile: ProfileInfo | null;
|
|
647
|
-
}
|
|
897
|
+
declare const optionalAuth: _spfn_core_route.NamedMiddleware<"optionalAuth">;
|
|
648
898
|
|
|
649
|
-
export {
|
|
899
|
+
export { authenticate as $, type AuthSession as A, registerPublicKeyService as B, type CheckAccountExistsResult as C, rotateKeyService as D, revokeKeyService as E, type RegisterPublicKeyParams as F, type RotateKeyParams as G, type RevokeKeyParams as H, type IssueOneTimeTokenResult as I, issueOneTimeTokenService as J, verifyOneTimeTokenService as K, type LoginResult as L, oauthStartService as M, oauthCallbackService as N, type OAuthStartResult as O, type PermissionConfig as P, buildOAuthErrorUrl as Q, type RoleConfig as R, type SendVerificationCodeResult as S, isOAuthProviderEnabled 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, optionalAuth as a0, EmailSchema as a1, PhoneSchema as a2, PasswordSchema as a3, TargetTypeSchema as a4, VerificationPurposeSchema as a5, type RotateKeyResult as b, type ProfileInfo as c, type VerificationPurpose as d, VERIFICATION_TARGET_TYPES as e, VERIFICATION_PURPOSES as f, PERMISSION_CATEGORIES as g, type PermissionCategory as h, type AuthInitOptions as i, type AuthContext as j, checkAccountExistsService as k, loginService as l, mainAuthRouter as m, logoutService as n, changePasswordService as o, type CheckAccountExistsParams as p, type RegisterParams as q, registerService as r, type LoginParams as s, type LogoutParams as t, type ChangePasswordParams as u, sendVerificationCodeService as v, verifyCodeService as w, type SendVerificationCodeParams as x, type VerifyCodeParams as y, type VerifyCodeResult as z };
|