@spfn/auth 0.1.0-alpha.0 → 0.1.0-alpha.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +320 -12
  3. package/dist/adapters/nextjs/api.d.ts +446 -0
  4. package/dist/adapters/nextjs/api.js +3279 -0
  5. package/dist/adapters/nextjs/api.js.map +1 -0
  6. package/dist/adapters/nextjs/server.d.ts +246 -0
  7. package/dist/adapters/nextjs/server.js +3645 -0
  8. package/dist/adapters/nextjs/server.js.map +1 -0
  9. package/dist/client.d.ts +2 -0
  10. package/dist/client.js +1 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/index.d.ts +14 -0
  13. package/dist/index.js +9098 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/api/auth-codes-verify.d.ts +37 -0
  16. package/dist/lib/api/auth-codes-verify.js +2949 -0
  17. package/dist/lib/api/auth-codes-verify.js.map +1 -0
  18. package/dist/lib/api/auth-codes.d.ts +37 -0
  19. package/dist/lib/api/auth-codes.js +2949 -0
  20. package/dist/lib/api/auth-codes.js.map +1 -0
  21. package/dist/lib/api/auth-exists.d.ts +38 -0
  22. package/dist/lib/api/auth-exists.js +2949 -0
  23. package/dist/lib/api/auth-exists.js.map +1 -0
  24. package/dist/lib/api/auth-invitations-accept.d.ts +38 -0
  25. package/dist/lib/api/auth-invitations-accept.js +2883 -0
  26. package/dist/lib/api/auth-invitations-accept.js.map +1 -0
  27. package/dist/lib/api/auth-invitations-cancel.d.ts +37 -0
  28. package/dist/lib/api/auth-invitations-cancel.js +2883 -0
  29. package/dist/lib/api/auth-invitations-cancel.js.map +1 -0
  30. package/dist/lib/api/auth-invitations-delete.d.ts +36 -0
  31. package/dist/lib/api/auth-invitations-delete.js +2883 -0
  32. package/dist/lib/api/auth-invitations-delete.js.map +1 -0
  33. package/dist/lib/api/auth-invitations-resend.d.ts +37 -0
  34. package/dist/lib/api/auth-invitations-resend.js +2883 -0
  35. package/dist/lib/api/auth-invitations-resend.js.map +1 -0
  36. package/dist/lib/api/auth-invitations.d.ts +109 -0
  37. package/dist/lib/api/auth-invitations.js +2887 -0
  38. package/dist/lib/api/auth-invitations.js.map +1 -0
  39. package/dist/lib/api/auth-keys-rotate.d.ts +37 -0
  40. package/dist/lib/api/auth-keys-rotate.js +2949 -0
  41. package/dist/lib/api/auth-keys-rotate.js.map +1 -0
  42. package/dist/lib/api/auth-login.d.ts +39 -0
  43. package/dist/lib/api/auth-login.js +2949 -0
  44. package/dist/lib/api/auth-login.js.map +1 -0
  45. package/dist/lib/api/auth-logout.d.ts +36 -0
  46. package/dist/lib/api/auth-logout.js +2949 -0
  47. package/dist/lib/api/auth-logout.js.map +1 -0
  48. package/dist/lib/api/auth-me.d.ts +50 -0
  49. package/dist/lib/api/auth-me.js +2949 -0
  50. package/dist/lib/api/auth-me.js.map +1 -0
  51. package/dist/lib/api/auth-password.d.ts +36 -0
  52. package/dist/lib/api/auth-password.js +2949 -0
  53. package/dist/lib/api/auth-password.js.map +1 -0
  54. package/dist/lib/api/auth-register.d.ts +38 -0
  55. package/dist/lib/api/auth-register.js +2949 -0
  56. package/dist/lib/api/auth-register.js.map +1 -0
  57. package/dist/lib/api/index.d.ts +356 -0
  58. package/dist/lib/api/index.js +3261 -0
  59. package/dist/lib/api/index.js.map +1 -0
  60. package/dist/lib/config.d.ts +70 -0
  61. package/dist/lib/config.js +64 -0
  62. package/dist/lib/config.js.map +1 -0
  63. package/dist/lib/contracts/auth.d.ts +302 -0
  64. package/dist/lib/contracts/auth.js +2951 -0
  65. package/dist/lib/contracts/auth.js.map +1 -0
  66. package/dist/lib/contracts/index.d.ts +3 -0
  67. package/dist/lib/contracts/index.js +3190 -0
  68. package/dist/lib/contracts/index.js.map +1 -0
  69. package/dist/lib/contracts/invitation.d.ts +243 -0
  70. package/dist/lib/contracts/invitation.js +2883 -0
  71. package/dist/lib/contracts/invitation.js.map +1 -0
  72. package/dist/lib/crypto.d.ts +76 -0
  73. package/dist/lib/crypto.js +127 -0
  74. package/dist/lib/crypto.js.map +1 -0
  75. package/dist/lib/index.d.ts +4 -0
  76. package/dist/lib/index.js +313 -0
  77. package/dist/lib/index.js.map +1 -0
  78. package/dist/lib/session.d.ts +68 -0
  79. package/dist/lib/session.js +126 -0
  80. package/dist/lib/session.js.map +1 -0
  81. package/dist/lib/types/api.d.ts +45 -0
  82. package/dist/lib/types/api.js +1 -0
  83. package/dist/lib/types/api.js.map +1 -0
  84. package/dist/lib/types/index.d.ts +3 -0
  85. package/dist/lib/types/index.js +2647 -0
  86. package/dist/lib/types/index.js.map +1 -0
  87. package/dist/lib/types/schemas.d.ts +45 -0
  88. package/dist/lib/types/schemas.js +2647 -0
  89. package/dist/lib/types/schemas.js.map +1 -0
  90. package/dist/lib.d.ts +2 -0
  91. package/dist/lib.js +1 -0
  92. package/dist/lib.js.map +1 -0
  93. package/dist/plugin.d.ts +12 -0
  94. package/dist/plugin.js +9081 -0
  95. package/dist/plugin.js.map +1 -0
  96. package/dist/server/entities/index.d.ts +11 -0
  97. package/dist/server/entities/index.js +395 -0
  98. package/dist/server/entities/index.js.map +1 -0
  99. package/dist/server/entities/invitations.d.ts +241 -0
  100. package/dist/server/entities/invitations.js +184 -0
  101. package/dist/server/entities/invitations.js.map +1 -0
  102. package/dist/server/entities/permissions.d.ts +196 -0
  103. package/dist/server/entities/permissions.js +49 -0
  104. package/dist/server/entities/permissions.js.map +1 -0
  105. package/dist/server/entities/role-permissions.d.ts +107 -0
  106. package/dist/server/entities/role-permissions.js +115 -0
  107. package/dist/server/entities/role-permissions.js.map +1 -0
  108. package/dist/server/entities/roles.d.ts +196 -0
  109. package/dist/server/entities/roles.js +50 -0
  110. package/dist/server/entities/roles.js.map +1 -0
  111. package/dist/server/entities/schema.d.ts +14 -0
  112. package/dist/server/entities/schema.js +7 -0
  113. package/dist/server/entities/schema.js.map +1 -0
  114. package/dist/server/entities/user-permissions.d.ts +163 -0
  115. package/dist/server/entities/user-permissions.js +193 -0
  116. package/dist/server/entities/user-permissions.js.map +1 -0
  117. package/dist/server/entities/user-public-keys.d.ts +227 -0
  118. package/dist/server/entities/user-public-keys.js +156 -0
  119. package/dist/server/entities/user-public-keys.js.map +1 -0
  120. package/dist/server/entities/user-social-accounts.d.ts +189 -0
  121. package/dist/server/entities/user-social-accounts.js +149 -0
  122. package/dist/server/entities/user-social-accounts.js.map +1 -0
  123. package/dist/server/entities/users.d.ts +235 -0
  124. package/dist/server/entities/users.js +117 -0
  125. package/dist/server/entities/users.js.map +1 -0
  126. package/dist/server/entities/verification-codes.d.ts +191 -0
  127. package/dist/server/entities/verification-codes.js +49 -0
  128. package/dist/server/entities/verification-codes.js.map +1 -0
  129. package/dist/server/routes/auth/index.d.ts +10 -0
  130. package/dist/server/routes/auth/index.js +4458 -0
  131. package/dist/server/routes/auth/index.js.map +1 -0
  132. package/dist/server/routes/index.d.ts +6 -0
  133. package/dist/server/routes/index.js +6582 -0
  134. package/dist/server/routes/index.js.map +1 -0
  135. package/dist/server/routes/invitations/index.d.ts +10 -0
  136. package/dist/server/routes/invitations/index.js +4395 -0
  137. package/dist/server/routes/invitations/index.js.map +1 -0
  138. package/dist/server.d.ts +1272 -0
  139. package/dist/server.js +2274 -0
  140. package/dist/server.js.map +1 -0
  141. package/migrations/0000_complex_swordsman.sql +167 -0
  142. package/migrations/meta/0000_snapshot.json +1397 -0
  143. package/migrations/meta/_journal.json +13 -0
  144. package/package.json +59 -24
