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

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/dist/server.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { k as AuthInitOptions, l as KeyAlgorithmType, n as InvitationStatus, f as VerificationPurpose, j as PermissionCategory, q as AuthContext } from './dto-81uR9gzF.js';
2
- export { B as ChangePasswordParams, w as CheckAccountExistsParams, C as CheckAccountExistsResult, X as EmailSchema, I as INVITATION_STATUSES, K as KEY_ALGORITHM, y as LoginParams, L as LoginResult, z as LogoutParams, Z as PasswordSchema, Y as PhoneSchema, x as RegisterParams, O as RegisterPublicKeyParams, a as RegisterResult, T as RevokeKeyParams, Q as RotateKeyParams, b as RotateKeyResult, e as SOCIAL_PROVIDERS, F as SendVerificationCodeParams, S as SendVerificationCodeResult, p as SocialProvider, _ as TargetTypeSchema, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, $ as VerificationPurposeSchema, V as VerificationTargetType, G as VerifyCodeParams, H as VerifyCodeResult, m as authRouter, W as authenticate, v as changePasswordService, r as checkAccountExistsService, t as loginService, u as logoutService, J as registerPublicKeyService, s as registerService, N as revokeKeyService, M as rotateKeyService, D as sendVerificationCodeService, E as verifyCodeService } from './dto-81uR9gzF.js';
1
+ import { k as AuthInitOptions, l as KeyAlgorithmType, n as InvitationStatus, f as VerificationPurpose, j as PermissionCategory, q as AuthContext } from './authenticate-CU6_zQaa.js';
2
+ export { B as ChangePasswordParams, w as CheckAccountExistsParams, C as CheckAccountExistsResult, X as EmailSchema, I as INVITATION_STATUSES, K as KEY_ALGORITHM, y as LoginParams, L as LoginResult, z as LogoutParams, Z as PasswordSchema, Y as PhoneSchema, x as RegisterParams, O as RegisterPublicKeyParams, a as RegisterResult, T as RevokeKeyParams, Q as RotateKeyParams, b as RotateKeyResult, e as SOCIAL_PROVIDERS, F as SendVerificationCodeParams, S as SendVerificationCodeResult, p as SocialProvider, _ as TargetTypeSchema, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, $ as VerificationPurposeSchema, V as VerificationTargetType, G as VerifyCodeParams, H as VerifyCodeResult, m as authRouter, W as authenticate, v as changePasswordService, r as checkAccountExistsService, t as loginService, u as logoutService, J as registerPublicKeyService, s as registerService, N as revokeKeyService, M as rotateKeyService, D as sendVerificationCodeService, E as verifyCodeService } from './authenticate-CU6_zQaa.js';
3
3
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
4
- import { UserProfile as UserProfile$1 } from '@spfn/auth';
4
+ import { UserProfile as UserProfile$1, ProfileInfo } from '@spfn/auth';
5
5
  import { BaseRepository } from '@spfn/core/db';
6
6
  import { Context } from 'hono';
7
7
  import * as _spfn_core_route from '@spfn/core/route';
