@spfn/auth 0.2.0-beta.4 → 0.2.0-beta.41
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 +713 -180
- package/dist/{dto-Bb2qFUO6.d.ts → authenticate-2953PCm8.d.ts} +420 -161
- package/dist/config.d.ts +156 -44
- package/dist/config.js +90 -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 +283 -113
- package/dist/index.js +58 -1
- package/dist/index.js.map +1 -1
- package/dist/nextjs/api.js +202 -1
- 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 +89 -2
- package/dist/nextjs/server.js +146 -21
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +564 -443
- package/dist/server.js +1030 -492
- package/dist/server.js.map +1 -1
- package/migrations/0001_smooth_the_fury.sql +3 -0
- package/migrations/meta/0001_snapshot.json +1660 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +13 -9
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as AuthInitOptions, l as KeyAlgorithmType, n as InvitationStatus, f as VerificationPurpose, j as PermissionCategory, q as AuthContext } from './
|
|
2
|
-
export { B as ChangePasswordParams, w as CheckAccountExistsParams, C as CheckAccountExistsResult,
|
|
1
|
+
import { k as AuthInitOptions, l as KeyAlgorithmType, n as InvitationStatus, f as VerificationPurpose, j as PermissionCategory, p as SocialProvider, q as AuthContext } from './authenticate-2953PCm8.js';
|
|
2
|
+
export { B as ChangePasswordParams, w as CheckAccountExistsParams, C as CheckAccountExistsResult, a6 as EmailSchema, I as INVITATION_STATUSES, K as KEY_ALGORITHM, y as LoginParams, L as LoginResult, z as LogoutParams, a2 as OAuthCallbackParams, a3 as OAuthCallbackResult, a1 as OAuthStartParams, O as OAuthStartResult, a8 as PasswordSchema, a7 as PhoneSchema, x as RegisterParams, Q as RegisterPublicKeyParams, a as RegisterResult, W as RevokeKeyParams, T as RotateKeyParams, b as RotateKeyResult, e as SOCIAL_PROVIDERS, F as SendVerificationCodeParams, S as SendVerificationCodeResult, a9 as TargetTypeSchema, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, aa as VerificationPurposeSchema, V as VerificationTargetType, G as VerifyCodeParams, H as VerifyCodeResult, m as authRouter, a4 as authenticate, Z as buildOAuthErrorUrl, v as changePasswordService, r as checkAccountExistsService, $ as getEnabledOAuthProviders, a0 as getGoogleAccessToken, _ as isOAuthProviderEnabled, t as loginService, u as logoutService, Y as oauthCallbackService, X as oauthStartService, a5 as optionalAuth, J as registerPublicKeyService, s as registerService, N as revokeKeyService, M as rotateKeyService, D as sendVerificationCodeService, E as verifyCodeService } from './authenticate-2953PCm8.js';
|
|
3
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
4
4
|
import { UserProfile as UserProfile$1, ProfileInfo } from '@spfn/auth';
|
|
5
5
|
import { BaseRepository } from '@spfn/core/db';
|
|
@@ -7,7 +7,8 @@ import { Context } from 'hono';
|
|
|
7
7
|
import * as _spfn_core_route from '@spfn/core/route';
|
|
8
8
|
import { Algorithm } from 'jsonwebtoken';
|
|
9
9
|
import * as _spfn_core_logger from '@spfn/core/logger';
|
|
10
|
-
import '@
|
|
10
|
+
import * as _spfn_core_event from '@spfn/core/event';
|
|
11
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
11
12
|
import '@spfn/auth/server';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -112,6 +113,23 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
112
113
|
identity: undefined;
|
|
113
114
|
generated: undefined;
|
|
114
115
|
}, {}, {}>;
|
|
116
|
+
username: drizzle_orm_pg_core.PgColumn<{
|
|
117
|
+
name: "username";
|
|
118
|
+
tableName: "users";
|
|
119
|
+
dataType: "string";
|
|
120
|
+
columnType: "PgText";
|
|
121
|
+
data: string;
|
|
122
|
+
driverParam: string;
|
|
123
|
+
notNull: false;
|
|
124
|
+
hasDefault: false;
|
|
125
|
+
isPrimaryKey: false;
|
|
126
|
+
isAutoincrement: false;
|
|
127
|
+
hasRuntimeDefault: false;
|
|
128
|
+
enumValues: [string, ...string[]];
|
|
129
|
+
baseColumn: never;
|
|
130
|
+
identity: undefined;
|
|
131
|
+
generated: undefined;
|
|
132
|
+
}, {}, {}>;
|
|
115
133
|
passwordHash: drizzle_orm_pg_core.PgColumn<{
|
|
116
134
|
name: "password_hash";
|
|
117
135
|
tableName: "users";
|
|
@@ -150,11 +168,11 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
150
168
|
name: `${string}_id`;
|
|
151
169
|
tableName: "users";
|
|
152
170
|
dataType: "number";
|
|
153
|
-
columnType: "
|
|
171
|
+
columnType: "PgBigInt53";
|
|
154
172
|
data: number;
|
|
155
|
-
driverParam: number;
|
|
173
|
+
driverParam: string | number;
|
|
156
174
|
notNull: true;
|
|
157
|
-
hasDefault:
|
|
175
|
+
hasDefault: false;
|
|
158
176
|
isPrimaryKey: false;
|
|
159
177
|
isAutoincrement: false;
|
|
160
178
|
hasRuntimeDefault: false;
|
|
@@ -252,6 +270,7 @@ declare function getUserByIdService(userId: number): Promise<{
|
|
|
252
270
|
id: number;
|
|
253
271
|
email: string | null;
|
|
254
272
|
phone: string | null;
|
|
273
|
+
username: string | null;
|
|
255
274
|
passwordHash: string | null;
|
|
256
275
|
passwordChangeRequired: boolean;
|
|
257
276
|
roleId: number;
|
|
@@ -269,6 +288,7 @@ declare function getUserByEmailService(email: string): Promise<{
|
|
|
269
288
|
id: number;
|
|
270
289
|
email: string | null;
|
|
271
290
|
phone: string | null;
|
|
291
|
+
username: string | null;
|
|
272
292
|
passwordHash: string | null;
|
|
273
293
|
passwordChangeRequired: boolean;
|
|
274
294
|
roleId: number;
|
|
@@ -286,6 +306,7 @@ declare function getUserByPhoneService(phone: string): Promise<{
|
|
|
286
306
|
id: number;
|
|
287
307
|
email: string | null;
|
|
288
308
|
phone: string | null;
|
|
309
|
+
username: string | null;
|
|
289
310
|
passwordHash: string | null;
|
|
290
311
|
passwordChangeRequired: boolean;
|
|
291
312
|
roleId: number;
|
|
@@ -302,6 +323,35 @@ declare function updateLastLoginService(userId: number): Promise<void>;
|
|
|
302
323
|
* Update user data
|
|
303
324
|
*/
|
|
304
325
|
declare function updateUserService(userId: number, updates: Partial<NewUser>): Promise<void>;
|
|
326
|
+
/**
|
|
327
|
+
* Check if username is available
|
|
328
|
+
*
|
|
329
|
+
* @returns true if the username is available (not taken and not reserved)
|
|
330
|
+
*/
|
|
331
|
+
declare function checkUsernameAvailableService(username: string): Promise<boolean>;
|
|
332
|
+
/**
|
|
333
|
+
* Update username with reserved word and duplicate check
|
|
334
|
+
*
|
|
335
|
+
* @param userId - User ID (string, number, or bigint)
|
|
336
|
+
* @param username - New username or null to clear
|
|
337
|
+
* @throws ReservedUsernameError if username is reserved
|
|
338
|
+
* @throws UsernameAlreadyTakenError if username is already in use by another user
|
|
339
|
+
*/
|
|
340
|
+
declare function updateUsernameService(userId: string | number | bigint, username: string | null): Promise<{
|
|
341
|
+
createdAt: Date;
|
|
342
|
+
updatedAt: Date;
|
|
343
|
+
id: number;
|
|
344
|
+
email: string | null;
|
|
345
|
+
phone: string | null;
|
|
346
|
+
username: string | null;
|
|
347
|
+
passwordHash: string | null;
|
|
348
|
+
passwordChangeRequired: boolean;
|
|
349
|
+
roleId: number;
|
|
350
|
+
status: "active" | "inactive" | "suspended";
|
|
351
|
+
emailVerifiedAt: Date | null;
|
|
352
|
+
phoneVerifiedAt: Date | null;
|
|
353
|
+
lastLoginAt: Date | null;
|
|
354
|
+
}>;
|
|
305
355
|
|
|
306
356
|
/**
|
|
307
357
|
* @spfn/auth - RBAC Initialization Service
|
|
@@ -880,11 +930,11 @@ declare const userInvitations: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
880
930
|
name: `${string}_id`;
|
|
881
931
|
tableName: "user_invitations";
|
|
882
932
|
dataType: "number";
|
|
883
|
-
columnType: "
|
|
933
|
+
columnType: "PgBigInt53";
|
|
884
934
|
data: number;
|
|
885
|
-
driverParam: number;
|
|
935
|
+
driverParam: string | number;
|
|
886
936
|
notNull: true;
|
|
887
|
-
hasDefault:
|
|
937
|
+
hasDefault: false;
|
|
888
938
|
isPrimaryKey: false;
|
|
889
939
|
isAutoincrement: false;
|
|
890
940
|
hasRuntimeDefault: false;
|
|
@@ -897,11 +947,11 @@ declare const userInvitations: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
897
947
|
name: `${string}_id`;
|
|
898
948
|
tableName: "user_invitations";
|
|
899
949
|
dataType: "number";
|
|
900
|
-
columnType: "
|
|
950
|
+
columnType: "PgBigInt53";
|
|
901
951
|
data: number;
|
|
902
|
-
driverParam: number;
|
|
952
|
+
driverParam: string | number;
|
|
903
953
|
notNull: true;
|
|
904
|
-
hasDefault:
|
|
954
|
+
hasDefault: false;
|
|
905
955
|
isPrimaryKey: false;
|
|
906
956
|
isAutoincrement: false;
|
|
907
957
|
hasRuntimeDefault: false;
|
|
@@ -1255,7 +1305,7 @@ declare function getAuthSessionService(userId: string | number | bigint): Promis
|
|
|
1255
1305
|
id: number;
|
|
1256
1306
|
name: string;
|
|
1257
1307
|
displayName: string;
|
|
1258
|
-
category: "
|
|
1308
|
+
category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
|
|
1259
1309
|
}[];
|
|
1260
1310
|
userId: number;
|
|
1261
1311
|
email: string | null;
|
|
@@ -1305,6 +1355,16 @@ interface UpdateProfileParams {
|
|
|
1305
1355
|
* ```
|
|
1306
1356
|
*/
|
|
1307
1357
|
declare function getUserProfileService(userId: string | number | bigint): Promise<UserProfile$1>;
|
|
1358
|
+
/**
|
|
1359
|
+
* Update user locale
|
|
1360
|
+
*
|
|
1361
|
+
* @param userId - User ID
|
|
1362
|
+
* @param locale - Locale code (e.g., 'en', 'ko', 'ja')
|
|
1363
|
+
* @returns Updated locale
|
|
1364
|
+
*/
|
|
1365
|
+
declare function updateLocaleService(userId: string | number | bigint, locale: string): Promise<{
|
|
1366
|
+
locale: string;
|
|
1367
|
+
}>;
|
|
1308
1368
|
/**
|
|
1309
1369
|
* Update user profile (upsert)
|
|
1310
1370
|
*
|
|
@@ -1326,369 +1386,6 @@ declare function getUserProfileService(userId: string | number | bigint): Promis
|
|
|
1326
1386
|
*/
|
|
1327
1387
|
declare function updateUserProfileService(userId: string | number | bigint, params: UpdateProfileParams): Promise<ProfileInfo>;
|
|
1328
1388
|
|
|
1329
|
-
/**
|
|
1330
|
-
* @spfn/auth - Email Template Types
|
|
1331
|
-
*
|
|
1332
|
-
* Type definitions for customizable email templates
|
|
1333
|
-
*/
|
|
1334
|
-
/**
|
|
1335
|
-
* Common template result
|
|
1336
|
-
*/
|
|
1337
|
-
interface EmailTemplateResult {
|
|
1338
|
-
subject: string;
|
|
1339
|
-
text: string;
|
|
1340
|
-
html: string;
|
|
1341
|
-
}
|
|
1342
|
-
/**
|
|
1343
|
-
* Verification code template parameters
|
|
1344
|
-
*/
|
|
1345
|
-
interface VerificationCodeParams {
|
|
1346
|
-
code: string;
|
|
1347
|
-
purpose: 'registration' | 'login' | 'password_reset' | string;
|
|
1348
|
-
expiresInMinutes?: number;
|
|
1349
|
-
appName?: string;
|
|
1350
|
-
}
|
|
1351
|
-
/**
|
|
1352
|
-
* Email template provider interface
|
|
1353
|
-
*
|
|
1354
|
-
* Implement this interface to create custom email templates
|
|
1355
|
-
*
|
|
1356
|
-
* @example
|
|
1357
|
-
* ```typescript
|
|
1358
|
-
* import { registerEmailTemplates } from '@spfn/auth/server';
|
|
1359
|
-
*
|
|
1360
|
-
* registerEmailTemplates({
|
|
1361
|
-
* verificationCode: (params) => ({
|
|
1362
|
-
* subject: 'Your Code',
|
|
1363
|
-
* text: `Code: ${params.code}`,
|
|
1364
|
-
* html: `<h1>Code: ${params.code}</h1>`,
|
|
1365
|
-
* }),
|
|
1366
|
-
* });
|
|
1367
|
-
* ```
|
|
1368
|
-
*/
|
|
1369
|
-
interface EmailTemplateProvider {
|
|
1370
|
-
/**
|
|
1371
|
-
* Verification code email template
|
|
1372
|
-
*/
|
|
1373
|
-
verificationCode?(params: VerificationCodeParams): EmailTemplateResult;
|
|
1374
|
-
/**
|
|
1375
|
-
* Welcome email template (after registration)
|
|
1376
|
-
*/
|
|
1377
|
-
welcome?(params: {
|
|
1378
|
-
email: string;
|
|
1379
|
-
appName?: string;
|
|
1380
|
-
}): EmailTemplateResult;
|
|
1381
|
-
/**
|
|
1382
|
-
* Password reset email template
|
|
1383
|
-
*/
|
|
1384
|
-
passwordReset?(params: {
|
|
1385
|
-
resetLink: string;
|
|
1386
|
-
expiresInMinutes?: number;
|
|
1387
|
-
appName?: string;
|
|
1388
|
-
}): EmailTemplateResult;
|
|
1389
|
-
/**
|
|
1390
|
-
* Invitation email template
|
|
1391
|
-
*/
|
|
1392
|
-
invitation?(params: {
|
|
1393
|
-
inviteLink: string;
|
|
1394
|
-
inviterName?: string;
|
|
1395
|
-
roleName?: string;
|
|
1396
|
-
appName?: string;
|
|
1397
|
-
}): EmailTemplateResult;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
/**
|
|
1401
|
-
* @spfn/auth - Email Template Registry
|
|
1402
|
-
*
|
|
1403
|
-
* Manages custom email template registration and fallback to defaults
|
|
1404
|
-
*/
|
|
1405
|
-
|
|
1406
|
-
/**
|
|
1407
|
-
* Register custom email templates
|
|
1408
|
-
*
|
|
1409
|
-
* Templates not provided will fall back to defaults
|
|
1410
|
-
*
|
|
1411
|
-
* @param templates - Custom template implementations
|
|
1412
|
-
*
|
|
1413
|
-
* @example
|
|
1414
|
-
* ```typescript
|
|
1415
|
-
* import { registerEmailTemplates } from '@spfn/auth/server';
|
|
1416
|
-
*
|
|
1417
|
-
* // Override verification code template with custom design
|
|
1418
|
-
* registerEmailTemplates({
|
|
1419
|
-
* verificationCode: ({ code, purpose, expiresInMinutes }) => ({
|
|
1420
|
-
* subject: `[MyApp] Your verification code`,
|
|
1421
|
-
* text: `Your code is: ${code}`,
|
|
1422
|
-
* html: `
|
|
1423
|
-
* <div style="font-family: Arial;">
|
|
1424
|
-
* <h1>Welcome to MyApp!</h1>
|
|
1425
|
-
* <p>Your code: <strong>${code}</strong></p>
|
|
1426
|
-
* </div>
|
|
1427
|
-
* `,
|
|
1428
|
-
* }),
|
|
1429
|
-
* });
|
|
1430
|
-
* ```
|
|
1431
|
-
*/
|
|
1432
|
-
declare function registerEmailTemplates(templates: Partial<EmailTemplateProvider>): void;
|
|
1433
|
-
/**
|
|
1434
|
-
* Get verification code template
|
|
1435
|
-
*
|
|
1436
|
-
* Uses custom template if registered, otherwise falls back to default
|
|
1437
|
-
*/
|
|
1438
|
-
declare function getVerificationCodeTemplate(params: VerificationCodeParams): EmailTemplateResult;
|
|
1439
|
-
/**
|
|
1440
|
-
* Get welcome template
|
|
1441
|
-
*/
|
|
1442
|
-
declare function getWelcomeTemplate(params: {
|
|
1443
|
-
email: string;
|
|
1444
|
-
appName?: string;
|
|
1445
|
-
}): EmailTemplateResult;
|
|
1446
|
-
/**
|
|
1447
|
-
* Get password reset template
|
|
1448
|
-
*/
|
|
1449
|
-
declare function getPasswordResetTemplate(params: {
|
|
1450
|
-
resetLink: string;
|
|
1451
|
-
expiresInMinutes?: number;
|
|
1452
|
-
appName?: string;
|
|
1453
|
-
}): EmailTemplateResult;
|
|
1454
|
-
/**
|
|
1455
|
-
* Get invitation template
|
|
1456
|
-
*/
|
|
1457
|
-
declare function getInvitationTemplate(params: {
|
|
1458
|
-
inviteLink: string;
|
|
1459
|
-
inviterName?: string;
|
|
1460
|
-
roleName?: string;
|
|
1461
|
-
appName?: string;
|
|
1462
|
-
}): EmailTemplateResult;
|
|
1463
|
-
|
|
1464
|
-
/**
|
|
1465
|
-
* @spfn/auth - Email Service Types
|
|
1466
|
-
*
|
|
1467
|
-
* Type definitions for email sending service
|
|
1468
|
-
*/
|
|
1469
|
-
/**
|
|
1470
|
-
* Parameters for sending email
|
|
1471
|
-
*/
|
|
1472
|
-
interface SendEmailParams {
|
|
1473
|
-
/**
|
|
1474
|
-
* Recipient email address
|
|
1475
|
-
*/
|
|
1476
|
-
to: string;
|
|
1477
|
-
/**
|
|
1478
|
-
* Email subject
|
|
1479
|
-
*/
|
|
1480
|
-
subject: string;
|
|
1481
|
-
/**
|
|
1482
|
-
* Plain text content
|
|
1483
|
-
*/
|
|
1484
|
-
text?: string;
|
|
1485
|
-
/**
|
|
1486
|
-
* HTML content
|
|
1487
|
-
*/
|
|
1488
|
-
html?: string;
|
|
1489
|
-
/**
|
|
1490
|
-
* Purpose of the email (for logging)
|
|
1491
|
-
*/
|
|
1492
|
-
purpose?: string;
|
|
1493
|
-
}
|
|
1494
|
-
/**
|
|
1495
|
-
* Result of sending email
|
|
1496
|
-
*/
|
|
1497
|
-
interface SendEmailResult {
|
|
1498
|
-
/**
|
|
1499
|
-
* Whether email was sent successfully
|
|
1500
|
-
*/
|
|
1501
|
-
success: boolean;
|
|
1502
|
-
/**
|
|
1503
|
-
* Message ID from email provider (if successful)
|
|
1504
|
-
*/
|
|
1505
|
-
messageId?: string;
|
|
1506
|
-
/**
|
|
1507
|
-
* Error message (if failed)
|
|
1508
|
-
*/
|
|
1509
|
-
error?: string;
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
* Email Provider Interface
|
|
1513
|
-
*
|
|
1514
|
-
* Implement this interface to create custom email providers
|
|
1515
|
-
*
|
|
1516
|
-
* @example
|
|
1517
|
-
* ```typescript
|
|
1518
|
-
* import { EmailProvider, registerEmailProvider } from '@spfn/auth/server/services/email';
|
|
1519
|
-
*
|
|
1520
|
-
* const sendgridProvider: EmailProvider = {
|
|
1521
|
-
* name: 'sendgrid',
|
|
1522
|
-
* sendEmail: async (params) => {
|
|
1523
|
-
* // Your SendGrid implementation
|
|
1524
|
-
* return { success: true, messageId: '...' };
|
|
1525
|
-
* }
|
|
1526
|
-
* };
|
|
1527
|
-
*
|
|
1528
|
-
* registerEmailProvider(sendgridProvider);
|
|
1529
|
-
* ```
|
|
1530
|
-
*/
|
|
1531
|
-
interface EmailProvider {
|
|
1532
|
-
/**
|
|
1533
|
-
* Provider name (e.g., 'aws-ses', 'sendgrid', 'custom')
|
|
1534
|
-
*/
|
|
1535
|
-
name: string;
|
|
1536
|
-
/**
|
|
1537
|
-
* Send email via this provider
|
|
1538
|
-
*
|
|
1539
|
-
* @param params - Email parameters
|
|
1540
|
-
* @returns Send result
|
|
1541
|
-
*/
|
|
1542
|
-
sendEmail(params: SendEmailParams): Promise<SendEmailResult>;
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
/**
|
|
1546
|
-
* @spfn/auth - Email Provider Management
|
|
1547
|
-
*
|
|
1548
|
-
* Manages email provider registration and fallback behavior
|
|
1549
|
-
*/
|
|
1550
|
-
|
|
1551
|
-
/**
|
|
1552
|
-
* Register a custom email provider
|
|
1553
|
-
*
|
|
1554
|
-
* @param provider - Custom email provider implementation
|
|
1555
|
-
*
|
|
1556
|
-
* @example
|
|
1557
|
-
* ```typescript
|
|
1558
|
-
* import { registerEmailProvider } from '@spfn/auth/server/services/email';
|
|
1559
|
-
*
|
|
1560
|
-
* const sendgridProvider = {
|
|
1561
|
-
* name: 'sendgrid',
|
|
1562
|
-
* sendEmail: async (params) => {
|
|
1563
|
-
* // SendGrid implementation
|
|
1564
|
-
* return { success: true, messageId: '...' };
|
|
1565
|
-
* }
|
|
1566
|
-
* };
|
|
1567
|
-
*
|
|
1568
|
-
* registerEmailProvider(sendgridProvider);
|
|
1569
|
-
* ```
|
|
1570
|
-
*/
|
|
1571
|
-
declare function registerEmailProvider(provider: EmailProvider): void;
|
|
1572
|
-
/**
|
|
1573
|
-
* Send email using the registered provider
|
|
1574
|
-
*
|
|
1575
|
-
* Falls back to development mode (console only) if no provider is registered
|
|
1576
|
-
*
|
|
1577
|
-
* @param params - Email parameters
|
|
1578
|
-
* @returns Send result
|
|
1579
|
-
*/
|
|
1580
|
-
declare function sendEmail(params: SendEmailParams): Promise<SendEmailResult>;
|
|
1581
|
-
|
|
1582
|
-
/**
|
|
1583
|
-
* @spfn/auth - SMS Service Types
|
|
1584
|
-
*
|
|
1585
|
-
* Type definitions for SMS sending service
|
|
1586
|
-
*/
|
|
1587
|
-
/**
|
|
1588
|
-
* Parameters for sending SMS
|
|
1589
|
-
*/
|
|
1590
|
-
interface SendSMSParams {
|
|
1591
|
-
/**
|
|
1592
|
-
* Phone number in E.164 format (e.g., +821012345678)
|
|
1593
|
-
*/
|
|
1594
|
-
phone: string;
|
|
1595
|
-
/**
|
|
1596
|
-
* SMS message content
|
|
1597
|
-
*/
|
|
1598
|
-
message: string;
|
|
1599
|
-
/**
|
|
1600
|
-
* Purpose of the SMS (for logging)
|
|
1601
|
-
*/
|
|
1602
|
-
purpose?: string;
|
|
1603
|
-
}
|
|
1604
|
-
/**
|
|
1605
|
-
* Result of sending SMS
|
|
1606
|
-
*/
|
|
1607
|
-
interface SendSMSResult {
|
|
1608
|
-
/**
|
|
1609
|
-
* Whether SMS was sent successfully
|
|
1610
|
-
*/
|
|
1611
|
-
success: boolean;
|
|
1612
|
-
/**
|
|
1613
|
-
* Message ID from SMS provider (if successful)
|
|
1614
|
-
*/
|
|
1615
|
-
messageId?: string;
|
|
1616
|
-
/**
|
|
1617
|
-
* Error message (if failed)
|
|
1618
|
-
*/
|
|
1619
|
-
error?: string;
|
|
1620
|
-
}
|
|
1621
|
-
/**
|
|
1622
|
-
* SMS Provider Interface
|
|
1623
|
-
*
|
|
1624
|
-
* Implement this interface to create custom SMS providers
|
|
1625
|
-
*
|
|
1626
|
-
* @example
|
|
1627
|
-
* ```typescript
|
|
1628
|
-
* import { SMSProvider, registerSMSProvider } from '@spfn/auth/server/services/sms';
|
|
1629
|
-
*
|
|
1630
|
-
* const twilioProvider: SMSProvider = {
|
|
1631
|
-
* name: 'twilio',
|
|
1632
|
-
* sendSMS: async (params) => {
|
|
1633
|
-
* // Your Twilio implementation
|
|
1634
|
-
* return { success: true, messageId: '...' };
|
|
1635
|
-
* }
|
|
1636
|
-
* };
|
|
1637
|
-
*
|
|
1638
|
-
* registerSMSProvider(twilioProvider);
|
|
1639
|
-
* ```
|
|
1640
|
-
*/
|
|
1641
|
-
interface SMSProvider {
|
|
1642
|
-
/**
|
|
1643
|
-
* Provider name (e.g., 'aws-sns', 'twilio', 'custom')
|
|
1644
|
-
*/
|
|
1645
|
-
name: string;
|
|
1646
|
-
/**
|
|
1647
|
-
* Send SMS via this provider
|
|
1648
|
-
*
|
|
1649
|
-
* @param params - SMS parameters
|
|
1650
|
-
* @returns Send result
|
|
1651
|
-
*/
|
|
1652
|
-
sendSMS(params: SendSMSParams): Promise<SendSMSResult>;
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
/**
|
|
1656
|
-
* @spfn/auth - SMS Provider Management
|
|
1657
|
-
*
|
|
1658
|
-
* Manages SMS provider registration and fallback behavior
|
|
1659
|
-
*/
|
|
1660
|
-
|
|
1661
|
-
/**
|
|
1662
|
-
* Register a custom SMS provider
|
|
1663
|
-
*
|
|
1664
|
-
* @param provider - Custom SMS provider implementation
|
|
1665
|
-
*
|
|
1666
|
-
* @example
|
|
1667
|
-
* ```typescript
|
|
1668
|
-
* import { registerSMSProvider } from '@spfn/auth/server/services/sms';
|
|
1669
|
-
*
|
|
1670
|
-
* const twilioProvider = {
|
|
1671
|
-
* name: 'twilio',
|
|
1672
|
-
* sendSMS: async (params) => {
|
|
1673
|
-
* // Twilio implementation
|
|
1674
|
-
* return { success: true, messageId: '...' };
|
|
1675
|
-
* }
|
|
1676
|
-
* };
|
|
1677
|
-
*
|
|
1678
|
-
* registerSMSProvider(twilioProvider);
|
|
1679
|
-
* ```
|
|
1680
|
-
*/
|
|
1681
|
-
declare function registerSMSProvider(provider: SMSProvider): void;
|
|
1682
|
-
/**
|
|
1683
|
-
* Send SMS using the registered provider
|
|
1684
|
-
*
|
|
1685
|
-
* Falls back to development mode (console only) if no provider is registered
|
|
1686
|
-
*
|
|
1687
|
-
* @param params - SMS parameters
|
|
1688
|
-
* @returns Send result
|
|
1689
|
-
*/
|
|
1690
|
-
declare function sendSMS(params: SendSMSParams): Promise<SendSMSResult>;
|
|
1691
|
-
|
|
1692
1389
|
/**
|
|
1693
1390
|
* @spfn/auth - Database Schema Definition
|
|
1694
1391
|
*
|
|
@@ -1771,11 +1468,11 @@ declare const userProfiles: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1771
1468
|
name: `${string}_id`;
|
|
1772
1469
|
tableName: "user_profiles";
|
|
1773
1470
|
dataType: "number";
|
|
1774
|
-
columnType: "
|
|
1471
|
+
columnType: "PgBigInt53";
|
|
1775
1472
|
data: number;
|
|
1776
|
-
driverParam: number;
|
|
1473
|
+
driverParam: string | number;
|
|
1777
1474
|
notNull: true;
|
|
1778
|
-
hasDefault:
|
|
1475
|
+
hasDefault: false;
|
|
1779
1476
|
isPrimaryKey: false;
|
|
1780
1477
|
isAutoincrement: false;
|
|
1781
1478
|
hasRuntimeDefault: false;
|
|
@@ -2065,11 +1762,11 @@ declare const userPublicKeys: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2065
1762
|
name: `${string}_id`;
|
|
2066
1763
|
tableName: "user_public_keys";
|
|
2067
1764
|
dataType: "number";
|
|
2068
|
-
columnType: "
|
|
1765
|
+
columnType: "PgBigInt53";
|
|
2069
1766
|
data: number;
|
|
2070
|
-
driverParam: number;
|
|
1767
|
+
driverParam: string | number;
|
|
2071
1768
|
notNull: true;
|
|
2072
|
-
hasDefault:
|
|
1769
|
+
hasDefault: false;
|
|
2073
1770
|
isPrimaryKey: false;
|
|
2074
1771
|
isAutoincrement: false;
|
|
2075
1772
|
hasRuntimeDefault: false;
|
|
@@ -2318,11 +2015,11 @@ declare const userSocialAccounts: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2318
2015
|
name: `${string}_id`;
|
|
2319
2016
|
tableName: "user_social_accounts";
|
|
2320
2017
|
dataType: "number";
|
|
2321
|
-
columnType: "
|
|
2018
|
+
columnType: "PgBigInt53";
|
|
2322
2019
|
data: number;
|
|
2323
|
-
driverParam: number;
|
|
2020
|
+
driverParam: string | number;
|
|
2324
2021
|
notNull: true;
|
|
2325
|
-
hasDefault:
|
|
2022
|
+
hasDefault: false;
|
|
2326
2023
|
isPrimaryKey: false;
|
|
2327
2024
|
isAutoincrement: false;
|
|
2328
2025
|
hasRuntimeDefault: false;
|
|
@@ -2747,7 +2444,7 @@ declare const permissions: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2747
2444
|
tableName: "permissions";
|
|
2748
2445
|
dataType: "string";
|
|
2749
2446
|
columnType: "PgText";
|
|
2750
|
-
data: "
|
|
2447
|
+
data: "custom" | "user" | "auth" | "rbac" | "system";
|
|
2751
2448
|
driverParam: string;
|
|
2752
2449
|
notNull: false;
|
|
2753
2450
|
hasDefault: false;
|
|
@@ -2905,11 +2602,11 @@ declare const rolePermissions: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2905
2602
|
name: `${string}_id`;
|
|
2906
2603
|
tableName: "role_permissions";
|
|
2907
2604
|
dataType: "number";
|
|
2908
|
-
columnType: "
|
|
2605
|
+
columnType: "PgBigInt53";
|
|
2909
2606
|
data: number;
|
|
2910
|
-
driverParam: number;
|
|
2607
|
+
driverParam: string | number;
|
|
2911
2608
|
notNull: true;
|
|
2912
|
-
hasDefault:
|
|
2609
|
+
hasDefault: false;
|
|
2913
2610
|
isPrimaryKey: false;
|
|
2914
2611
|
isAutoincrement: false;
|
|
2915
2612
|
hasRuntimeDefault: false;
|
|
@@ -2922,11 +2619,11 @@ declare const rolePermissions: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2922
2619
|
name: `${string}_id`;
|
|
2923
2620
|
tableName: "role_permissions";
|
|
2924
2621
|
dataType: "number";
|
|
2925
|
-
columnType: "
|
|
2622
|
+
columnType: "PgBigInt53";
|
|
2926
2623
|
data: number;
|
|
2927
|
-
driverParam: number;
|
|
2624
|
+
driverParam: string | number;
|
|
2928
2625
|
notNull: true;
|
|
2929
|
-
hasDefault:
|
|
2626
|
+
hasDefault: false;
|
|
2930
2627
|
isPrimaryKey: false;
|
|
2931
2628
|
isAutoincrement: false;
|
|
2932
2629
|
hasRuntimeDefault: false;
|
|
@@ -3014,11 +2711,11 @@ declare const userPermissions: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
3014
2711
|
name: `${string}_id`;
|
|
3015
2712
|
tableName: "user_permissions";
|
|
3016
2713
|
dataType: "number";
|
|
3017
|
-
columnType: "
|
|
2714
|
+
columnType: "PgBigInt53";
|
|
3018
2715
|
data: number;
|
|
3019
|
-
driverParam: number;
|
|
2716
|
+
driverParam: string | number;
|
|
3020
2717
|
notNull: true;
|
|
3021
|
-
hasDefault:
|
|
2718
|
+
hasDefault: false;
|
|
3022
2719
|
isPrimaryKey: false;
|
|
3023
2720
|
isAutoincrement: false;
|
|
3024
2721
|
hasRuntimeDefault: false;
|
|
@@ -3031,11 +2728,11 @@ declare const userPermissions: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
3031
2728
|
name: `${string}_id`;
|
|
3032
2729
|
tableName: "user_permissions";
|
|
3033
2730
|
dataType: "number";
|
|
3034
|
-
columnType: "
|
|
2731
|
+
columnType: "PgBigInt53";
|
|
3035
2732
|
data: number;
|
|
3036
|
-
driverParam: number;
|
|
2733
|
+
driverParam: string | number;
|
|
3037
2734
|
notNull: true;
|
|
3038
|
-
hasDefault:
|
|
2735
|
+
hasDefault: false;
|
|
3039
2736
|
isPrimaryKey: false;
|
|
3040
2737
|
isAutoincrement: false;
|
|
3041
2738
|
hasRuntimeDefault: false;
|
|
@@ -3127,6 +2824,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3127
2824
|
id: number;
|
|
3128
2825
|
email: string | null;
|
|
3129
2826
|
phone: string | null;
|
|
2827
|
+
username: string | null;
|
|
3130
2828
|
passwordHash: string | null;
|
|
3131
2829
|
passwordChangeRequired: boolean;
|
|
3132
2830
|
roleId: number;
|
|
@@ -3145,6 +2843,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3145
2843
|
id: number;
|
|
3146
2844
|
email: string | null;
|
|
3147
2845
|
phone: string | null;
|
|
2846
|
+
username: string | null;
|
|
3148
2847
|
passwordHash: string | null;
|
|
3149
2848
|
passwordChangeRequired: boolean;
|
|
3150
2849
|
roleId: number;
|
|
@@ -3163,6 +2862,26 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3163
2862
|
id: number;
|
|
3164
2863
|
email: string | null;
|
|
3165
2864
|
phone: string | null;
|
|
2865
|
+
username: string | null;
|
|
2866
|
+
passwordHash: string | null;
|
|
2867
|
+
passwordChangeRequired: boolean;
|
|
2868
|
+
roleId: number;
|
|
2869
|
+
status: "active" | "inactive" | "suspended";
|
|
2870
|
+
emailVerifiedAt: Date | null;
|
|
2871
|
+
phoneVerifiedAt: Date | null;
|
|
2872
|
+
lastLoginAt: Date | null;
|
|
2873
|
+
}>;
|
|
2874
|
+
/**
|
|
2875
|
+
* 사용자명으로 사용자 조회
|
|
2876
|
+
* Read replica 사용
|
|
2877
|
+
*/
|
|
2878
|
+
findByUsername(username: string): Promise<{
|
|
2879
|
+
createdAt: Date;
|
|
2880
|
+
updatedAt: Date;
|
|
2881
|
+
id: number;
|
|
2882
|
+
email: string | null;
|
|
2883
|
+
phone: string | null;
|
|
2884
|
+
username: string | null;
|
|
3166
2885
|
passwordHash: string | null;
|
|
3167
2886
|
passwordChangeRequired: boolean;
|
|
3168
2887
|
roleId: number;
|
|
@@ -3181,6 +2900,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3181
2900
|
id: number;
|
|
3182
2901
|
email: string | null;
|
|
3183
2902
|
phone: string | null;
|
|
2903
|
+
username: string | null;
|
|
3184
2904
|
passwordHash: string | null;
|
|
3185
2905
|
passwordChangeRequired: boolean;
|
|
3186
2906
|
roleId: number;
|
|
@@ -3189,6 +2909,34 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3189
2909
|
phoneVerifiedAt: Date | null;
|
|
3190
2910
|
lastLoginAt: Date | null;
|
|
3191
2911
|
} | null>;
|
|
2912
|
+
/**
|
|
2913
|
+
* ID로 사용자 + Role 조회 (leftJoin)
|
|
2914
|
+
* Read replica 사용
|
|
2915
|
+
*
|
|
2916
|
+
* roleId가 null인 유저는 role: null 반환
|
|
2917
|
+
*/
|
|
2918
|
+
findByIdWithRole(id: number): Promise<{
|
|
2919
|
+
user: {
|
|
2920
|
+
createdAt: Date;
|
|
2921
|
+
updatedAt: Date;
|
|
2922
|
+
id: number;
|
|
2923
|
+
email: string | null;
|
|
2924
|
+
phone: string | null;
|
|
2925
|
+
username: string | null;
|
|
2926
|
+
passwordHash: string | null;
|
|
2927
|
+
passwordChangeRequired: boolean;
|
|
2928
|
+
roleId: number;
|
|
2929
|
+
status: "active" | "inactive" | "suspended";
|
|
2930
|
+
emailVerifiedAt: Date | null;
|
|
2931
|
+
phoneVerifiedAt: Date | null;
|
|
2932
|
+
lastLoginAt: Date | null;
|
|
2933
|
+
};
|
|
2934
|
+
role: {
|
|
2935
|
+
name: string;
|
|
2936
|
+
displayName: string;
|
|
2937
|
+
priority: number;
|
|
2938
|
+
} | null;
|
|
2939
|
+
} | null>;
|
|
3192
2940
|
/**
|
|
3193
2941
|
* 사용자 생성
|
|
3194
2942
|
* Write primary 사용
|
|
@@ -3196,13 +2944,14 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3196
2944
|
create(data: NewUser): Promise<{
|
|
3197
2945
|
email: string | null;
|
|
3198
2946
|
phone: string | null;
|
|
2947
|
+
status: "active" | "inactive" | "suspended";
|
|
2948
|
+
username: string | null;
|
|
3199
2949
|
id: number;
|
|
2950
|
+
createdAt: Date;
|
|
2951
|
+
updatedAt: Date;
|
|
3200
2952
|
passwordHash: string | null;
|
|
3201
2953
|
passwordChangeRequired: boolean;
|
|
3202
2954
|
roleId: number;
|
|
3203
|
-
createdAt: Date;
|
|
3204
|
-
updatedAt: Date;
|
|
3205
|
-
status: "active" | "inactive" | "suspended";
|
|
3206
2955
|
emailVerifiedAt: Date | null;
|
|
3207
2956
|
phoneVerifiedAt: Date | null;
|
|
3208
2957
|
lastLoginAt: Date | null;
|
|
@@ -3217,6 +2966,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3217
2966
|
id: number;
|
|
3218
2967
|
email: string | null;
|
|
3219
2968
|
phone: string | null;
|
|
2969
|
+
username: string | null;
|
|
3220
2970
|
passwordHash: string | null;
|
|
3221
2971
|
passwordChangeRequired: boolean;
|
|
3222
2972
|
roleId: number;
|
|
@@ -3235,6 +2985,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3235
2985
|
id: number;
|
|
3236
2986
|
email: string | null;
|
|
3237
2987
|
phone: string | null;
|
|
2988
|
+
username: string | null;
|
|
3238
2989
|
passwordHash: string | null;
|
|
3239
2990
|
passwordChangeRequired: boolean;
|
|
3240
2991
|
roleId: number;
|
|
@@ -3253,6 +3004,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3253
3004
|
id: number;
|
|
3254
3005
|
email: string | null;
|
|
3255
3006
|
phone: string | null;
|
|
3007
|
+
username: string | null;
|
|
3256
3008
|
passwordHash: string | null;
|
|
3257
3009
|
passwordChangeRequired: boolean;
|
|
3258
3010
|
roleId: number;
|
|
@@ -3268,13 +3020,14 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3268
3020
|
deleteById(id: number): Promise<{
|
|
3269
3021
|
email: string | null;
|
|
3270
3022
|
phone: string | null;
|
|
3023
|
+
status: "active" | "inactive" | "suspended";
|
|
3024
|
+
username: string | null;
|
|
3271
3025
|
id: number;
|
|
3026
|
+
createdAt: Date;
|
|
3027
|
+
updatedAt: Date;
|
|
3272
3028
|
passwordHash: string | null;
|
|
3273
3029
|
passwordChangeRequired: boolean;
|
|
3274
3030
|
roleId: number;
|
|
3275
|
-
createdAt: Date;
|
|
3276
|
-
updatedAt: Date;
|
|
3277
|
-
status: "active" | "inactive" | "suspended";
|
|
3278
3031
|
emailVerifiedAt: Date | null;
|
|
3279
3032
|
phoneVerifiedAt: Date | null;
|
|
3280
3033
|
lastLoginAt: Date | null;
|
|
@@ -3297,7 +3050,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3297
3050
|
id: number;
|
|
3298
3051
|
name: string;
|
|
3299
3052
|
displayName: string;
|
|
3300
|
-
category: "
|
|
3053
|
+
category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
|
|
3301
3054
|
}[];
|
|
3302
3055
|
}>;
|
|
3303
3056
|
/**
|
|
@@ -3310,6 +3063,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3310
3063
|
fetchMinimalUserData(userId: number): Promise<{
|
|
3311
3064
|
userId: number;
|
|
3312
3065
|
email: string | null;
|
|
3066
|
+
username: string | null;
|
|
3313
3067
|
isEmailVerified: boolean;
|
|
3314
3068
|
isPhoneVerified: boolean;
|
|
3315
3069
|
}>;
|
|
@@ -3323,6 +3077,7 @@ declare class UsersRepository extends BaseRepository {
|
|
|
3323
3077
|
fetchFullUserData(userId: number): Promise<{
|
|
3324
3078
|
userId: number;
|
|
3325
3079
|
email: string | null;
|
|
3080
|
+
username: string | null;
|
|
3326
3081
|
isEmailVerified: boolean;
|
|
3327
3082
|
isPhoneVerified: boolean;
|
|
3328
3083
|
lastLoginAt: Date | null;
|
|
@@ -3407,16 +3162,16 @@ declare class KeysRepository extends BaseRepository {
|
|
|
3407
3162
|
* Write primary 사용
|
|
3408
3163
|
*/
|
|
3409
3164
|
create(data: NewUserPublicKey): Promise<{
|
|
3410
|
-
publicKey: string;
|
|
3411
|
-
keyId: string;
|
|
3412
|
-
fingerprint: string;
|
|
3413
|
-
algorithm: "ES256" | "RS256";
|
|
3414
3165
|
userId: number;
|
|
3166
|
+
keyId: string;
|
|
3415
3167
|
id: number;
|
|
3416
3168
|
isActive: boolean;
|
|
3417
3169
|
createdAt: Date;
|
|
3418
|
-
|
|
3170
|
+
publicKey: string;
|
|
3171
|
+
algorithm: "ES256" | "RS256";
|
|
3172
|
+
fingerprint: string;
|
|
3419
3173
|
lastUsedAt: Date | null;
|
|
3174
|
+
expiresAt: Date | null;
|
|
3420
3175
|
revokedAt: Date | null;
|
|
3421
3176
|
revokedReason: string | null;
|
|
3422
3177
|
}>;
|
|
@@ -3443,16 +3198,16 @@ declare class KeysRepository extends BaseRepository {
|
|
|
3443
3198
|
* Write primary 사용
|
|
3444
3199
|
*/
|
|
3445
3200
|
deleteByKeyIdAndUserId(keyId: string, userId: number): Promise<{
|
|
3446
|
-
publicKey: string;
|
|
3447
|
-
keyId: string;
|
|
3448
|
-
fingerprint: string;
|
|
3449
|
-
algorithm: "ES256" | "RS256";
|
|
3450
3201
|
userId: number;
|
|
3202
|
+
keyId: string;
|
|
3451
3203
|
id: number;
|
|
3452
3204
|
isActive: boolean;
|
|
3453
3205
|
createdAt: Date;
|
|
3454
|
-
|
|
3206
|
+
publicKey: string;
|
|
3207
|
+
algorithm: "ES256" | "RS256";
|
|
3208
|
+
fingerprint: string;
|
|
3455
3209
|
lastUsedAt: Date | null;
|
|
3210
|
+
expiresAt: Date | null;
|
|
3456
3211
|
revokedAt: Date | null;
|
|
3457
3212
|
revokedReason: string | null;
|
|
3458
3213
|
}>;
|
|
@@ -3567,14 +3322,14 @@ declare class VerificationCodesRepository extends BaseRepository {
|
|
|
3567
3322
|
* Write primary 사용
|
|
3568
3323
|
*/
|
|
3569
3324
|
create(data: NewVerificationCode): Promise<{
|
|
3570
|
-
target: string;
|
|
3571
|
-
targetType: "email" | "phone";
|
|
3572
|
-
purpose: "registration" | "login" | "password_reset" | "email_change" | "phone_change";
|
|
3573
|
-
code: string;
|
|
3574
3325
|
id: number;
|
|
3575
3326
|
createdAt: Date;
|
|
3576
3327
|
updatedAt: Date;
|
|
3577
3328
|
expiresAt: Date;
|
|
3329
|
+
target: string;
|
|
3330
|
+
targetType: "email" | "phone";
|
|
3331
|
+
code: string;
|
|
3332
|
+
purpose: "registration" | "login" | "password_reset" | "email_change" | "phone_change";
|
|
3578
3333
|
usedAt: Date | null;
|
|
3579
3334
|
attempts: number;
|
|
3580
3335
|
}>;
|
|
@@ -3763,7 +3518,7 @@ declare class PermissionsRepository extends BaseRepository {
|
|
|
3763
3518
|
name: string;
|
|
3764
3519
|
displayName: string;
|
|
3765
3520
|
description: string | null;
|
|
3766
|
-
category: "
|
|
3521
|
+
category: "custom" | "user" | "auth" | "rbac" | "system" | null;
|
|
3767
3522
|
isBuiltin: boolean;
|
|
3768
3523
|
isSystem: boolean;
|
|
3769
3524
|
isActive: boolean;
|
|
@@ -3779,7 +3534,7 @@ declare class PermissionsRepository extends BaseRepository {
|
|
|
3779
3534
|
name: string;
|
|
3780
3535
|
displayName: string;
|
|
3781
3536
|
description: string | null;
|
|
3782
|
-
category: "
|
|
3537
|
+
category: "custom" | "user" | "auth" | "rbac" | "system" | null;
|
|
3783
3538
|
isBuiltin: boolean;
|
|
3784
3539
|
isSystem: boolean;
|
|
3785
3540
|
isActive: boolean;
|
|
@@ -3819,7 +3574,7 @@ declare class PermissionsRepository extends BaseRepository {
|
|
|
3819
3574
|
name: string;
|
|
3820
3575
|
displayName: string;
|
|
3821
3576
|
description: string | null;
|
|
3822
|
-
category: "
|
|
3577
|
+
category: "custom" | "user" | "auth" | "rbac" | "system" | null;
|
|
3823
3578
|
isBuiltin: boolean;
|
|
3824
3579
|
isSystem: boolean;
|
|
3825
3580
|
isActive: boolean;
|
|
@@ -3838,8 +3593,8 @@ declare class PermissionsRepository extends BaseRepository {
|
|
|
3838
3593
|
isActive: boolean;
|
|
3839
3594
|
createdAt: Date;
|
|
3840
3595
|
updatedAt: Date;
|
|
3841
|
-
category: "auth" | "custom" | "user" | "rbac" | "system" | null;
|
|
3842
3596
|
metadata: Record<string, any> | null;
|
|
3597
|
+
category: "custom" | "user" | "auth" | "rbac" | "system" | null;
|
|
3843
3598
|
}>;
|
|
3844
3599
|
}
|
|
3845
3600
|
declare const permissionsRepository: PermissionsRepository;
|
|
@@ -3884,9 +3639,9 @@ declare class RolePermissionsRepository extends BaseRepository {
|
|
|
3884
3639
|
*/
|
|
3885
3640
|
createMany(data: NewRolePermission[]): Promise<{
|
|
3886
3641
|
id: number;
|
|
3887
|
-
roleId: number;
|
|
3888
3642
|
createdAt: Date;
|
|
3889
3643
|
updatedAt: Date;
|
|
3644
|
+
roleId: number;
|
|
3890
3645
|
permissionId: number;
|
|
3891
3646
|
}[]>;
|
|
3892
3647
|
/**
|
|
@@ -3902,9 +3657,9 @@ declare class RolePermissionsRepository extends BaseRepository {
|
|
|
3902
3657
|
*/
|
|
3903
3658
|
setPermissionsForRole(roleId: number, permissionIds: number[]): Promise<{
|
|
3904
3659
|
id: number;
|
|
3905
|
-
roleId: number;
|
|
3906
3660
|
createdAt: Date;
|
|
3907
3661
|
updatedAt: Date;
|
|
3662
|
+
roleId: number;
|
|
3908
3663
|
permissionId: number;
|
|
3909
3664
|
}[]>;
|
|
3910
3665
|
}
|
|
@@ -3969,10 +3724,10 @@ declare class UserPermissionsRepository extends BaseRepository {
|
|
|
3969
3724
|
id: number;
|
|
3970
3725
|
createdAt: Date;
|
|
3971
3726
|
updatedAt: Date;
|
|
3972
|
-
permissionId: number;
|
|
3973
3727
|
expiresAt: Date | null;
|
|
3974
|
-
|
|
3728
|
+
permissionId: number;
|
|
3975
3729
|
granted: boolean;
|
|
3730
|
+
reason: string | null;
|
|
3976
3731
|
}>;
|
|
3977
3732
|
/**
|
|
3978
3733
|
* 사용자 권한 오버라이드 업데이트
|
|
@@ -3995,10 +3750,10 @@ declare class UserPermissionsRepository extends BaseRepository {
|
|
|
3995
3750
|
id: number;
|
|
3996
3751
|
createdAt: Date;
|
|
3997
3752
|
updatedAt: Date;
|
|
3998
|
-
permissionId: number;
|
|
3999
3753
|
expiresAt: Date | null;
|
|
4000
|
-
|
|
3754
|
+
permissionId: number;
|
|
4001
3755
|
granted: boolean;
|
|
3756
|
+
reason: string | null;
|
|
4002
3757
|
}>;
|
|
4003
3758
|
/**
|
|
4004
3759
|
* 사용자의 모든 권한 오버라이드 삭제
|
|
@@ -4045,6 +3800,10 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4045
3800
|
jobTitle: string | null;
|
|
4046
3801
|
metadata: Record<string, any> | null;
|
|
4047
3802
|
}>;
|
|
3803
|
+
/**
|
|
3804
|
+
* User ID로 locale만 조회 (경량)
|
|
3805
|
+
*/
|
|
3806
|
+
findLocaleByUserId(userId: number): Promise<string>;
|
|
4048
3807
|
/**
|
|
4049
3808
|
* User ID로 프로필 조회
|
|
4050
3809
|
*/
|
|
@@ -4077,7 +3836,6 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4077
3836
|
displayName: string;
|
|
4078
3837
|
createdAt: Date;
|
|
4079
3838
|
updatedAt: Date;
|
|
4080
|
-
metadata: Record<string, any> | null;
|
|
4081
3839
|
firstName: string | null;
|
|
4082
3840
|
lastName: string | null;
|
|
4083
3841
|
avatarUrl: string | null;
|
|
@@ -4090,6 +3848,7 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4090
3848
|
location: string | null;
|
|
4091
3849
|
company: string | null;
|
|
4092
3850
|
jobTitle: string | null;
|
|
3851
|
+
metadata: Record<string, any> | null;
|
|
4093
3852
|
}>;
|
|
4094
3853
|
/**
|
|
4095
3854
|
* 프로필 업데이트 (by ID)
|
|
@@ -4146,7 +3905,6 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4146
3905
|
displayName: string;
|
|
4147
3906
|
createdAt: Date;
|
|
4148
3907
|
updatedAt: Date;
|
|
4149
|
-
metadata: Record<string, any> | null;
|
|
4150
3908
|
firstName: string | null;
|
|
4151
3909
|
lastName: string | null;
|
|
4152
3910
|
avatarUrl: string | null;
|
|
@@ -4159,6 +3917,7 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4159
3917
|
location: string | null;
|
|
4160
3918
|
company: string | null;
|
|
4161
3919
|
jobTitle: string | null;
|
|
3920
|
+
metadata: Record<string, any> | null;
|
|
4162
3921
|
}>;
|
|
4163
3922
|
/**
|
|
4164
3923
|
* 프로필 삭제 (by User ID)
|
|
@@ -4169,7 +3928,6 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4169
3928
|
displayName: string;
|
|
4170
3929
|
createdAt: Date;
|
|
4171
3930
|
updatedAt: Date;
|
|
4172
|
-
metadata: Record<string, any> | null;
|
|
4173
3931
|
firstName: string | null;
|
|
4174
3932
|
lastName: string | null;
|
|
4175
3933
|
avatarUrl: string | null;
|
|
@@ -4182,6 +3940,7 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4182
3940
|
location: string | null;
|
|
4183
3941
|
company: string | null;
|
|
4184
3942
|
jobTitle: string | null;
|
|
3943
|
+
metadata: Record<string, any> | null;
|
|
4185
3944
|
}>;
|
|
4186
3945
|
/**
|
|
4187
3946
|
* 프로필 Upsert (by User ID)
|
|
@@ -4195,7 +3954,6 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4195
3954
|
displayName: string;
|
|
4196
3955
|
createdAt: Date;
|
|
4197
3956
|
updatedAt: Date;
|
|
4198
|
-
metadata: Record<string, any> | null;
|
|
4199
3957
|
firstName: string | null;
|
|
4200
3958
|
lastName: string | null;
|
|
4201
3959
|
avatarUrl: string | null;
|
|
@@ -4208,6 +3966,7 @@ declare class UserProfilesRepository extends BaseRepository {
|
|
|
4208
3966
|
location: string | null;
|
|
4209
3967
|
company: string | null;
|
|
4210
3968
|
jobTitle: string | null;
|
|
3969
|
+
metadata: Record<string, any> | null;
|
|
4211
3970
|
}>;
|
|
4212
3971
|
/**
|
|
4213
3972
|
* User ID로 프로필 데이터 조회 (formatted)
|
|
@@ -4335,15 +4094,15 @@ declare class InvitationsRepository extends BaseRepository {
|
|
|
4335
4094
|
*/
|
|
4336
4095
|
create(data: NewInvitation): Promise<{
|
|
4337
4096
|
email: string;
|
|
4097
|
+
status: "pending" | "accepted" | "expired" | "cancelled";
|
|
4338
4098
|
id: number;
|
|
4339
|
-
roleId: number;
|
|
4340
4099
|
createdAt: Date;
|
|
4341
4100
|
updatedAt: Date;
|
|
4342
|
-
|
|
4101
|
+
roleId: number;
|
|
4343
4102
|
metadata: Record<string, any> | null;
|
|
4103
|
+
expiresAt: Date;
|
|
4344
4104
|
token: string;
|
|
4345
4105
|
invitedBy: number;
|
|
4346
|
-
expiresAt: Date;
|
|
4347
4106
|
acceptedAt: Date | null;
|
|
4348
4107
|
cancelledAt: Date | null;
|
|
4349
4108
|
}>;
|
|
@@ -4369,15 +4128,15 @@ declare class InvitationsRepository extends BaseRepository {
|
|
|
4369
4128
|
*/
|
|
4370
4129
|
deleteById(id: number): Promise<{
|
|
4371
4130
|
email: string;
|
|
4131
|
+
status: "pending" | "accepted" | "expired" | "cancelled";
|
|
4372
4132
|
id: number;
|
|
4373
|
-
roleId: number;
|
|
4374
4133
|
createdAt: Date;
|
|
4375
4134
|
updatedAt: Date;
|
|
4376
|
-
|
|
4135
|
+
roleId: number;
|
|
4377
4136
|
metadata: Record<string, any> | null;
|
|
4137
|
+
expiresAt: Date;
|
|
4378
4138
|
token: string;
|
|
4379
4139
|
invitedBy: number;
|
|
4380
|
-
expiresAt: Date;
|
|
4381
4140
|
acceptedAt: Date | null;
|
|
4382
4141
|
cancelledAt: Date | null;
|
|
4383
4142
|
}>;
|
|
@@ -4502,6 +4261,136 @@ declare class InvitationsRepository extends BaseRepository {
|
|
|
4502
4261
|
}
|
|
4503
4262
|
declare const invitationsRepository: InvitationsRepository;
|
|
4504
4263
|
|
|
4264
|
+
/**
|
|
4265
|
+
* Social Accounts Repository
|
|
4266
|
+
*
|
|
4267
|
+
* OAuth 소셜 계정 데이터 관리를 위한 Repository
|
|
4268
|
+
* BaseRepository를 상속받아 자동 트랜잭션 컨텍스트 지원 및 Read/Write 분리
|
|
4269
|
+
*/
|
|
4270
|
+
|
|
4271
|
+
/**
|
|
4272
|
+
* Social Accounts Repository 클래스
|
|
4273
|
+
*/
|
|
4274
|
+
declare class SocialAccountsRepository extends BaseRepository {
|
|
4275
|
+
/**
|
|
4276
|
+
* provider와 providerUserId로 소셜 계정 조회
|
|
4277
|
+
* Read replica 사용
|
|
4278
|
+
*/
|
|
4279
|
+
findByProviderAndProviderId(provider: SocialProvider, providerUserId: string): Promise<{
|
|
4280
|
+
createdAt: Date;
|
|
4281
|
+
updatedAt: Date;
|
|
4282
|
+
id: number;
|
|
4283
|
+
userId: number;
|
|
4284
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4285
|
+
providerUserId: string;
|
|
4286
|
+
providerEmail: string | null;
|
|
4287
|
+
accessToken: string | null;
|
|
4288
|
+
refreshToken: string | null;
|
|
4289
|
+
tokenExpiresAt: Date | null;
|
|
4290
|
+
}>;
|
|
4291
|
+
/**
|
|
4292
|
+
* userId로 모든 소셜 계정 조회
|
|
4293
|
+
* Read replica 사용
|
|
4294
|
+
*/
|
|
4295
|
+
findByUserId(userId: number): Promise<{
|
|
4296
|
+
createdAt: Date;
|
|
4297
|
+
updatedAt: Date;
|
|
4298
|
+
id: number;
|
|
4299
|
+
userId: number;
|
|
4300
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4301
|
+
providerUserId: string;
|
|
4302
|
+
providerEmail: string | null;
|
|
4303
|
+
accessToken: string | null;
|
|
4304
|
+
refreshToken: string | null;
|
|
4305
|
+
tokenExpiresAt: Date | null;
|
|
4306
|
+
}[]>;
|
|
4307
|
+
/**
|
|
4308
|
+
* userId와 provider로 소셜 계정 조회
|
|
4309
|
+
* Read replica 사용
|
|
4310
|
+
*/
|
|
4311
|
+
findByUserIdAndProvider(userId: number, provider: SocialProvider): Promise<{
|
|
4312
|
+
createdAt: Date;
|
|
4313
|
+
updatedAt: Date;
|
|
4314
|
+
id: number;
|
|
4315
|
+
userId: number;
|
|
4316
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4317
|
+
providerUserId: string;
|
|
4318
|
+
providerEmail: string | null;
|
|
4319
|
+
accessToken: string | null;
|
|
4320
|
+
refreshToken: string | null;
|
|
4321
|
+
tokenExpiresAt: Date | null;
|
|
4322
|
+
}>;
|
|
4323
|
+
/**
|
|
4324
|
+
* 소셜 계정 생성
|
|
4325
|
+
* Write primary 사용
|
|
4326
|
+
*/
|
|
4327
|
+
create(data: NewUserSocialAccount): Promise<{
|
|
4328
|
+
userId: number;
|
|
4329
|
+
id: number;
|
|
4330
|
+
createdAt: Date;
|
|
4331
|
+
updatedAt: Date;
|
|
4332
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4333
|
+
providerUserId: string;
|
|
4334
|
+
providerEmail: string | null;
|
|
4335
|
+
accessToken: string | null;
|
|
4336
|
+
refreshToken: string | null;
|
|
4337
|
+
tokenExpiresAt: Date | null;
|
|
4338
|
+
}>;
|
|
4339
|
+
/**
|
|
4340
|
+
* 토큰 정보 업데이트
|
|
4341
|
+
* Write primary 사용
|
|
4342
|
+
*/
|
|
4343
|
+
updateTokens(id: number, data: {
|
|
4344
|
+
accessToken?: string | null;
|
|
4345
|
+
refreshToken?: string | null;
|
|
4346
|
+
tokenExpiresAt?: Date | null;
|
|
4347
|
+
}): Promise<{
|
|
4348
|
+
createdAt: Date;
|
|
4349
|
+
updatedAt: Date;
|
|
4350
|
+
id: number;
|
|
4351
|
+
userId: number;
|
|
4352
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4353
|
+
providerUserId: string;
|
|
4354
|
+
providerEmail: string | null;
|
|
4355
|
+
accessToken: string | null;
|
|
4356
|
+
refreshToken: string | null;
|
|
4357
|
+
tokenExpiresAt: Date | null;
|
|
4358
|
+
}>;
|
|
4359
|
+
/**
|
|
4360
|
+
* 소셜 계정 삭제
|
|
4361
|
+
* Write primary 사용
|
|
4362
|
+
*/
|
|
4363
|
+
deleteById(id: number): Promise<{
|
|
4364
|
+
userId: number;
|
|
4365
|
+
id: number;
|
|
4366
|
+
createdAt: Date;
|
|
4367
|
+
updatedAt: Date;
|
|
4368
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4369
|
+
providerUserId: string;
|
|
4370
|
+
providerEmail: string | null;
|
|
4371
|
+
accessToken: string | null;
|
|
4372
|
+
refreshToken: string | null;
|
|
4373
|
+
tokenExpiresAt: Date | null;
|
|
4374
|
+
}>;
|
|
4375
|
+
/**
|
|
4376
|
+
* userId와 provider로 소셜 계정 삭제
|
|
4377
|
+
* Write primary 사용
|
|
4378
|
+
*/
|
|
4379
|
+
deleteByUserIdAndProvider(userId: number, provider: SocialProvider): Promise<{
|
|
4380
|
+
userId: number;
|
|
4381
|
+
id: number;
|
|
4382
|
+
createdAt: Date;
|
|
4383
|
+
updatedAt: Date;
|
|
4384
|
+
provider: "google" | "github" | "kakao" | "naver";
|
|
4385
|
+
providerUserId: string;
|
|
4386
|
+
providerEmail: string | null;
|
|
4387
|
+
accessToken: string | null;
|
|
4388
|
+
refreshToken: string | null;
|
|
4389
|
+
tokenExpiresAt: Date | null;
|
|
4390
|
+
}>;
|
|
4391
|
+
}
|
|
4392
|
+
declare const socialAccountsRepository: SocialAccountsRepository;
|
|
4393
|
+
|
|
4505
4394
|
/**
|
|
4506
4395
|
* @spfn/auth - Password Helpers
|
|
4507
4396
|
*
|
|
@@ -4872,6 +4761,32 @@ declare const roleGuard: _spfn_core_route.NamedMiddlewareFactory<"roleGuard", [o
|
|
|
4872
4761
|
declare function getAuth(c: Context | {
|
|
4873
4762
|
raw: Context;
|
|
4874
4763
|
}): AuthContext;
|
|
4764
|
+
/**
|
|
4765
|
+
* Get optional auth context from route context
|
|
4766
|
+
*
|
|
4767
|
+
* Returns AuthContext if authenticated, undefined otherwise.
|
|
4768
|
+
* Use with `optionalAuth` middleware for routes that serve both
|
|
4769
|
+
* authenticated and unauthenticated users.
|
|
4770
|
+
*
|
|
4771
|
+
* @example
|
|
4772
|
+
* ```typescript
|
|
4773
|
+
* export const getProducts = route.get('/products')
|
|
4774
|
+
* .use([optionalAuth])
|
|
4775
|
+
* .handler(async (c) => {
|
|
4776
|
+
* const auth = getOptionalAuth(c);
|
|
4777
|
+
*
|
|
4778
|
+
* if (auth)
|
|
4779
|
+
* {
|
|
4780
|
+
* return getPersonalizedProducts(auth.userId);
|
|
4781
|
+
* }
|
|
4782
|
+
*
|
|
4783
|
+
* return getPublicProducts();
|
|
4784
|
+
* });
|
|
4785
|
+
* ```
|
|
4786
|
+
*/
|
|
4787
|
+
declare function getOptionalAuth(c: Context | {
|
|
4788
|
+
raw: Context;
|
|
4789
|
+
}): AuthContext | undefined;
|
|
4875
4790
|
/**
|
|
4876
4791
|
* Get authenticated user from route context
|
|
4877
4792
|
*
|
|
@@ -4888,13 +4803,14 @@ declare function getUser(c: Context | {
|
|
|
4888
4803
|
}): {
|
|
4889
4804
|
email: string | null;
|
|
4890
4805
|
phone: string | null;
|
|
4806
|
+
status: "active" | "inactive" | "suspended";
|
|
4807
|
+
username: string | null;
|
|
4891
4808
|
id: number;
|
|
4809
|
+
createdAt: Date;
|
|
4810
|
+
updatedAt: Date;
|
|
4892
4811
|
passwordHash: string | null;
|
|
4893
4812
|
passwordChangeRequired: boolean;
|
|
4894
4813
|
roleId: number;
|
|
4895
|
-
createdAt: Date;
|
|
4896
|
-
updatedAt: Date;
|
|
4897
|
-
status: "active" | "inactive" | "suspended";
|
|
4898
4814
|
emailVerifiedAt: Date | null;
|
|
4899
4815
|
phoneVerifiedAt: Date | null;
|
|
4900
4816
|
lastLoginAt: Date | null;
|
|
@@ -4913,6 +4829,38 @@ declare function getUser(c: Context | {
|
|
|
4913
4829
|
declare function getUserId(c: Context | {
|
|
4914
4830
|
raw: Context;
|
|
4915
4831
|
}): string;
|
|
4832
|
+
/**
|
|
4833
|
+
* Get authenticated user's role from route context
|
|
4834
|
+
*
|
|
4835
|
+
* @returns Role name or null if user has no role
|
|
4836
|
+
*
|
|
4837
|
+
* @example
|
|
4838
|
+
* ```typescript
|
|
4839
|
+
* app.bind(adminContract, [authenticate], async (c) => {
|
|
4840
|
+
* const role = getRole(c);
|
|
4841
|
+
* // 'admin' | 'superadmin' | null
|
|
4842
|
+
* });
|
|
4843
|
+
* ```
|
|
4844
|
+
*/
|
|
4845
|
+
declare function getRole(c: Context | {
|
|
4846
|
+
raw: Context;
|
|
4847
|
+
}): string | null;
|
|
4848
|
+
/**
|
|
4849
|
+
* Get authenticated user's locale from route context
|
|
4850
|
+
*
|
|
4851
|
+
* @returns Locale string (e.g., 'en', 'ko')
|
|
4852
|
+
*
|
|
4853
|
+
* @example
|
|
4854
|
+
* ```typescript
|
|
4855
|
+
* app.bind(contract, [authenticate], async (c) => {
|
|
4856
|
+
* const locale = getLocale(c);
|
|
4857
|
+
* // 'en' | 'ko' | ...
|
|
4858
|
+
* });
|
|
4859
|
+
* ```
|
|
4860
|
+
*/
|
|
4861
|
+
declare function getLocale(c: Context | {
|
|
4862
|
+
raw: Context;
|
|
4863
|
+
}): string;
|
|
4916
4864
|
/**
|
|
4917
4865
|
* Get current key ID from route context
|
|
4918
4866
|
*
|
|
@@ -5048,6 +4996,8 @@ declare const COOKIE_NAMES: {
|
|
|
5048
4996
|
readonly SESSION: "spfn_session";
|
|
5049
4997
|
/** Current key ID (for key rotation) */
|
|
5050
4998
|
readonly SESSION_KEY_ID: "spfn_session_key_id";
|
|
4999
|
+
/** Pending OAuth session (privateKey, keyId, algorithm) - temporary during OAuth flow */
|
|
5000
|
+
readonly OAUTH_PENDING: "spfn_oauth_pending";
|
|
5051
5001
|
};
|
|
5052
5002
|
/**
|
|
5053
5003
|
* Parse duration string to seconds
|
|
@@ -5104,6 +5054,116 @@ declare function getAuthConfig(): AuthConfig;
|
|
|
5104
5054
|
*/
|
|
5105
5055
|
declare function getSessionTtl(override?: string | number): number;
|
|
5106
5056
|
|
|
5057
|
+
/**
|
|
5058
|
+
* Google OAuth 2.0 Client
|
|
5059
|
+
*
|
|
5060
|
+
* Authorization Code Flow 구현
|
|
5061
|
+
* - getGoogleAuthUrl: Google 로그인 URL 생성
|
|
5062
|
+
* - exchangeCodeForTokens: Code를 Token으로 교환
|
|
5063
|
+
* - getGoogleUserInfo: 사용자 정보 조회
|
|
5064
|
+
*/
|
|
5065
|
+
interface GoogleTokenResponse {
|
|
5066
|
+
access_token: string;
|
|
5067
|
+
expires_in: number;
|
|
5068
|
+
refresh_token?: string;
|
|
5069
|
+
scope: string;
|
|
5070
|
+
token_type: string;
|
|
5071
|
+
id_token?: string;
|
|
5072
|
+
}
|
|
5073
|
+
interface GoogleUserInfo {
|
|
5074
|
+
id: string;
|
|
5075
|
+
email: string;
|
|
5076
|
+
verified_email: boolean;
|
|
5077
|
+
name?: string;
|
|
5078
|
+
given_name?: string;
|
|
5079
|
+
family_name?: string;
|
|
5080
|
+
picture?: string;
|
|
5081
|
+
locale?: string;
|
|
5082
|
+
}
|
|
5083
|
+
/**
|
|
5084
|
+
* Google OAuth가 활성화되어 있는지 확인
|
|
5085
|
+
*/
|
|
5086
|
+
declare function isGoogleOAuthEnabled(): boolean;
|
|
5087
|
+
/**
|
|
5088
|
+
* Google OAuth 설정 가져오기
|
|
5089
|
+
*/
|
|
5090
|
+
declare function getGoogleOAuthConfig(): {
|
|
5091
|
+
clientId: string;
|
|
5092
|
+
clientSecret: string;
|
|
5093
|
+
redirectUri: string;
|
|
5094
|
+
};
|
|
5095
|
+
/**
|
|
5096
|
+
* Google 로그인 URL 생성
|
|
5097
|
+
*
|
|
5098
|
+
* @param state - CSRF 방지용 state 파라미터 (암호화된 returnUrl + nonce 포함)
|
|
5099
|
+
* @param scopes - 요청할 OAuth scopes (기본: env 또는 email, profile)
|
|
5100
|
+
*/
|
|
5101
|
+
declare function getGoogleAuthUrl(state: string, scopes?: string[]): string;
|
|
5102
|
+
/**
|
|
5103
|
+
* Authorization Code를 Token으로 교환
|
|
5104
|
+
*
|
|
5105
|
+
* @param code - Google에서 받은 authorization code
|
|
5106
|
+
*/
|
|
5107
|
+
declare function exchangeCodeForTokens(code: string): Promise<GoogleTokenResponse>;
|
|
5108
|
+
/**
|
|
5109
|
+
* Access Token으로 Google 사용자 정보 조회
|
|
5110
|
+
*
|
|
5111
|
+
* @param accessToken - Google access token
|
|
5112
|
+
*/
|
|
5113
|
+
declare function getGoogleUserInfo(accessToken: string): Promise<GoogleUserInfo>;
|
|
5114
|
+
/**
|
|
5115
|
+
* Refresh Token으로 새 Access Token 획득
|
|
5116
|
+
*
|
|
5117
|
+
* @param refreshToken - Google refresh token
|
|
5118
|
+
*/
|
|
5119
|
+
declare function refreshAccessToken(refreshToken: string): Promise<GoogleTokenResponse>;
|
|
5120
|
+
|
|
5121
|
+
/**
|
|
5122
|
+
* OAuth State Management
|
|
5123
|
+
*
|
|
5124
|
+
* CSRF 방지를 위한 state 파라미터 암호화/복호화
|
|
5125
|
+
* - returnUrl: OAuth 성공 후 리다이렉트할 URL
|
|
5126
|
+
* - nonce: CSRF 방지용 일회용 토큰
|
|
5127
|
+
* - provider: OAuth provider (google, github 등)
|
|
5128
|
+
* - publicKey, keyId, fingerprint, algorithm: 클라이언트 키 정보
|
|
5129
|
+
* - expiresAt: state 만료 시간
|
|
5130
|
+
*/
|
|
5131
|
+
|
|
5132
|
+
interface OAuthState {
|
|
5133
|
+
returnUrl: string;
|
|
5134
|
+
nonce: string;
|
|
5135
|
+
provider: string;
|
|
5136
|
+
publicKey: string;
|
|
5137
|
+
keyId: string;
|
|
5138
|
+
fingerprint: string;
|
|
5139
|
+
algorithm: KeyAlgorithmType;
|
|
5140
|
+
metadata?: Record<string, unknown>;
|
|
5141
|
+
}
|
|
5142
|
+
interface CreateOAuthStateParams {
|
|
5143
|
+
provider: string;
|
|
5144
|
+
returnUrl: string;
|
|
5145
|
+
publicKey: string;
|
|
5146
|
+
keyId: string;
|
|
5147
|
+
fingerprint: string;
|
|
5148
|
+
algorithm: KeyAlgorithmType;
|
|
5149
|
+
metadata?: Record<string, unknown>;
|
|
5150
|
+
}
|
|
5151
|
+
/**
|
|
5152
|
+
* OAuth state 생성 및 암호화
|
|
5153
|
+
*
|
|
5154
|
+
* @param params - state 생성에 필요한 파라미터
|
|
5155
|
+
* @returns 암호화된 state 문자열
|
|
5156
|
+
*/
|
|
5157
|
+
declare function createOAuthState(params: CreateOAuthStateParams): Promise<string>;
|
|
5158
|
+
/**
|
|
5159
|
+
* OAuth state 복호화 및 검증
|
|
5160
|
+
*
|
|
5161
|
+
* @param encryptedState - 암호화된 state 문자열
|
|
5162
|
+
* @returns 복호화된 state 객체
|
|
5163
|
+
* @throws Error if state is invalid or expired (JWE exp claim으로 자동 검증)
|
|
5164
|
+
*/
|
|
5165
|
+
declare function verifyOAuthState(encryptedState: string): Promise<OAuthState>;
|
|
5166
|
+
|
|
5107
5167
|
/**
|
|
5108
5168
|
* @spfn/auth - Centralized Logger
|
|
5109
5169
|
*
|
|
@@ -5116,6 +5176,7 @@ declare const authLogger: {
|
|
|
5116
5176
|
general: _spfn_core_logger.Logger;
|
|
5117
5177
|
login: _spfn_core_logger.Logger;
|
|
5118
5178
|
keyRotation: _spfn_core_logger.Logger;
|
|
5179
|
+
oauth: _spfn_core_logger.Logger;
|
|
5119
5180
|
};
|
|
5120
5181
|
service: _spfn_core_logger.Logger;
|
|
5121
5182
|
setup: _spfn_core_logger.Logger;
|
|
@@ -5199,4 +5260,64 @@ interface AuthLifecycleConfig {
|
|
|
5199
5260
|
*/
|
|
5200
5261
|
declare function createAuthLifecycle(options?: AuthInitOptions): AuthLifecycleConfig;
|
|
5201
5262
|
|
|
5202
|
-
|
|
5263
|
+
/**
|
|
5264
|
+
* @spfn/auth - Auth Events
|
|
5265
|
+
*
|
|
5266
|
+
* 인증 관련 이벤트 정의
|
|
5267
|
+
* - auth.login: 로그인 성공 시 (기존 사용자만)
|
|
5268
|
+
* - auth.register: 회원가입 성공 시 (OAuth 신규 가입 포함)
|
|
5269
|
+
*/
|
|
5270
|
+
/**
|
|
5271
|
+
* Auth provider type
|
|
5272
|
+
*/
|
|
5273
|
+
declare const AuthProviderSchema: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"email">, _sinclair_typebox.TLiteral<"phone">, _sinclair_typebox.TLiteral<"google">]>;
|
|
5274
|
+
/**
|
|
5275
|
+
* auth.login - 로그인 성공 이벤트
|
|
5276
|
+
*
|
|
5277
|
+
* 발행 시점:
|
|
5278
|
+
* - 이메일/전화 로그인 성공 시
|
|
5279
|
+
* - OAuth 기존 사용자 로그인 시
|
|
5280
|
+
*
|
|
5281
|
+
* @example
|
|
5282
|
+
* ```typescript
|
|
5283
|
+
* authLoginEvent.subscribe(async (payload) => {
|
|
5284
|
+
* await analytics.trackLogin(payload.userId, payload.provider);
|
|
5285
|
+
* });
|
|
5286
|
+
* ```
|
|
5287
|
+
*/
|
|
5288
|
+
declare const authLoginEvent: _spfn_core_event.EventDef<{
|
|
5289
|
+
email?: string | undefined;
|
|
5290
|
+
phone?: string | undefined;
|
|
5291
|
+
userId: string;
|
|
5292
|
+
provider: "email" | "phone" | "google";
|
|
5293
|
+
}>;
|
|
5294
|
+
/**
|
|
5295
|
+
* auth.register - 회원가입 성공 이벤트
|
|
5296
|
+
*
|
|
5297
|
+
* 발행 시점:
|
|
5298
|
+
* - 이메일/전화 회원가입 성공 시
|
|
5299
|
+
* - OAuth 신규 사용자 가입 시
|
|
5300
|
+
*
|
|
5301
|
+
* @example
|
|
5302
|
+
* ```typescript
|
|
5303
|
+
* authRegisterEvent.subscribe(async (payload) => {
|
|
5304
|
+
* await emailService.sendWelcome(payload.email);
|
|
5305
|
+
* });
|
|
5306
|
+
* ```
|
|
5307
|
+
*/
|
|
5308
|
+
declare const authRegisterEvent: _spfn_core_event.EventDef<{
|
|
5309
|
+
email?: string | undefined;
|
|
5310
|
+
phone?: string | undefined;
|
|
5311
|
+
metadata?: {
|
|
5312
|
+
[x: string]: unknown;
|
|
5313
|
+
} | undefined;
|
|
5314
|
+
userId: string;
|
|
5315
|
+
provider: "email" | "phone" | "google";
|
|
5316
|
+
}>;
|
|
5317
|
+
/**
|
|
5318
|
+
* Auth event payload types
|
|
5319
|
+
*/
|
|
5320
|
+
type AuthLoginPayload = typeof authLoginEvent._payload;
|
|
5321
|
+
type AuthRegisterPayload = typeof authRegisterEvent._payload;
|
|
5322
|
+
|
|
5323
|
+
export { type AuthConfig, AuthContext, type AuthLoginPayload, AuthProviderSchema, type AuthRegisterPayload, COOKIE_NAMES, type CreateOAuthStateParams, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, InvitationStatus, InvitationsRepository, KeyAlgorithmType, type KeyPair, KeysRepository, type NewInvitation, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, type OAuthState, type Permission, type PermissionEntity, PermissionsRepository, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionData, type SessionPayload, SocialAccountsRepository, SocialProvider, type TokenPayload, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, acceptInvitation, addPermissionToRole, authLogger, authLoginEvent, authRegisterEvent, authSchema, cancelInvitation, checkUsernameAvailableService, configureAuth, createAuthLifecycle, createInvitation, createOAuthState, createRole, decodeToken, deleteInvitation, deleteRole, exchangeCodeForTokens, expireOldInvitations, generateClientToken, generateKeyPair, generateKeyPairES256, generateKeyPairRS256, generateToken, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getKeySize, getLocale, getOptionalAuth, getRole, getRoleByName, getRolePermissions, getSessionInfo, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initializeAuth, invitationsRepository, isGoogleOAuthEnabled, keysRepository, listInvitations, parseDuration, permissions, permissionsRepository, refreshAccessToken, removePermissionFromRole, requireAnyPermission, requirePermissions, requireRole, resendInvitation, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, sealSession, setRolePermissions, shouldRefreshSession, shouldRotateKey, socialAccountsRepository, unsealSession, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyKeyFingerprint, verifyOAuthState, verifyPassword, verifyToken };
|