@@ -0,0 +1,1272 @@
1
+ import { User } from './server/entities/users.js';
2
+ import { Role } from './server/entities/roles.js';
3
+ import { Invitation, InvitationWithDetails, InvitationStatus } from './server/entities/invitations.js';
4
+ import { SessionPayload } from './lib/types/api.js';
5
+ import { Context, Next } from 'hono';
6
+ import 'drizzle-orm/pg-core';
7
+
8
+ /**
9
+ * @spfn/auth - RBAC Type Definitions
10
+ *
11
+ * Type definitions for role and permission configuration
12
+ */
13
+ interface RoleConfig {
14
+ name: string;
15
+ displayName: string;
16
+ description?: string;
17
+ priority?: number;
18
+ isSystem?: boolean;
19
+ isBuiltin?: boolean;
20
+ }
21
+ interface PermissionConfig {
22
+ name: string;
23
+ displayName: string;
24
+ description?: string;
25
+ category?: string;
26
+ isSystem?: boolean;
27
+ isBuiltin?: boolean;
28
+ }
29
+ interface AuthInitOptions {
30
+ /**
31
+ * Additional roles to create
32
+ * Built-in roles (user, admin, superadmin) are automatically included
33
+ */
34
+ roles?: RoleConfig[];
35
+ /**
36
+ * Additional permissions to create
37
+ * Built-in permissions are automatically included
38
+ */
39
+ permissions?: PermissionConfig[];
40
+ /**
41
+ * Role-Permission mappings
42
+ * Built-in mappings are automatically included
43
+ * You can extend built-in roles or define mappings for custom roles
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * {
48
+ * // Extend built-in admin role
49
+ * admin: ['project:create', 'project:delete'],
50
+ *
51
+ * // Define custom role permissions
52
+ * 'project-manager': ['project:create', 'task:assign'],
53
+ * }
54
+ * ```
55
+ */
56
+ rolePermissions?: Record<string, string[]>;
57
+ /**
58
+ * Default role name for new users
59
+ * Must be a valid role name that exists after initialization
60
+ * @default 'user'
61
+ */
62
+ defaultRole?: string;
63
+ /**
64
+ * Default session TTL (Time To Live)
65
+ *
66
+ * Supports:
67
+ * - Number: seconds (e.g., 2592000)
68
+ * - String: duration format ('30d', '12h', '45m', '3600s')
69
+ *
70
+ * Can be overridden at runtime with `remember` parameter.
71
+ *
72
+ * @default '7d' (7 days)
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * {
77
+ * sessionTtl: '30d', // 30 days
78
+ * }
79
+ * ```
80
+ */
81
+ sessionTtl?: string | number;
82
+ }
83
+
84
+ /**
85
+ * @spfn/auth - Built-in Roles and Permissions
86
+ *
87
+ * Core roles and permissions required by the auth package
88
+ * These cannot be deleted and are automatically created on initialization
89
+ */
90
+
91
+ /**
92
+ * Built-in roles (required by package)
93
+ * These roles are always created and cannot be deleted
94
+ */
95
+ declare const BUILTIN_ROLES: Record<string, RoleConfig>;
96
+ /**
97
+ * Built-in permissions (required by package)
98
+ * These permissions are always created and cannot be deleted
99
+ */
100
+ declare const BUILTIN_PERMISSIONS: Record<string, PermissionConfig>;
101
+ /**
102
+ * Built-in role-permission mappings
103
+ * Defines default permissions for each built-in role
104
+ */
105
+ declare const BUILTIN_ROLE_PERMISSIONS: Record<string, string[]>;
106
+ type BuiltinRoleName = keyof typeof BUILTIN_ROLE_PERMISSIONS;
107
+ type BuiltinPermissionName = typeof BUILTIN_PERMISSIONS[keyof typeof BUILTIN_PERMISSIONS]['name'];
108
+
109
+ /**
110
+ * @spfn/auth - Auth Service
111
+ *
112
+ * Core authentication logic: registration, login, logout, password management
113
+ */
114
+ interface CheckAccountExistsParams {
115
+ email?: string;
116
+ phone?: string;
117
+ }
118
+ interface CheckAccountExistsResult {
119
+ exists: boolean;
120
+ identifier: string;
121
+ identifierType: 'email' | 'phone';
122
+ }
123
+ interface RegisterParams {
124
+ email?: string;
125
+ phone?: string;
126
+ verificationToken: string;
127
+ password: string;
128
+ publicKey: string;
129
+ keyId: string;
130
+ fingerprint: string;
131
+ algorithm?: 'ES256' | 'RS256';
132
+ }
133
+ interface RegisterResult {
134
+ userId: string;
135
+ email?: string;
136
+ phone?: string;
137
+ }
138
+ interface LoginParams {
139
+ email?: string;
140
+ phone?: string;
141
+ password: string;
142
+ publicKey: string;
143
+ keyId: string;
144
+ fingerprint: string;
145
+ oldKeyId?: string;
146
+ algorithm?: 'ES256' | 'RS256';
147
+ }
148
+ interface LoginResult {
149
+ userId: string;
150
+ email?: string;
151
+ phone?: string;
152
+ passwordChangeRequired: boolean;
153
+ }
154
+ interface LogoutParams {
155
+ userId: number;
156
+ keyId: string;
157
+ }
158
+ interface ChangePasswordParams {
159
+ userId: number;
160
+ currentPassword: string;
161
+ newPassword: string;
162
+ passwordHash?: string;
163
+ }
164
+ /**
165
+ * Check if an account exists by email or phone
166
+ */
167
+ declare function checkAccountExistsService(params: CheckAccountExistsParams): Promise<CheckAccountExistsResult>;
168
+ /**
169
+ * Register a new user account
170
+ */
171
+ declare function registerService(params: RegisterParams): Promise<RegisterResult>;
172
+ /**
173
+ * Authenticate user and create session
174
+ */
175
+ declare function loginService(params: LoginParams): Promise<LoginResult>;
176
+ /**
177
+ * Logout user (revoke current key)
178
+ */
179
+ declare function logoutService(params: LogoutParams): Promise<void>;
180
+ /**
181
+ * Change user password
182
+ */
183
+ declare function changePasswordService(params: ChangePasswordParams): Promise<void>;
184
+
185
+ /**
186
+ * @spfn/auth - Verification Service
187
+ *
188
+ * Handles OTP code generation, validation, and delivery
189
+ */
190
+ interface SendVerificationCodeParams {
191
+ target: string;
192
+ targetType: 'email' | 'phone';
193
+ purpose: 'registration' | 'login' | 'password_reset';
194
+ }
195
+ interface SendVerificationCodeResult {
196
+ success: boolean;
197
+ expiresAt: string;
198
+ }
199
+ interface VerifyCodeParams {
200
+ target: string;
201
+ targetType: 'email' | 'phone';
202
+ code: string;
203
+ purpose: 'registration' | 'login' | 'password_reset';
204
+ }
205
+ interface VerifyCodeResult {
206
+ valid: boolean;
207
+ verificationToken: string;
208
+ }
209
+ /**
210
+ * Send verification code via email or SMS
211
+ */
212
+ declare function sendVerificationCodeService(params: SendVerificationCodeParams): Promise<SendVerificationCodeResult>;
213
+ /**
214
+ * Verify OTP code and return verification token
215
+ */
216
+ declare function verifyCodeService(params: VerifyCodeParams): Promise<VerifyCodeResult>;
217
+
218
+ /**
219
+ * @spfn/auth - Key Service
220
+ *
221
+ * Handles public key registration, rotation, and revocation
222
+ */
223
+ interface RegisterPublicKeyParams {
224
+ userId: number;
225
+ keyId: string;
226
+ publicKey: string;
227
+ fingerprint: string;
228
+ algorithm?: 'ES256' | 'RS256';
229
+ }
230
+ interface RotateKeyParams {
231
+ userId: number;
232
+ oldKeyId: string;
233
+ newKeyId: string;
234
+ newPublicKey: string;
235
+ fingerprint: string;
236
+ algorithm?: 'ES256' | 'RS256';
237
+ }
238
+ interface RotateKeyResult {
239
+ success: boolean;
240
+ keyId: string;
241
+ }
242
+ interface RevokeKeyParams {
243
+ userId: number;
244
+ keyId: string;
245
+ reason: string;
246
+ }
247
+ /**
248
+ * Register a new public key for a user
249
+ */
250
+ declare function registerPublicKeyService(params: RegisterPublicKeyParams): Promise<void>;
251
+ /**
252
+ * Rotate user's public key (revoke old, register new)
253
+ */
254
+ declare function rotateKeyService(params: RotateKeyParams): Promise<RotateKeyResult>;
255
+ /**
256
+ * Revoke a user's public key
257
+ */
258
+ declare function revokeKeyService(params: RevokeKeyParams): Promise<void>;
259
+
260
+ /**
261
+ * @spfn/auth - User Service
262
+ *
263
+ * Handles user CRUD operations
264
+ */
265
+
266
+ /**
267
+ * Get user by ID
268
+ */
269
+ declare function getUserByIdService(userId: number): Promise<User | null>;
270
+ /**
271
+ * Get user by email
272
+ */
273
+ declare function getUserByEmailService(email: string): Promise<User | null>;
274
+ /**
275
+ * Get user by phone
276
+ */
277
+ declare function getUserByPhoneService(phone: string): Promise<User | null>;
278
+ /**
279
+ * Update user's last login timestamp
280
+ */
281
+ declare function updateLastLoginService(userId: number): Promise<void>;
282
+ /**
283
+ * Update user data
284
+ */
285
+ declare function updateUserService(userId: number, updates: Partial<Omit<User, 'id' | 'createdAt'>>): Promise<void>;
286
+
287
+ /**
288
+ * @spfn/auth - Me Service
289
+ *
290
+ * Service for retrieving current user information
291
+ */
292
+ interface GetMeResult {
293
+ userId: string;
294
+ email?: string;
295
+ phone?: string;
296
+ role: {
297
+ id: number;
298
+ name: string;
299
+ displayName: string;
300
+ priority: number;
301
+ };
302
+ permissions: Array<{
303
+ id: number;
304
+ name: string;
305
+ displayName: string;
306
+ category?: string;
307
+ }>;
308
+ }
309
+ /**
310
+ * Get current user information including role and permissions
311
+ *
312
+ * @param userId - User ID (string, number, or bigint)
313
+ * @returns User info with role and permissions
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * const userInfo = await getMeService('123');
318
+ * console.log(userInfo.role.name); // 'admin'
319
+ * console.log(userInfo.permissions.length); // 15
320
+ * ```
321
+ */
322
+ declare function getMeService(userId: string | number | bigint): Promise<GetMeResult>;
323
+
324
+ /**
325
+ * @spfn/auth - RBAC Initialization Service
326
+ *
327
+ * Initialize roles, permissions, and their mappings
328
+ */
329
+
330
+ /**
331
+ * Initialize auth package with RBAC system
332
+ *
333
+ * Creates built-in roles, permissions, and custom configurations
334
+ *
335
+ * @param options - Initialization options
336
+ *
337
+ * @example
338
+ * ```typescript
339
+ * // Minimal - only built-in roles (user, admin, superadmin)
340
+ * await initializeAuth();
341
+ *
342
+ * // Custom roles and permissions
343
+ * await initializeAuth({
344
+ * roles: [
345
+ * { name: 'project-manager', displayName: 'Project Manager', priority: 50 },
346
+ * { name: 'developer', displayName: 'Developer', priority: 30 },
347
+ * ],
348
+ * permissions: [
349
+ * { name: 'project:create', displayName: 'Create Project', category: 'project' },
350
+ * { name: 'task:assign', displayName: 'Assign Task', category: 'task' },
351
+ * ],
352
+ * rolePermissions: {
353
+ * 'project-manager': ['project:create', 'task:assign'],
354
+ * 'developer': ['task:complete'],
355
+ * },
356
+ * });
357
+ * ```
358
+ */
359
+ declare function initializeAuth(options?: AuthInitOptions): Promise<void>;
360
+
361
+ /**
362
+ * @spfn/auth - Permission Service
363
+ *
364
+ * Permission checking and validation logic
365
+ */
366
+ /**
367
+ * Get all permissions for a user
368
+ *
369
+ * Combines role-based permissions with user-specific overrides
370
+ * Handles expiration of temporary permissions
371
+ *
372
+ * @param userId - User ID (string, number, or bigint)
373
+ * @returns Array of permission names
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * const perms = await getUserPermissions('123');
378
+ * // ['auth:self:manage', 'user:read', 'post:create']
379
+ * ```
380
+ */
381
+ declare function getUserPermissions(userId: string | number | bigint): Promise<string[]>;
382
+ /**
383
+ * Check if user has a specific permission
384
+ *
385
+ * @param userId - User ID
386
+ * @param permissionName - Permission name (e.g., 'user:delete')
387
+ * @returns true if user has permission
388
+ *
389
+ * @example
390
+ * ```typescript
391
+ * if (await hasPermission('123', 'user:delete')) {
392
+ * // User can delete users
393
+ * }
394
+ * ```
395
+ */
396
+ declare function hasPermission(userId: string | number | bigint, permissionName: string): Promise<boolean>;
397
+ /**
398
+ * Check if user has any of the specified permissions
399
+ *
400
+ * @param userId - User ID
401
+ * @param permissionNames - Array of permission names
402
+ * @returns true if user has at least one permission
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * if (await hasAnyPermission('123', ['post:read', 'admin:access'])) {
407
+ * // User can access content
408
+ * }
409
+ * ```
410
+ */
411
+ declare function hasAnyPermission(userId: string | number | bigint, permissionNames: string[]): Promise<boolean>;
412
+ /**
413
+ * Check if user has all of the specified permissions
414
+ *
415
+ * @param userId - User ID
416
+ * @param permissionNames - Array of permission names
417
+ * @returns true if user has all permissions
418
+ *
419
+ * @example
420
+ * ```typescript
421
+ * if (await hasAllPermissions('123', ['post:write', 'post:publish'])) {
422
+ * // User can write AND publish
423
+ * }
424
+ * ```
425
+ */
426
+ declare function hasAllPermissions(userId: string | number | bigint, permissionNames: string[]): Promise<boolean>;
427
+ /**
428
+ * Check if user has a specific role
429
+ *
430
+ * @param userId - User ID
431
+ * @param roleName - Role name (e.g., 'admin', 'superadmin')
432
+ * @returns true if user has role
433
+ *
434
+ * @example
435
+ * ```typescript
436
+ * if (await hasRole('123', 'admin')) {
437
+ * // User is admin
438
+ * }
439
+ * ```
440
+ */
441
+ declare function hasRole(userId: string | number | bigint, roleName: string): Promise<boolean>;
442
+ /**
443
+ * Check if user has any of the specified roles
444
+ *
445
+ * @param userId - User ID
446
+ * @param roleNames - Array of role names
447
+ * @returns true if user has at least one role
448
+ */
449
+ declare function hasAnyRole(userId: string | number | bigint, roleNames: string[]): Promise<boolean>;
450
+
451
+ /**
452
+ * @spfn/auth - Role Service
453
+ *
454
+ * Role management functions for runtime role creation and modification
455
+ */
456
+
457
+ /**
458
+ * Create a new custom role
459
+ *
460
+ * @param data - Role configuration
461
+ * @returns Created role
462
+ * @throws Error if role name already exists
463
+ *
464
+ * @example
465
+ * ```typescript
466
+ * const role = await createRole({
467
+ * name: 'content-creator',
468
+ * displayName: 'Content Creator',
469
+ * description: 'Can create and publish content',
470
+ * priority: 20,
471
+ * permissionIds: [1n, 2n, 3n],
472
+ * });
473
+ * ```
474
+ */
475
+ declare function createRole(data: {
476
+ name: string;
477
+ displayName: string;
478
+ description?: string;
479
+ priority?: number;
480
+ permissionIds?: number[];
481
+ }): Promise<Role>;
482
+ /**
483
+ * Update an existing role
484
+ *
485
+ * @param roleId - Role ID
486
+ * @param data - Update data
487
+ * @returns Updated role
488
+ * @throws Error if role is built-in (cannot modify)
489
+ *
490
+ * @example
491
+ * ```typescript
492
+ * await updateRole(1n, {
493
+ * displayName: 'Senior Content Creator',
494
+ * priority: 25,
495
+ * });
496
+ * ```
497
+ */
498
+ declare function updateRole(roleId: number, data: {
499
+ displayName?: string;
500
+ description?: string;
501
+ priority?: number;
502
+ isActive?: boolean;
503
+ }): Promise<Role>;
504
+ /**
505
+ * Delete a role
506
+ *
507
+ * @param roleId - Role ID
508
+ * @throws Error if role is built-in or system role
509
+ *
510
+ * @example
511
+ * ```typescript
512
+ * await deleteRole(5n); // Delete custom role
513
+ * ```
514
+ */
515
+ declare function deleteRole(roleId: number): Promise<void>;
516
+ /**
517
+ * Add permission to role
518
+ *
519
+ * @param roleId - Role ID
520
+ * @param permissionId - Permission ID
521
+ *
522
+ * @example
523
+ * ```typescript
524
+ * await addPermissionToRole(1n, 5n);
525
+ * ```
526
+ */
527
+ declare function addPermissionToRole(roleId: number, permissionId: number): Promise<void>;
528
+ /**
529
+ * Remove permission from role
530
+ *
531
+ * @param roleId - Role ID
532
+ * @param permissionId - Permission ID
533
+ *
534
+ * @example
535
+ * ```typescript
536
+ * await removePermissionFromRole(1n, 5n);
537
+ * ```
538
+ */
539
+ declare function removePermissionFromRole(roleId: number, permissionId: number): Promise<void>;
540
+ /**
541
+ * Set permissions for a role (replaces all existing permissions)
542
+ *
543
+ * @param roleId - Role ID
544
+ * @param permissionIds - Array of permission IDs
545
+ *
546
+ * @example
547
+ * ```typescript
548
+ * await setRolePermissions(1n, [1n, 2n, 3n]);
549
+ * ```
550
+ */
551
+ declare function setRolePermissions(roleId: number, permissionIds: number[]): Promise<void>;
552
+ /**
553
+ * Get all roles
554
+ *
555
+ * @param includeInactive - Include inactive roles
556
+ * @returns Array of roles
557
+ *
558
+ * @example
559
+ * ```typescript
560
+ * const roles = await getAllRoles();
561
+ * ```
562
+ */
563
+ declare function getAllRoles(includeInactive?: boolean): Promise<Role[]>;
564
+ /**
565
+ * Get role by name
566
+ *
567
+ * @param name - Role name
568
+ * @returns Role or null
569
+ *
570
+ * @example
571
+ * ```typescript
572
+ * const role = await getRoleByName('admin');
573
+ * ```
574
+ */
575
+ declare function getRoleByName(name: string): Promise<Role | null>;
576
+ /**
577
+ * Get role permissions
578
+ *
579
+ * @param roleId - Role ID
580
+ * @returns Array of permission names
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * const perms = await getRolePermissions(1n);
585
+ * // ['user:read', 'user:write']
586
+ * ```
587
+ */
588
+ declare function getRolePermissions(roleId: number): Promise<string[]>;
589
+
590
+ /**
591
+ * @spfn/auth - Invitation Service
592
+ *
593
+ * User invitation management for invite-only registration
594
+ */
595
+
596
+ /**
597
+ * Create a new invitation
598
+ *
599
+ * @param params - Invitation parameters
600
+ * @returns Created invitation
601
+ * @throws Error if validation fails
602
+ *
603
+ * @example
604
+ * ```typescript
605
+ * const invitation = await createInvitation({
606
+ * email: 'newuser@example.com',
607
+ * roleId: 2n,
608
+ * invitedBy: 1n,
609
+ * expiresInDays: 7,
610
+ * metadata: { message: 'Welcome!' }
611
+ * });
612
+ * ```
613
+ */
614
+ declare function createInvitation(params: {
615
+ email: string;
616
+ roleId: number;
617
+ invitedBy: number;
618
+ expiresInDays?: number;
619
+ metadata?: Record<string, any>;
620
+ }): Promise<Invitation>;
621
+ /**
622
+ * Get invitation by token
623
+ *
624
+ * @param token - Invitation token (UUID)
625
+ * @returns Invitation or null if not found
626
+ */
627
+ declare function getInvitationByToken(token: string): Promise<Invitation | null>;
628
+ /**
629
+ * Get invitation with role and inviter details
630
+ *
631
+ * @param token - Invitation token
632
+ * @returns Invitation with joined data or null
633
+ */
634
+ declare function getInvitationWithDetails(token: string): Promise<InvitationWithDetails | null>;
635
+ /**
636
+ * Validate invitation
637
+ *
638
+ * Checks if invitation is valid for acceptance
639
+ *
640
+ * @param token - Invitation token
641
+ * @returns Validation result
642
+ */
643
+ declare function validateInvitation(token: string): Promise<{
644
+ valid: boolean;
645
+ invitation?: Invitation;
646
+ error?: string;
647
+ }>;
648
+ /**
649
+ * Accept invitation and create user account
650
+ *
651
+ * @param params - Acceptance parameters
652
+ * @returns Created user info
653
+ * @throws Error if invitation is invalid or user creation fails
654
+ *
655
+ * @example
656
+ * ```typescript
657
+ * const user = await acceptInvitation({
658
+ * token: 'uuid-v4',
659
+ * password: 'SecurePass123!',
660
+ * publicKey: 'base64-der...',
661
+ * keyId: 'uuid-v4',
662
+ * fingerprint: 'sha256-hex',
663
+ * algorithm: 'ES256'
664
+ * });
665
+ * ```
666
+ */
667
+ declare function acceptInvitation(params: {
668
+ token: string;
669
+ password: string;
670
+ publicKey: string;
671
+ keyId: string;
672
+ fingerprint: string;
673
+ algorithm: 'ES256' | 'RS256';
674
+ }): Promise<{
675
+ userId: number;
676
+ email: string;
677
+ role: string;
678
+ }>;
679
+ /**
680
+ * List invitations with filtering and pagination
681
+ *
682
+ * @param params - Query parameters
683
+ * @returns Paginated invitations
684
+ *
685
+ * @example
686
+ * ```typescript
687
+ * const result = await listInvitations({
688
+ * status: 'pending',
689
+ * invitedBy: 1n,
690
+ * page: 1,
691
+ * limit: 20
692
+ * });
693
+ * ```
694
+ */
695
+ declare function listInvitations(params: {
696
+ status?: InvitationStatus;
697
+ invitedBy?: number;
698
+ page?: number;
699
+ limit?: number;
700
+ }): Promise<{
701
+ invitations: InvitationWithDetails[];
702
+ total: number;
703
+ page: number;
704
+ limit: number;
705
+ totalPages: number;
706
+ }>;
707
+ /**
708
+ * Cancel invitation
709
+ *
710
+ * Only pending invitations can be cancelled
711
+ *
712
+ * @param id - Invitation ID
713
+ * @param cancelledBy - User ID who cancelled
714
+ * @param reason - Optional cancellation reason
715
+ * @throws Error if invitation cannot be cancelled
716
+ */
717
+ declare function cancelInvitation(id: number, cancelledBy: number, reason?: string): Promise<void>;
718
+ /**
719
+ * Delete invitation
720
+ *
721
+ * Permanently removes invitation record
722
+ * Typically only for superadmin cleanup
723
+ *
724
+ * @param id - Invitation ID
725
+ */
726
+ declare function deleteInvitation(id: number): Promise<void>;
727
+ /**
728
+ * Expire old invitations (cron job)
729
+ *
730
+ * Updates status of expired pending invitations
731
+ *
732
+ * @returns Number of invitations expired
733
+ */
734
+ declare function expireOldInvitations(): Promise<number>;
735
+ /**
736
+ * Resend invitation email
737
+ *
738
+ * Extends expiration and triggers email resend
739
+ *
740
+ * @param id - Invitation ID
741
+ * @param expiresInDays - New expiration period (default: 7)
742
+ * @returns Updated invitation
743
+ * @throws Error if invitation cannot be resent
744
+ */
745
+ declare function resendInvitation(id: number, expiresInDays?: number): Promise<Invitation>;
746
+
747
+ /**
748
+ * @spfn/auth - Password Helpers
749
+ *
750
+ * Password hashing and verification using bcrypt
751
+ *
752
+ * Security:
753
+ * - Adaptive hashing (configurable rounds)
754
+ * - Automatic salt generation (per-password)
755
+ * - Constant-time comparison (timing attack protection)
756
+ * - Rainbow table protection
757
+ */
758
+ /**
759
+ * Hash a plain text password using bcrypt
760
+ *
761
+ * Algorithm:
762
+ * 1. Generate random salt (128-bit)
763
+ * 2. Apply bcrypt key derivation (2^rounds iterations)
764
+ * 3. Return $2b$rounds$[salt][hash] (60 chars)
765
+ *
766
+ * @param password - Plain text password to hash
767
+ * @returns Bcrypt hash string (includes salt)
768
+ * @throws Error if password is empty or invalid
769
+ *
770
+ * @example
771
+ * ```typescript
772
+ * const hash = await hashPassword('mySecurePassword123');
773
+ * // Returns: "$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
774
+ * ```
775
+ */
776
+ declare function hashPassword(password: string): Promise<string>;
777
+ /**
778
+ * Verify a password against a bcrypt hash
779
+ *
780
+ * Uses constant-time comparison to prevent timing attacks
781
+ * Automatically extracts salt from hash for verification
782
+ *
783
+ * @param password - Plain text password to verify
784
+ * @param hash - Bcrypt hash string (from hashPassword)
785
+ * @returns True if password matches hash
786
+ * @throws Error if inputs are invalid
787
+ *
788
+ * @example
789
+ * ```typescript
790
+ * const isValid = await verifyPassword(
791
+ * 'mySecurePassword123',
792
+ * '$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy'
793
+ * );
794
+ * // Returns: true
795
+ * ```
796
+ */
797
+ declare function verifyPassword(password: string, hash: string): Promise<boolean>;
798
+ /**
799
+ * Validate password strength
800
+ *
801
+ * Requirements:
802
+ * - Minimum 8 characters
803
+ * - At least one uppercase letter
804
+ * - At least one lowercase letter
805
+ * - At least one number
806
+ * - At least one special character
807
+ *
808
+ * @param password - Password to validate
809
+ * @returns Validation result with error messages
810
+ *
811
+ * @example
812
+ * ```typescript
813
+ * const result = validatePasswordStrength('weak');
814
+ * // Returns: { valid: false, errors: ['Too short', 'Missing uppercase', ...] }
815
+ *
816
+ * const result = validatePasswordStrength('SecurePass123!');
817
+ * // Returns: { valid: true, errors: [] }
818
+ * ```
819
+ */
820
+ declare function validatePasswordStrength(password: string): {
821
+ valid: boolean;
822
+ errors: string[];
823
+ };
824
+
825
+ /**
826
+ * @spfn/auth - JWT Helpers
827
+ *
828
+ * JWT token generation and verification
829
+ * Supports both server-signed (legacy) and client-signed (asymmetric) tokens
830
+ *
831
+ * Architecture:
832
+ * - Legacy: Server signs/verifies with SPFN_AUTH_JWT_SECRET (symmetric HMAC)
833
+ * - New: Client signs with privateKey, server verifies with publicKey (asymmetric)
834
+ */
835
+
836
+ interface TokenPayload extends SessionPayload {
837
+ exp?: number;
838
+ iat?: number;
839
+ iss?: string;
840
+ keyId?: string;
841
+ timestamp?: number;
842
+ [key: string]: any;
843
+ }
844
+ /**
845
+ * Generate a JWT token (legacy server-signed)
846
+ *
847
+ * @deprecated Use client-side signing with private keys instead
848
+ * This method uses symmetric HMAC which requires sharing the secret
849
+ *
850
+ * @param payload - Token payload
851
+ * @returns JWT token string
852
+ */
853
+ declare function generateToken(payload: SessionPayload): string;
854
+ /**
855
+ * Verify and decode a JWT token (legacy server-signed)
856
+ *
857
+ * @deprecated Use verifyClientToken for client-signed tokens
858
+ * This method uses symmetric HMAC verification
859
+ *
860
+ * @param token - JWT token to verify
861
+ * @returns Decoded payload
862
+ * @throws Error if verification fails
863
+ */
864
+ declare function verifyToken(token: string): TokenPayload;
865
+ /**
866
+ * Verify client-signed JWT token with public key (DER format)
867
+ *
868
+ * Flow:
869
+ * 1. Decode Base64 DER to Buffer
870
+ * 2. Create KeyObject from DER
871
+ * 3. Verify JWT signature with public key
872
+ * 4. Validate issuer claim
873
+ *
874
+ * @param token - JWT token signed by client's private key
875
+ * @param publicKeyB64 - Base64 encoded DER public key (SPKI format)
876
+ * @param algorithm - Algorithm used for signing (ES256 or RS256)
877
+ * @returns Decoded token payload
878
+ * @throws Error if verification fails
879
+ *
880
+ * @example
881
+ * ```typescript
882
+ * const payload = verifyClientToken(
883
+ * token,
884
+ * 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...',
885
+ * 'ES256'
886
+ * );
887
+ * ```
888
+ */
889
+ declare function verifyClientToken(token: string, publicKeyB64: string, algorithm: 'ES256' | 'RS256'): TokenPayload;
890
+ /**
891
+ * Decode a JWT token without verification (for debugging)
892
+ *
893
+ * WARNING: Does not verify signature! Only use for debugging/logging.
894
+ * Never trust decoded data without verification.
895
+ *
896
+ * @param token - JWT token to decode
897
+ * @returns Decoded payload or null if invalid
898
+ */
899
+ declare function decodeToken(token: string): TokenPayload | null;
900
+ /**
901
+ * Verify public key fingerprint matches
902
+ *
903
+ * Used during registration/login to ensure the public key wasn't tampered with
904
+ * during transmission.
905
+ *
906
+ * Security:
907
+ * - Client sends: publicKey + fingerprint
908
+ * - Server calculates: SHA-256(publicKey)
909
+ * - Server compares: calculated === received
910
+ *
911
+ * @param publicKeyB64 - Base64 encoded DER public key
912
+ * @param expectedFingerprint - SHA-256 hex fingerprint (64 chars)
913
+ * @returns True if fingerprint matches
914
+ *
915
+ * @example
916
+ * ```typescript
917
+ * const isValid = verifyKeyFingerprint(
918
+ * publicKey,
919
+ * 'a1b2c3d4e5f6...' // 64-char hex string
920
+ * );
921
+ * if (!isValid) {
922
+ * throw new Error('Public key fingerprint mismatch');
923
+ * }
924
+ * ```
925
+ */
926
+ declare function verifyKeyFingerprint(publicKeyB64: string, expectedFingerprint: string): boolean;
927
+
928
+ /**
929
+ * @spfn/auth - Verification Code Helpers
930
+ *
931
+ * Helper functions for email/phone verification codes
932
+ */
933
+ /**
934
+ * Verification token payload
935
+ */
936
+ interface VerificationTokenPayload {
937
+ target: string;
938
+ targetType: 'email' | 'phone';
939
+ purpose: 'registration' | 'login' | 'password_reset';
940
+ codeId: number;
941
+ }
942
+ /**
943
+ * Generate a random 6-digit verification code
944
+ *
945
+ * @returns 6-digit code as string
946
+ */
947
+ declare function generateVerificationCode(): string;
948
+ /**
949
+ * Store verification code in database
950
+ *
951
+ * @param target - Email or phone number
952
+ * @param targetType - Type of target (email or phone)
953
+ * @param code - 6-digit verification code
954
+ * @param purpose - Purpose of verification
955
+ * @returns Created verification code record
956
+ */
957
+ declare function storeVerificationCode(target: string, targetType: 'email' | 'phone', code: string, purpose: 'registration' | 'login' | 'password_reset'): Promise<{
958
+ id: number;
959
+ createdAt: Date;
960
+ updatedAt: Date;
961
+ expiresAt: Date;
962
+ target: string;
963
+ targetType: "email" | "phone";
964
+ code: string;
965
+ purpose: "registration" | "login" | "password_reset" | "email_change" | "phone_change";
966
+ usedAt: Date | null;
967
+ attempts: string;
968
+ }>;
969
+ /**
970
+ * Validate verification code
971
+ *
972
+ * @param target - Email or phone number
973
+ * @param targetType - Type of target
974
+ * @param code - 6-digit code to validate
975
+ * @param purpose - Purpose of verification
976
+ * @returns Validation result with code ID if valid
977
+ */
978
+ declare function validateVerificationCode(target: string, targetType: 'email' | 'phone', code: string, purpose: 'registration' | 'login' | 'password_reset'): Promise<{
979
+ valid: boolean;
980
+ codeId?: number;
981
+ error?: string;
982
+ }>;
983
+ /**
984
+ * Mark verification code as used
985
+ *
986
+ * @param codeId - Verification code ID
987
+ */
988
+ declare function markCodeAsUsed(codeId: number): Promise<void>;
989
+ /**
990
+ * Create verification token (JWT)
991
+ *
992
+ * @param payload - Token payload
993
+ * @returns Signed JWT token
994
+ */
995
+ declare function createVerificationToken(payload: VerificationTokenPayload): string;
996
+ /**
997
+ * Validate verification token (JWT)
998
+ *
999
+ * @param token - JWT token to validate
1000
+ * @returns Decoded payload if valid, null otherwise
1001
+ */
1002
+ declare function validateVerificationToken(token: string): VerificationTokenPayload | null;
1003
+ /**
1004
+ * Send verification code via email
1005
+ *
1006
+ * @param email - Email address
1007
+ * @param code - 6-digit verification code
1008
+ * @param purpose - Purpose of verification
1009
+ */
1010
+ declare function sendVerificationEmail(email: string, code: string, purpose: string): Promise<void>;
1011
+ /**
1012
+ * Send verification code via SMS
1013
+ *
1014
+ * @param phone - Phone number in E.164 format
1015
+ * @param code - 6-digit verification code
1016
+ * @param purpose - Purpose of verification
1017
+ */
1018
+ declare function sendVerificationSMS(phone: string, code: string, purpose: string): Promise<void>;
1019
+
1020
+ /**
1021
+ * @spfn/auth - Authentication Middleware
1022
+ *
1023
+ * Verify client-signed JWT token with public key
1024
+ *
1025
+ * Flow:
1026
+ * 1. Extract Authorization header
1027
+ * 2. Decode JWT to extract keyId
1028
+ * 3. Fetch public key from database
1029
+ * 4. Check key expiration
1030
+ * 5. Verify JWT signature with public key
1031
+ * 6. Validate user status
1032
+ * 7. Update last used timestamp
1033
+ * 8. Attach user to context
1034
+ *
1035
+ * Security Checks:
1036
+ * - Token signature verification
1037
+ * - Key expiration check
1038
+ * - User status check (active/inactive/suspended)
1039
+ * - Key revocation check (isActive flag)
1040
+ */
1041
+
1042
+ interface AuthContext {
1043
+ user: User;
1044
+ userId: string;
1045
+ keyId: string;
1046
+ }
1047
+ declare module 'hono' {
1048
+ interface ContextVariableMap {
1049
+ auth: AuthContext;
1050
+ }
1051
+ }
1052
+ /**
1053
+ * Authentication middleware
1054
+ *
1055
+ * Verifies client-signed JWT token using stored public key
1056
+ * Must be applied to routes that require authentication
1057
+ *
1058
+ * @example
1059
+ * ```typescript
1060
+ * // In route file
1061
+ * app.bind(logoutContract, [authenticate], async (c) => {
1062
+ * const auth = c.raw.get('auth'); // Get auth context
1063
+ * const { user, userId, keyId } = auth;
1064
+ * // Or access directly: c.raw.get('auth').user
1065
+ * });
1066
+ * ```
1067
+ */
1068
+ declare function authenticate(c: Context, next: Next): Promise<Response | void>;
1069
+
1070
+ /**
1071
+ * Auth Context Helpers
1072
+ *
1073
+ * Helper functions to access authenticated user data from route context
1074
+ */
1075
+
1076
+ /**
1077
+ * Get auth context from route context
1078
+ *
1079
+ * Accepts both raw Hono Context and RouteContext with raw property
1080
+ *
1081
+ * @example
1082
+ * ```typescript
1083
+ * // With RouteContext (RPC routes)
1084
+ * app.bind(logoutContract, [authenticate], async (c) => {
1085
+ * const { user, userId, keyId } = getAuth(c);
1086
+ * // Use authenticated data...
1087
+ * });
1088
+ *
1089
+ * // With raw Context (middleware)
1090
+ * const auth = getAuth(c);
1091
+ * ```
1092
+ */
1093
+ declare function getAuth(c: Context | {
1094
+ raw: Context;
1095
+ }): AuthContext;
1096
+ /**
1097
+ * Get authenticated user from route context
1098
+ *
1099
+ * @example
1100
+ * ```typescript
1101
+ * app.bind(profileContract, [authenticate], async (c) => {
1102
+ * const user = getUser(c);
1103
+ * return c.success({ email: user.email });
1104
+ * });
1105
+ * ```
1106
+ */
1107
+ declare function getUser(c: Context | {
1108
+ raw: Context;
1109
+ }): {
1110
+ id: number;
1111
+ createdAt: Date;
1112
+ updatedAt: Date;
1113
+ email: string | null;
1114
+ phone: string | null;
1115
+ passwordHash: string | null;
1116
+ passwordChangeRequired: boolean;
1117
+ roleId: number;
1118
+ status: "active" | "inactive" | "suspended";
1119
+ emailVerifiedAt: Date | null;
1120
+ phoneVerifiedAt: Date | null;
1121
+ lastLoginAt: Date | null;
1122
+ };
1123
+ /**
1124
+ * Get authenticated user ID from route context
1125
+ *
1126
+ * @example
1127
+ * ```typescript
1128
+ * app.bind(postsContract, [authenticate], async (c) => {
1129
+ * const userId = getUserId(c);
1130
+ * const posts = await findPosts({ authorId: userId });
1131
+ * });
1132
+ * ```
1133
+ */
1134
+ declare function getUserId(c: Context | {
1135
+ raw: Context;
1136
+ }): string;
1137
+ /**
1138
+ * Get current key ID from route context
1139
+ *
1140
+ * @example
1141
+ * ```typescript
1142
+ * app.bind(rotateKeyContract, [authenticate], async (c) => {
1143
+ * const oldKeyId = getKeyId(c);
1144
+ * // Revoke old key...
1145
+ * });
1146
+ * ```
1147
+ */
1148
+ declare function getKeyId(c: Context | {
1149
+ raw: Context;
1150
+ }): string;
1151
+
1152
+ /**
1153
+ * @spfn/auth - Permission Middleware
1154
+ *
1155
+ * Middleware functions for permission-based access control
1156
+ */
1157
+
1158
+ /**
1159
+ * Require user to have all specified permissions
1160
+ *
1161
+ * Must be used after authenticate middleware
1162
+ *
1163
+ * @param permissionNames - Permission names (e.g., 'user:delete', 'post:publish')
1164
+ * @returns Middleware function
1165
+ *
1166
+ * @example
1167
+ * ```typescript
1168
+ * app.bind(
1169
+ * deleteUserContract,
1170
+ * [authenticate, requirePermissions('user:delete')],
1171
+ * async (c) => {
1172
+ * // Only users with user:delete permission
1173
+ * }
1174
+ * );
1175
+ *
1176
+ * // Multiple permissions (all required)
1177
+ * app.bind(
1178
+ * publishPostContract,
1179
+ * [authenticate, requirePermissions('post:write', 'post:publish')],
1180
+ * async (c) => {
1181
+ * // Needs both permissions
1182
+ * }
1183
+ * );
1184
+ * ```
1185
+ */
1186
+ declare function requirePermissions(...permissionNames: string[]): (c: Context, next: Next) => Promise<void>;
1187
+ /**
1188
+ * Require user to have at least one of the specified permissions
1189
+ *
1190
+ * Must be used after authenticate middleware
1191
+ *
1192
+ * @param permissionNames - Permission names
1193
+ * @returns Middleware function
1194
+ *
1195
+ * @example
1196
+ * ```typescript
1197
+ * app.bind(
1198
+ * viewContentContract,
1199
+ * [authenticate, requireAnyPermission('content:read', 'admin:access')],
1200
+ * async (c) => {
1201
+ * // User has either content:read OR admin:access
1202
+ * }
1203
+ * );
1204
+ * ```
1205
+ */
1206
+ declare function requireAnyPermission(...permissionNames: string[]): (c: Context, next: Next) => Promise<void>;
1207
+
1208
+ /**
1209
+ * @spfn/auth - Role Middleware
1210
+ *
1211
+ * Middleware functions for role-based access control
1212
+ */
1213
+
1214
+ /**
1215
+ * Require user to have one of the specified roles
1216
+ *
1217
+ * Must be used after authenticate middleware
1218
+ *
1219
+ * @param roleNames - Role names (e.g., 'admin', 'superadmin')
1220
+ * @returns Middleware function
1221
+ *
1222
+ * @example
1223
+ * ```typescript
1224
+ * app.bind(
1225
+ * adminDashboardContract,
1226
+ * [authenticate, requireRole('admin', 'superadmin')],
1227
+ * async (c) => {
1228
+ * // Only admin or superadmin
1229
+ * }
1230
+ * );
1231
+ *
1232
+ * // Single role
1233
+ * app.bind(
1234
+ * systemConfigContract,
1235
+ * [authenticate, requireRole('superadmin')],
1236
+ * async (c) => {
1237
+ * // Only superadmin
1238
+ * }
1239
+ * );
1240
+ * ```
1241
+ */
1242
+ declare function requireRole(...roleNames: string[]): (c: Context, next: Next) => Promise<void>;
1243
+
1244
+ /**
1245
+ * @spfn/auth - Setup Functions
1246
+ *
1247
+ * Initial setup and admin account creation
1248
+ */
1249
+ /**
1250
+ * Ensure admin accounts exist from environment variables
1251
+ *
1252
+ * Supports multiple admin account creation via three formats:
1253
+ * 1. JSON format (SPFN_AUTH_ADMIN_ACCOUNTS)
1254
+ * 2. Comma-separated format (SPFN_AUTH_ADMIN_EMAILS + SPFN_AUTH_ADMIN_PASSWORDS + SPFN_AUTH_ADMIN_ROLES)
1255
+ * 3. Single account format (SPFN_AUTH_ADMIN_EMAIL + SPFN_AUTH_ADMIN_PASSWORD) - legacy
1256
+ *
1257
+ * Default behavior for created accounts:
1258
+ * - emailVerifiedAt: current timestamp (auto-verified)
1259
+ * - passwordChangeRequired: true (must change on first login)
1260
+ * - status: 'active'
1261
+ *
1262
+ * @example
1263
+ * ```typescript
1264
+ * // In your server startup code:
1265
+ * import { ensureAdminExists } from '@spfn/auth/server';
1266
+ *
1267
+ * await ensureAdminExists();
1268
+ * ```
1269
+ */
1270
+ declare function ensureAdminExists(): Promise<void>;
1271
+
1272
+ export { type AuthContext, type AuthInitOptions, BUILTIN_PERMISSIONS, BUILTIN_ROLES, BUILTIN_ROLE_PERMISSIONS, type BuiltinPermissionName, type BuiltinRoleName, type ChangePasswordParams, type CheckAccountExistsParams, type CheckAccountExistsResult, type GetMeResult, type LoginParams, type LoginResult, type LogoutParams, type PermissionConfig, type RegisterParams, type RegisterPublicKeyParams, type RegisterResult, type RevokeKeyParams, type RoleConfig, type RotateKeyParams, type RotateKeyResult, type SendVerificationCodeParams, type SendVerificationCodeResult, type TokenPayload, type VerificationTokenPayload, type VerifyCodeParams, type VerifyCodeResult, acceptInvitation, addPermissionToRole, authenticate, cancelInvitation, changePasswordService, checkAccountExistsService, createInvitation, createRole, createVerificationToken, decodeToken, deleteInvitation, deleteRole, ensureAdminExists, expireOldInvitations, generateToken, generateVerificationCode, getAllRoles, getAuth, getInvitationByToken, getInvitationWithDetails, getKeyId, getMeService, getRoleByName, getRolePermissions, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashPassword, initializeAuth, listInvitations, loginService, logoutService, markCodeAsUsed, registerPublicKeyService, registerService, removePermissionFromRole, requireAnyPermission, requirePermissions, requireRole, resendInvitation, revokeKeyService, rotateKeyService, sendVerificationCodeService, sendVerificationEmail, sendVerificationSMS, setRolePermissions, storeVerificationCode, updateLastLoginService, updateRole, updateUserService, validateInvitation, validatePasswordStrength, validateVerificationCode, validateVerificationToken, verifyClientToken, verifyCodeService, verifyKeyFingerprint, verifyPassword, verifyToken };