@@ -406,6 +406,19 @@ declare function hasAnyPermission(userId: string | number | bigint, permissionNa
406
406
  * ```
407
407
  */
408
408
  declare function hasAllPermissions(userId: string | number | bigint, permissionNames: string[]): Promise<boolean>;
409
+ /**
410
+ * Get user's role name
411
+ *
412
+ * @param userId - User ID
413
+ * @returns Role name or null if user has no role
414
+ *
415
+ * @example
416
+ * ```typescript
417
+ * const role = await getUserRole('123');
418
+ * // 'admin' or null
419
+ * ```
420
+ */
421
+ declare function getUserRole(userId: string | number | bigint): Promise<string | null>;
409
422
  /**
410
423
  * Check if user has a specific role
411
424
  *
@@ -1242,7 +1255,7 @@ declare function getAuthSessionService(userId: string | number | bigint): Promis
1242
1255
  id: number;
1243
1256
  name: string;
1244
1257
  displayName: string;
1245
- category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
1258
+ category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
1246
1259
  }[];
1247
1260
  userId: number;
1248
1261
  email: string | null;
@@ -1253,10 +1266,30 @@ declare function getAuthSessionService(userId: string | number | bigint): Promis
1253
1266
  /**
1254
1267
  * @spfn/auth - User Profile Service
1255
1268
  *
1256
- * Service for retrieving user profile information
1269
+ * Service for retrieving and updating user profile information
1257
1270
  * Returns full user info with profile data
1258
1271
  */
1259
1272
 
1273
+ /**
1274
+ * Profile update parameters
1275
+ * All fields are optional, empty string will be converted to null
1276
+ */
1277
+ interface UpdateProfileParams {
1278
+ displayName?: string;
1279
+ firstName?: string;
1280
+ lastName?: string;
1281
+ avatarUrl?: string;
1282
+ bio?: string;
1283
+ locale?: string;
1284
+ timezone?: string;
1285
+ dateOfBirth?: string;
1286
+ gender?: string;
1287
+ website?: string;
1288
+ location?: string;
1289
+ company?: string;
1290
+ jobTitle?: string;
1291
+ metadata?: Record<string, any>;
1292
+ }
1260
1293
  /**
1261
1294
  * Get user profile information
1262
1295
  *
@@ -1272,369 +1305,26 @@ declare function getAuthSessionService(userId: string | number | bigint): Promis
1272
1305
  * ```
1273
1306
  */
1274
1307
  declare function getUserProfileService(userId: string | number | bigint): Promise<UserProfile$1>;
1275
-
1276
1308
  /**
1277
- * @spfn/auth - Email Template Types
1309
+ * Update user profile (upsert)
1278
1310
  *
1279
- * Type definitions for customizable email templates
1280
- */
1281
- /**
1282
- * Common template result
1283
- */
1284
- interface EmailTemplateResult {
1285
- subject: string;
1286
- text: string;
1287
- html: string;
1288
- }
1289
- /**
1290
- * Verification code template parameters
1291
- */
1292
- interface VerificationCodeParams {
1293
- code: string;
1294
- purpose: 'registration' | 'login' | 'password_reset' | string;
1295
- expiresInMinutes?: number;
1296
- appName?: string;
1297
- }
1298
- /**
1299
- * Email template provider interface
1300
- *
1301
- * Implement this interface to create custom email templates
1311
+ * Creates profile if not exists, updates if exists
1312
+ * Empty strings are converted to null
1302
1313
  *
1303
- * @example
1304
- * ```typescript
1305
- * import { registerEmailTemplates } from '@spfn/auth/server';
1306
- *
1307
- * registerEmailTemplates({
1308
- * verificationCode: (params) => ({
1309
- * subject: 'Your Code',
1310
- * text: `Code: ${params.code}`,
1311
- * html: `<h1>Code: ${params.code}</h1>`,
1312
- * }),
1313
- * });
1314
- * ```
1315
- */
1316
- interface EmailTemplateProvider {
1317
- /**
1318
- * Verification code email template
1319
- */
1320
- verificationCode?(params: VerificationCodeParams): EmailTemplateResult;
1321
- /**
1322
- * Welcome email template (after registration)
1323
- */
1324
- welcome?(params: {
1325
- email: string;
1326
- appName?: string;
1327
- }): EmailTemplateResult;
1328
- /**
1329
- * Password reset email template
1330
- */
1331
- passwordReset?(params: {
1332
- resetLink: string;
1333
- expiresInMinutes?: number;
1334
- appName?: string;
1335
- }): EmailTemplateResult;
1336
- /**
1337
- * Invitation email template
1338
- */
1339
- invitation?(params: {
1340
- inviteLink: string;
1341
- inviterName?: string;
1342
- roleName?: string;
1343
- appName?: string;
1344
- }): EmailTemplateResult;
1345
- }
1346
-
1347
- /**
1348
- * @spfn/auth - Email Template Registry
1349
- *
1350
- * Manages custom email template registration and fallback to defaults
1351
- */
1352
-
1353
- /**
1354
- * Register custom email templates
1355
- *
1356
- * Templates not provided will fall back to defaults
1357
- *
1358
- * @param templates - Custom template implementations
1314
+ * @param userId - User ID
1315
+ * @param params - Profile fields to update
1316
+ * @returns Updated profile info
1359
1317
  *
1360
1318
  * @example
1361
1319
  * ```typescript
1362
- * import { registerEmailTemplates } from '@spfn/auth/server';
1363
- *
1364
- * // Override verification code template with custom design
1365
- * registerEmailTemplates({
1366
- * verificationCode: ({ code, purpose, expiresInMinutes }) => ({
1367
- * subject: `[MyApp] Your verification code`,
1368
- * text: `Your code is: ${code}`,
1369
- * html: `
1370
- * <div style="font-family: Arial;">
1371
- * <h1>Welcome to MyApp!</h1>
1372
- * <p>Your code: <strong>${code}</strong></p>
1373
- * </div>
1374
- * `,
1375
- * }),
1320
+ * const profile = await updateUserProfileService(123, {
1321
+ * displayName: 'John Doe',
1322
+ * bio: 'Software Engineer',
1323
+ * location: '', // will be saved as null
1376
1324
  * });
1377
1325
  * ```
1378
1326
  */
1379
- declare function registerEmailTemplates(templates: Partial<EmailTemplateProvider>): void;
1380
- /**
1381
- * Get verification code template
1382
- *
1383
- * Uses custom template if registered, otherwise falls back to default
1384
- */
1385
- declare function getVerificationCodeTemplate(params: VerificationCodeParams): EmailTemplateResult;
1386
- /**
1387
- * Get welcome template
1388
- */
1389
- declare function getWelcomeTemplate(params: {
1390
- email: string;
1391
- appName?: string;
1392
- }): EmailTemplateResult;
1393
- /**
1394
- * Get password reset template
1395
- */
1396
- declare function getPasswordResetTemplate(params: {
1397
- resetLink: string;
1398
- expiresInMinutes?: number;
1399
- appName?: string;
1400
- }): EmailTemplateResult;
1401
- /**
1402
- * Get invitation template
1403
- */
1404
- declare function getInvitationTemplate(params: {
1405
- inviteLink: string;
1406
- inviterName?: string;
1407
- roleName?: string;
1408
- appName?: string;
1409
- }): EmailTemplateResult;
1410
-
1411
- /**
1412
- * @spfn/auth - Email Service Types
1413
- *
1414
- * Type definitions for email sending service
1415
- */
1416
- /**
1417
- * Parameters for sending email
1418
- */
1419
- interface SendEmailParams {
1420
- /**
1421
- * Recipient email address
1422
- */
1423
- to: string;
1424
- /**
1425
- * Email subject
1426
- */
1427
- subject: string;
1428
- /**
1429
- * Plain text content
1430
- */
1431
- text?: string;
1432
- /**
1433
- * HTML content
1434
- */
1435
- html?: string;
1436
- /**
1437
- * Purpose of the email (for logging)
1438
- */
1439
- purpose?: string;
1440
- }
1441
- /**
1442
- * Result of sending email
1443
- */
1444
- interface SendEmailResult {
1445
- /**
1446
- * Whether email was sent successfully
1447
- */
1448
- success: boolean;
1449
- /**
1450
- * Message ID from email provider (if successful)
1451
- */
1452
- messageId?: string;
1453
- /**
1454
- * Error message (if failed)
1455
- */
1456
- error?: string;
1457
- }
1458
- /**
1459
- * Email Provider Interface
1460
- *
1461
- * Implement this interface to create custom email providers
1462
- *
1463
- * @example
1464
- * ```typescript
1465
- * import { EmailProvider, registerEmailProvider } from '@spfn/auth/server/services/email';
1466
- *
1467
- * const sendgridProvider: EmailProvider = {
1468
- * name: 'sendgrid',
1469
- * sendEmail: async (params) => {
1470
- * // Your SendGrid implementation
1471
- * return { success: true, messageId: '...' };
1472
- * }
1473
- * };
1474
- *
1475
- * registerEmailProvider(sendgridProvider);
1476
- * ```
1477
- */
1478
- interface EmailProvider {
1479
- /**
1480
- * Provider name (e.g., 'aws-ses', 'sendgrid', 'custom')
1481
- */
1482
- name: string;
1483
- /**
1484
- * Send email via this provider
1485
- *
1486
- * @param params - Email parameters
1487
- * @returns Send result
1488
- */
1489
- sendEmail(params: SendEmailParams): Promise<SendEmailResult>;
1490
- }
1491
-
1492
- /**
1493
- * @spfn/auth - Email Provider Management
1494
- *
1495
- * Manages email provider registration and fallback behavior
1496
- */
1497
-
1498
- /**
1499
- * Register a custom email provider
1500
- *
1501
- * @param provider - Custom email provider implementation
1502
- *
1503
- * @example
1504
- * ```typescript
1505
- * import { registerEmailProvider } from '@spfn/auth/server/services/email';
1506
- *
1507
- * const sendgridProvider = {
1508
- * name: 'sendgrid',
1509
- * sendEmail: async (params) => {
1510
- * // SendGrid implementation
1511
- * return { success: true, messageId: '...' };
1512
- * }
1513
- * };
1514
- *
1515
- * registerEmailProvider(sendgridProvider);
1516
- * ```
1517
- */
1518
- declare function registerEmailProvider(provider: EmailProvider): void;
1519
- /**
1520
- * Send email using the registered provider
1521
- *
1522
- * Falls back to development mode (console only) if no provider is registered
1523
- *
1524
- * @param params - Email parameters
1525
- * @returns Send result
1526
- */
1527
- declare function sendEmail(params: SendEmailParams): Promise<SendEmailResult>;
1528
-
1529
- /**
1530
- * @spfn/auth - SMS Service Types
1531
- *
1532
- * Type definitions for SMS sending service
1533
- */
1534
- /**
1535
- * Parameters for sending SMS
1536
- */
1537
- interface SendSMSParams {
1538
- /**
1539
- * Phone number in E.164 format (e.g., +821012345678)
1540
- */
1541
- phone: string;
1542
- /**
1543
- * SMS message content
1544
- */
1545
- message: string;
1546
- /**
1547
- * Purpose of the SMS (for logging)
1548
- */
1549
- purpose?: string;
1550
- }
1551
- /**
1552
- * Result of sending SMS
1553
- */
1554
- interface SendSMSResult {
1555
- /**
1556
- * Whether SMS was sent successfully
1557
- */
1558
- success: boolean;
1559
- /**
1560
- * Message ID from SMS provider (if successful)
1561
- */
1562
- messageId?: string;
1563
- /**
1564
- * Error message (if failed)
1565
- */
1566
- error?: string;
1567
- }
1568
- /**
1569
- * SMS Provider Interface
1570
- *
1571
- * Implement this interface to create custom SMS providers
1572
- *
1573
- * @example
1574
- * ```typescript
1575
- * import { SMSProvider, registerSMSProvider } from '@spfn/auth/server/services/sms';
1576
- *
1577
- * const twilioProvider: SMSProvider = {
1578
- * name: 'twilio',
1579
- * sendSMS: async (params) => {
1580
- * // Your Twilio implementation
1581
- * return { success: true, messageId: '...' };
1582
- * }
1583
- * };
1584
- *
1585
- * registerSMSProvider(twilioProvider);
1586
- * ```
1587
- */
1588
- interface SMSProvider {
1589
- /**
1590
- * Provider name (e.g., 'aws-sns', 'twilio', 'custom')
1591
- */
1592
- name: string;
1593
- /**
1594
- * Send SMS via this provider
1595
- *
1596
- * @param params - SMS parameters
1597
- * @returns Send result
1598
- */
1599
- sendSMS(params: SendSMSParams): Promise<SendSMSResult>;
1600
- }
1601
-
1602
- /**
1603
- * @spfn/auth - SMS Provider Management
1604
- *
1605
- * Manages SMS provider registration and fallback behavior
1606
- */
1607
-
1608
- /**
1609
- * Register a custom SMS provider
1610
- *
1611
- * @param provider - Custom SMS provider implementation
1612
- *
1613
- * @example
1614
- * ```typescript
1615
- * import { registerSMSProvider } from '@spfn/auth/server/services/sms';
1616
- *
1617
- * const twilioProvider = {
1618
- * name: 'twilio',
1619
- * sendSMS: async (params) => {
1620
- * // Twilio implementation
1621
- * return { success: true, messageId: '...' };
1622
- * }
1623
- * };
1624
- *
1625
- * registerSMSProvider(twilioProvider);
1626
- * ```
1627
- */
1628
- declare function registerSMSProvider(provider: SMSProvider): void;
1629
- /**
1630
- * Send SMS using the registered provider
1631
- *
1632
- * Falls back to development mode (console only) if no provider is registered
1633
- *
1634
- * @param params - SMS parameters
1635
- * @returns Send result
1636
- */
1637
- declare function sendSMS(params: SendSMSParams): Promise<SendSMSResult>;
1327
+ declare function updateUserProfileService(userId: string | number | bigint, params: UpdateProfileParams): Promise<ProfileInfo>;
1638
1328
 
1639
1329
  /**
1640
1330
  * @spfn/auth - Database Schema Definition
@@ -2694,7 +2384,7 @@ declare const permissions: drizzle_orm_pg_core.PgTableWithColumns<{
2694
2384
  tableName: "permissions";
2695
2385
  dataType: "string";
2696
2386
  columnType: "PgText";
2697
- data: "custom" | "user" | "auth" | "rbac" | "system";
2387
+ data: "auth" | "custom" | "user" | "rbac" | "system";
2698
2388
  driverParam: string;
2699
2389
  notNull: false;
2700
2390
  hasDefault: false;
@@ -3143,13 +2833,13 @@ declare class UsersRepository extends BaseRepository {
3143
2833
  create(data: NewUser): Promise<{
3144
2834
  email: string | null;
3145
2835
  phone: string | null;
3146
- status: "active" | "inactive" | "suspended";
3147
2836
  id: number;
3148
- createdAt: Date;
3149
- updatedAt: Date;
3150
2837
  passwordHash: string | null;
3151
2838
  passwordChangeRequired: boolean;
3152
2839
  roleId: number;
2840
+ createdAt: Date;
2841
+ updatedAt: Date;
2842
+ status: "active" | "inactive" | "suspended";
3153
2843
  emailVerifiedAt: Date | null;
3154
2844
  phoneVerifiedAt: Date | null;
3155
2845
  lastLoginAt: Date | null;
@@ -3215,13 +2905,13 @@ declare class UsersRepository extends BaseRepository {
3215
2905
  deleteById(id: number): Promise<{
3216
2906
  email: string | null;
3217
2907
  phone: string | null;
3218
- status: "active" | "inactive" | "suspended";
3219
2908
  id: number;
3220
- createdAt: Date;
3221
- updatedAt: Date;
3222
2909
  passwordHash: string | null;
3223
2910
  passwordChangeRequired: boolean;
3224
2911
  roleId: number;
2912
+ createdAt: Date;
2913
+ updatedAt: Date;
2914
+ status: "active" | "inactive" | "suspended";
3225
2915
  emailVerifiedAt: Date | null;
3226
2916
  phoneVerifiedAt: Date | null;
3227
2917
  lastLoginAt: Date | null;
@@ -3244,7 +2934,7 @@ declare class UsersRepository extends BaseRepository {
3244
2934
  id: number;
3245
2935
  name: string;
3246
2936
  displayName: string;
3247
- category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
2937
+ category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
3248
2938
  }[];
3249
2939
  }>;
3250
2940
  /**
@@ -3354,16 +3044,16 @@ declare class KeysRepository extends BaseRepository {
3354
3044
  * Write primary 사용
3355
3045
  */
3356
3046
  create(data: NewUserPublicKey): Promise<{
3357
- userId: number;
3047
+ publicKey: string;
3358
3048
  keyId: string;
3049
+ fingerprint: string;
3050
+ algorithm: "ES256" | "RS256";
3051
+ userId: number;
3359
3052
  id: number;
3360
3053
  isActive: boolean;
3361
3054
  createdAt: Date;
3362
- publicKey: string;
3363
- algorithm: "ES256" | "RS256";
3364
- fingerprint: string;
3365
- lastUsedAt: Date | null;
3366
3055
  expiresAt: Date | null;
3056
+ lastUsedAt: Date | null;
3367
3057
  revokedAt: Date | null;
3368
3058
  revokedReason: string | null;
3369
3059
  }>;
@@ -3390,16 +3080,16 @@ declare class KeysRepository extends BaseRepository {
3390
3080
  * Write primary 사용
3391
3081
  */
3392
3082
  deleteByKeyIdAndUserId(keyId: string, userId: number): Promise<{
3393
- userId: number;
3083
+ publicKey: string;
3394
3084
  keyId: string;
3085
+ fingerprint: string;
3086
+ algorithm: "ES256" | "RS256";
3087
+ userId: number;
3395
3088
  id: number;
3396
3089
  isActive: boolean;
3397
3090
  createdAt: Date;
3398
- publicKey: string;
3399
- algorithm: "ES256" | "RS256";
3400
- fingerprint: string;
3401
- lastUsedAt: Date | null;
3402
3091
  expiresAt: Date | null;
3092
+ lastUsedAt: Date | null;
3403
3093
  revokedAt: Date | null;
3404
3094
  revokedReason: string | null;
3405
3095
  }>;
@@ -3514,14 +3204,14 @@ declare class VerificationCodesRepository extends BaseRepository {
3514
3204
  * Write primary 사용
3515
3205
  */
3516
3206
  create(data: NewVerificationCode): Promise<{
3207
+ target: string;
3208
+ targetType: "email" | "phone";
3209
+ purpose: "registration" | "login" | "password_reset" | "email_change" | "phone_change";
3210
+ code: string;
3517
3211
  id: number;
3518
3212
  createdAt: Date;
3519
3213
  updatedAt: Date;
3520
3214
  expiresAt: Date;
3521
- target: string;
3522
- targetType: "email" | "phone";
3523
- code: string;
3524
- purpose: "registration" | "login" | "password_reset" | "email_change" | "phone_change";
3525
3215
  usedAt: Date | null;
3526
3216
  attempts: number;
3527
3217
  }>;
@@ -3710,7 +3400,7 @@ declare class PermissionsRepository extends BaseRepository {
3710
3400
  name: string;
3711
3401
  displayName: string;
3712
3402
  description: string | null;
3713
- category: "custom" | "user" | "auth" | "rbac" | "system" | null;
3403
+ category: "auth" | "custom" | "user" | "rbac" | "system" | null;
3714
3404
  isBuiltin: boolean;
3715
3405
  isSystem: boolean;
3716
3406
  isActive: boolean;
@@ -3726,7 +3416,7 @@ declare class PermissionsRepository extends BaseRepository {
3726
3416
  name: string;
3727
3417
  displayName: string;
3728
3418
  description: string | null;
3729
- category: "custom" | "user" | "auth" | "rbac" | "system" | null;
3419
+ category: "auth" | "custom" | "user" | "rbac" | "system" | null;
3730
3420
  isBuiltin: boolean;
3731
3421
  isSystem: boolean;
3732
3422
  isActive: boolean;
@@ -3766,7 +3456,7 @@ declare class PermissionsRepository extends BaseRepository {
3766
3456
  name: string;
3767
3457
  displayName: string;
3768
3458
  description: string | null;
3769
- category: "custom" | "user" | "auth" | "rbac" | "system" | null;
3459
+ category: "auth" | "custom" | "user" | "rbac" | "system" | null;
3770
3460
  isBuiltin: boolean;
3771
3461
  isSystem: boolean;
3772
3462
  isActive: boolean;
@@ -3785,8 +3475,8 @@ declare class PermissionsRepository extends BaseRepository {
3785
3475
  isActive: boolean;
3786
3476
  createdAt: Date;
3787
3477
  updatedAt: Date;
3478
+ category: "auth" | "custom" | "user" | "rbac" | "system" | null;
3788
3479
  metadata: Record<string, any> | null;
3789
- category: "custom" | "user" | "auth" | "rbac" | "system" | null;
3790
3480
  }>;
3791
3481
  }
3792
3482
  declare const permissionsRepository: PermissionsRepository;
@@ -3831,9 +3521,9 @@ declare class RolePermissionsRepository extends BaseRepository {
3831
3521
  */
3832
3522
  createMany(data: NewRolePermission[]): Promise<{
3833
3523
  id: number;
3524
+ roleId: number;
3834
3525
  createdAt: Date;
3835
3526
  updatedAt: Date;
3836
- roleId: number;
3837
3527
  permissionId: number;
3838
3528
  }[]>;
3839
3529
  /**
@@ -3849,9 +3539,9 @@ declare class RolePermissionsRepository extends BaseRepository {
3849
3539
  */
3850
3540
  setPermissionsForRole(roleId: number, permissionIds: number[]): Promise<{
3851
3541
  id: number;
3542
+ roleId: number;
3852
3543
  createdAt: Date;
3853
3544
  updatedAt: Date;
3854
- roleId: number;
3855
3545
  permissionId: number;
3856
3546
  }[]>;
3857
3547
  }
@@ -3916,10 +3606,10 @@ declare class UserPermissionsRepository extends BaseRepository {
3916
3606
  id: number;
3917
3607
  createdAt: Date;
3918
3608
  updatedAt: Date;
3919
- expiresAt: Date | null;
3920
3609
  permissionId: number;
3921
- granted: boolean;
3610
+ expiresAt: Date | null;
3922
3611
  reason: string | null;
3612
+ granted: boolean;
3923
3613
  }>;
3924
3614
  /**
3925
3615
  * 사용자 권한 오버라이드 업데이트
@@ -3942,10 +3632,10 @@ declare class UserPermissionsRepository extends BaseRepository {
3942
3632
  id: number;
3943
3633
  createdAt: Date;
3944
3634
  updatedAt: Date;
3945
- expiresAt: Date | null;
3946
3635
  permissionId: number;
3947
- granted: boolean;
3636
+ expiresAt: Date | null;
3948
3637
  reason: string | null;
3638
+ granted: boolean;
3949
3639
  }>;
3950
3640
  /**
3951
3641
  * 사용자의 모든 권한 오버라이드 삭제
@@ -4024,6 +3714,7 @@ declare class UserProfilesRepository extends BaseRepository {
4024
3714
  displayName: string;
4025
3715
  createdAt: Date;
4026
3716
  updatedAt: Date;
3717
+ metadata: Record<string, any> | null;
4027
3718
  firstName: string | null;
4028
3719
  lastName: string | null;
4029
3720
  avatarUrl: string | null;
@@ -4036,7 +3727,6 @@ declare class UserProfilesRepository extends BaseRepository {
4036
3727
  location: string | null;
4037
3728
  company: string | null;
4038
3729
  jobTitle: string | null;
4039
- metadata: Record<string, any> | null;
4040
3730
  }>;
4041
3731
  /**
4042
3732
  * 프로필 업데이트 (by ID)
@@ -4093,6 +3783,7 @@ declare class UserProfilesRepository extends BaseRepository {
4093
3783
  displayName: string;
4094
3784
  createdAt: Date;
4095
3785
  updatedAt: Date;
3786
+ metadata: Record<string, any> | null;
4096
3787
  firstName: string | null;
4097
3788
  lastName: string | null;
4098
3789
  avatarUrl: string | null;
@@ -4105,7 +3796,6 @@ declare class UserProfilesRepository extends BaseRepository {
4105
3796
  location: string | null;
4106
3797
  company: string | null;
4107
3798
  jobTitle: string | null;
4108
- metadata: Record<string, any> | null;
4109
3799
  }>;
4110
3800
  /**
4111
3801
  * 프로필 삭제 (by User ID)
@@ -4116,6 +3806,7 @@ declare class UserProfilesRepository extends BaseRepository {
4116
3806
  displayName: string;
4117
3807
  createdAt: Date;
4118
3808
  updatedAt: Date;
3809
+ metadata: Record<string, any> | null;
4119
3810
  firstName: string | null;
4120
3811
  lastName: string | null;
4121
3812
  avatarUrl: string | null;
@@ -4128,7 +3819,32 @@ declare class UserProfilesRepository extends BaseRepository {
4128
3819
  location: string | null;
4129
3820
  company: string | null;
4130
3821
  jobTitle: string | null;
3822
+ }>;
3823
+ /**
3824
+ * 프로필 Upsert (by User ID)
3825
+ *
3826
+ * 프로필이 없으면 생성, 있으면 업데이트
3827
+ * 새로 생성 시 displayName은 필수 (없으면 'User'로 설정)
3828
+ */
3829
+ upsertByUserId(userId: number, data: Partial<Omit<NewUserProfile, 'userId'>>): Promise<{
3830
+ userId: number;
3831
+ id: number;
3832
+ displayName: string;
3833
+ createdAt: Date;
3834
+ updatedAt: Date;
4131
3835
  metadata: Record<string, any> | null;
3836
+ firstName: string | null;
3837
+ lastName: string | null;
3838
+ avatarUrl: string | null;
3839
+ bio: string | null;
3840
+ locale: string | null;
3841
+ timezone: string | null;
3842
+ dateOfBirth: string | null;
3843
+ gender: string | null;
3844
+ website: string | null;
3845
+ location: string | null;
3846
+ company: string | null;
3847
+ jobTitle: string | null;
4132
3848
  }>;
4133
3849
  /**
4134
3850
  * User ID로 프로필 데이터 조회 (formatted)
@@ -4148,6 +3864,7 @@ declare class UserProfilesRepository extends BaseRepository {
4148
3864
  location: string | null;
4149
3865
  company: string | null;
4150
3866
  jobTitle: string | null;
3867
+ metadata: Record<string, any> | null;
4151
3868
  createdAt: Date;
4152
3869
  updatedAt: Date;
4153
3870
  } | null>;
@@ -4255,15 +3972,15 @@ declare class InvitationsRepository extends BaseRepository {
4255
3972
  */
4256
3973
  create(data: NewInvitation): Promise<{
4257
3974
  email: string;
4258
- status: "pending" | "accepted" | "expired" | "cancelled";
4259
3975
  id: number;
3976
+ roleId: number;
4260
3977
  createdAt: Date;
4261
3978
  updatedAt: Date;
4262
- roleId: number;
3979
+ status: "pending" | "accepted" | "expired" | "cancelled";
4263
3980
  metadata: Record<string, any> | null;
4264
- expiresAt: Date;
4265
3981
  token: string;
4266
3982
  invitedBy: number;
3983
+ expiresAt: Date;
4267
3984
  acceptedAt: Date | null;
4268
3985
  cancelledAt: Date | null;
4269
3986
  }>;
@@ -4289,15 +4006,15 @@ declare class InvitationsRepository extends BaseRepository {
4289
4006
  */
4290
4007
  deleteById(id: number): Promise<{
4291
4008
  email: string;
4292
- status: "pending" | "accepted" | "expired" | "cancelled";
4293
4009
  id: number;
4010
+ roleId: number;
4294
4011
  createdAt: Date;
4295
4012
  updatedAt: Date;
4296
- roleId: number;
4013
+ status: "pending" | "accepted" | "expired" | "cancelled";
4297
4014
  metadata: Record<string, any> | null;
4298
- expiresAt: Date;
4299
4015
  token: string;
4300
4016
  invitedBy: number;
4017
+ expiresAt: Date;
4301
4018
  acceptedAt: Date | null;
4302
4019
  cancelledAt: Date | null;
4303
4020
  }>;
@@ -4715,6 +4432,57 @@ declare const requireAnyPermission: _spfn_core_route.NamedMiddlewareFactory<"any
4715
4432
  */
4716
4433
  declare const requireRole: _spfn_core_route.NamedMiddlewareFactory<"role", string[]>;
4717
4434
 
4435
+ /**
4436
+ * @spfn/auth - Role Guard Middleware
4437
+ *
4438
+ * Middleware for role-based access control with allow/deny options
4439
+ */
4440
+ /**
4441
+ * Role guard options
4442
+ */
4443
+ interface RoleGuardOptions {
4444
+ /**
4445
+ * Roles to allow (OR condition)
4446
+ * User must have at least one of these roles
4447
+ */
4448
+ allow?: string[];
4449
+ /**
4450
+ * Roles to deny
4451
+ * User with any of these roles will be rejected
4452
+ */
4453
+ deny?: string[];
4454
+ }
4455
+ /**
4456
+ * Role-based access control middleware
4457
+ *
4458
+ * Must be used after authenticate middleware
4459
+ *
4460
+ * @param options - Role guard options (allow/deny)
4461
+ * @returns Middleware function
4462
+ *
4463
+ * @example Allow specific roles
4464
+ * ```typescript
4465
+ * export const adminRoute = route.get('/admin')
4466
+ * .use([authenticate, roleGuard({ allow: ['admin', 'superadmin'] })])
4467
+ * .handler(async (c) => { ... });
4468
+ * ```
4469
+ *
4470
+ * @example Deny specific roles
4471
+ * ```typescript
4472
+ * export const publicRoute = route.get('/content')
4473
+ * .use([authenticate, roleGuard({ deny: ['banned', 'suspended'] })])
4474
+ * .handler(async (c) => { ... });
4475
+ * ```
4476
+ *
4477
+ * @example Combined allow and deny
4478
+ * ```typescript
4479
+ * export const managerRoute = route.get('/manage')
4480
+ * .use([authenticate, roleGuard({ allow: ['admin', 'manager'], deny: ['suspended'] })])
4481
+ * .handler(async (c) => { ... });
4482
+ * ```
4483
+ */
4484
+ declare const roleGuard: _spfn_core_route.NamedMiddlewareFactory<"roleGuard", [options: RoleGuardOptions]>;
4485
+
4718
4486
  /**
4719
4487
  * Auth Context Helpers
4720
4488
  *
@@ -4757,13 +4525,13 @@ declare function getUser(c: Context | {
4757
4525
  }): {
4758
4526
  email: string | null;
4759
4527
  phone: string | null;
4760
- status: "active" | "inactive" | "suspended";
4761
4528
  id: number;
4762
- createdAt: Date;
4763
- updatedAt: Date;
4764
4529
  passwordHash: string | null;
4765
4530
  passwordChangeRequired: boolean;
4766
4531
  roleId: number;
4532
+ createdAt: Date;
4533
+ updatedAt: Date;
4534
+ status: "active" | "inactive" | "suspended";
4767
4535
  emailVerifiedAt: Date | null;
4768
4536
  phoneVerifiedAt: Date | null;
4769
4537
  lastLoginAt: Date | null;
@@ -5068,4 +4836,4 @@ interface AuthLifecycleConfig {
5068
4836
  */
5069
4837
  declare function createAuthLifecycle(options?: AuthInitOptions): AuthLifecycleConfig;
5070
4838
 
5071
- export { type AuthConfig, AuthContext, COOKIE_NAMES, type EmailProvider, type EmailTemplateProvider, type EmailTemplateResult, 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 Permission, type PermissionEntity, PermissionsRepository, type Role, type RoleEntity, type RolePermission, RolePermissionsRepository, RolesRepository, type SMSProvider, type SendEmailParams, type SendEmailResult, type SendSMSParams, type SendSMSResult, type SessionData, type SessionPayload, type TokenPayload, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, type VerificationCodeParams, VerificationCodesRepository, VerificationPurpose, acceptInvitation, addPermissionToRole, authLogger, authSchema, cancelInvitation, configureAuth, createAuthLifecycle, createInvitation, createRole, decodeToken, deleteInvitation, deleteRole, expireOldInvitations, generateClientToken, generateKeyPair, generateKeyPairES256, generateKeyPairRS256, generateToken, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getInvitationByToken, getInvitationTemplate, getInvitationWithDetails, getKeyId, getKeySize, getPasswordResetTemplate, getRoleByName, getRolePermissions, getSessionInfo, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getVerificationCodeTemplate, getWelcomeTemplate, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initializeAuth, invitationsRepository, keysRepository, listInvitations, parseDuration, permissions, permissionsRepository, registerEmailProvider, registerEmailTemplates, registerSMSProvider, removePermissionFromRole, requireAnyPermission, requirePermissions, requireRole, resendInvitation, rolePermissions, rolePermissionsRepository, roles, rolesRepository, sealSession, sendEmail, sendSMS, setRolePermissions, shouldRefreshSession, shouldRotateKey, unsealSession, updateLastLoginService, updateRole, updateUserService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyKeyFingerprint, verifyPassword, verifyToken };
4839
+ export { type AuthConfig, AuthContext, COOKIE_NAMES, 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 Permission, type PermissionEntity, PermissionsRepository, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionData, type SessionPayload, type TokenPayload, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, acceptInvitation, addPermissionToRole, authLogger, authSchema, cancelInvitation, configureAuth, createAuthLifecycle, createInvitation, createRole, decodeToken, deleteInvitation, deleteRole, expireOldInvitations, generateClientToken, generateKeyPair, generateKeyPairES256, generateKeyPairRS256, generateToken, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getInvitationByToken, getInvitationWithDetails, getKeyId, getKeySize, getRoleByName, getRolePermissions, getSessionInfo, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initializeAuth, invitationsRepository, keysRepository, listInvitations, parseDuration, permissions, permissionsRepository, removePermissionFromRole, requireAnyPermission, requirePermissions, requireRole, resendInvitation, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, sealSession, setRolePermissions, shouldRefreshSession, shouldRotateKey, unsealSession, updateLastLoginService, updateRole, updateUserProfileService, updateUserService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyKeyFingerprint, verifyPassword, verifyToken };