@parsrun/auth 0.1.0

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 (54) hide show
  1. package/README.md +133 -0
  2. package/dist/adapters/hono.d.ts +9 -0
  3. package/dist/adapters/hono.js +6 -0
  4. package/dist/adapters/hono.js.map +1 -0
  5. package/dist/adapters/index.d.ts +9 -0
  6. package/dist/adapters/index.js +7 -0
  7. package/dist/adapters/index.js.map +1 -0
  8. package/dist/authorization-By1Xp8Za.d.ts +213 -0
  9. package/dist/base-BKyR8rcE.d.ts +646 -0
  10. package/dist/chunk-42MGHABB.js +263 -0
  11. package/dist/chunk-42MGHABB.js.map +1 -0
  12. package/dist/chunk-7GOBAL4G.js +3 -0
  13. package/dist/chunk-7GOBAL4G.js.map +1 -0
  14. package/dist/chunk-G5I3T73A.js +152 -0
  15. package/dist/chunk-G5I3T73A.js.map +1 -0
  16. package/dist/chunk-IB4WUQDZ.js +410 -0
  17. package/dist/chunk-IB4WUQDZ.js.map +1 -0
  18. package/dist/chunk-MOG4Y6I7.js +415 -0
  19. package/dist/chunk-MOG4Y6I7.js.map +1 -0
  20. package/dist/chunk-NK4TJV2W.js +295 -0
  21. package/dist/chunk-NK4TJV2W.js.map +1 -0
  22. package/dist/chunk-RHNVRCF3.js +838 -0
  23. package/dist/chunk-RHNVRCF3.js.map +1 -0
  24. package/dist/chunk-YTCPXJR5.js +570 -0
  25. package/dist/chunk-YTCPXJR5.js.map +1 -0
  26. package/dist/cloudflare-kv-L64CZKDK.js +105 -0
  27. package/dist/cloudflare-kv-L64CZKDK.js.map +1 -0
  28. package/dist/deno-kv-F55HKKP6.js +111 -0
  29. package/dist/deno-kv-F55HKKP6.js.map +1 -0
  30. package/dist/index-C3kz9XqE.d.ts +226 -0
  31. package/dist/index-DOGcetyD.d.ts +1041 -0
  32. package/dist/index.d.ts +1579 -0
  33. package/dist/index.js +4294 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/jwt-manager-CH8H0kmm.d.ts +182 -0
  36. package/dist/providers/index.d.ts +90 -0
  37. package/dist/providers/index.js +3 -0
  38. package/dist/providers/index.js.map +1 -0
  39. package/dist/providers/otp/index.d.ts +3 -0
  40. package/dist/providers/otp/index.js +4 -0
  41. package/dist/providers/otp/index.js.map +1 -0
  42. package/dist/redis-5TIS6XCA.js +121 -0
  43. package/dist/redis-5TIS6XCA.js.map +1 -0
  44. package/dist/security/index.d.ts +301 -0
  45. package/dist/security/index.js +5 -0
  46. package/dist/security/index.js.map +1 -0
  47. package/dist/session/index.d.ts +117 -0
  48. package/dist/session/index.js +4 -0
  49. package/dist/session/index.js.map +1 -0
  50. package/dist/storage/index.d.ts +97 -0
  51. package/dist/storage/index.js +3 -0
  52. package/dist/storage/index.js.map +1 -0
  53. package/dist/types-DSjafxJ4.d.ts +193 -0
  54. package/package.json +102 -0
@@ -0,0 +1,1041 @@
1
+ import { T as TokenPair, d as JwtPayload, J as JwtManager } from './jwt-manager-CH8H0kmm.js';
2
+ import * as hono_types from 'hono/types';
3
+ import { Context, MiddlewareHandler, Hono } from 'hono';
4
+ import { K as KVStorage } from './types-DSjafxJ4.js';
5
+ import { h as AuthAdapter, u as AdapterTenant, v as AdapterMembership, l as TenantResolutionStrategy, i as ParsAuthConfig, a as ProviderInfo, r as AdapterUser, s as AdapterSession } from './base-BKyR8rcE.js';
6
+ import { R as RequestOTPInput, d as RequestOTPResult } from './index-C3kz9XqE.js';
7
+ import { f as PermissionPattern } from './authorization-By1Xp8Za.js';
8
+
9
+ /**
10
+ * Tenant Manager
11
+ * CRUD operations for tenants and memberships
12
+ */
13
+
14
+ /**
15
+ * Tenant creation input
16
+ */
17
+ interface CreateTenantInput {
18
+ /** Tenant name */
19
+ name: string;
20
+ /** URL-friendly slug (auto-generated if not provided) */
21
+ slug?: string;
22
+ /** Owner user ID */
23
+ ownerId: string;
24
+ /** Owner role name (default: 'owner') */
25
+ ownerRole?: string;
26
+ /** Initial status (default: 'active') */
27
+ status?: 'active' | 'suspended' | 'inactive';
28
+ }
29
+ /**
30
+ * Tenant update input
31
+ */
32
+ interface UpdateTenantInput {
33
+ /** Tenant name */
34
+ name?: string;
35
+ /** Status */
36
+ status?: 'active' | 'suspended' | 'inactive';
37
+ }
38
+ /**
39
+ * Membership creation input
40
+ */
41
+ interface AddMemberInput {
42
+ /** User ID to add */
43
+ userId: string;
44
+ /** Tenant ID */
45
+ tenantId: string;
46
+ /** Role name */
47
+ role: string;
48
+ /** Initial permissions */
49
+ permissions?: string[];
50
+ /** Status (default: 'active') */
51
+ status?: 'active' | 'inactive' | 'pending';
52
+ }
53
+ /**
54
+ * Membership update input
55
+ */
56
+ interface UpdateMemberInput {
57
+ /** New role */
58
+ role?: string;
59
+ /** New permissions */
60
+ permissions?: string[];
61
+ /** New status */
62
+ status?: 'active' | 'inactive' | 'pending';
63
+ }
64
+ /**
65
+ * Tenant with members
66
+ */
67
+ interface TenantWithMembers extends AdapterTenant {
68
+ members: AdapterMembership[];
69
+ memberCount: number;
70
+ }
71
+ /**
72
+ * User's tenant memberships with tenant details
73
+ */
74
+ interface UserTenantMembership extends AdapterMembership {
75
+ tenant?: AdapterTenant;
76
+ }
77
+ /**
78
+ * Tenant Manager
79
+ */
80
+ declare class TenantManager {
81
+ private adapter;
82
+ constructor(adapter: AuthAdapter);
83
+ /**
84
+ * Create a new tenant with owner
85
+ */
86
+ createTenant(input: CreateTenantInput): Promise<{
87
+ tenant: AdapterTenant;
88
+ membership: AdapterMembership;
89
+ }>;
90
+ /**
91
+ * Get tenant by ID
92
+ */
93
+ getTenantById(id: string): Promise<AdapterTenant | null>;
94
+ /**
95
+ * Get tenant by slug
96
+ */
97
+ getTenantBySlug(slug: string): Promise<AdapterTenant | null>;
98
+ /**
99
+ * Check if user is member of tenant
100
+ */
101
+ isMember(userId: string, tenantId: string): Promise<boolean>;
102
+ /**
103
+ * Check if user has specific role in tenant
104
+ */
105
+ hasRole(userId: string, tenantId: string, role: string): Promise<boolean>;
106
+ /**
107
+ * Check if user is owner of tenant
108
+ */
109
+ isOwner(userId: string, tenantId: string): Promise<boolean>;
110
+ /**
111
+ * Check if user is admin of tenant (owner or admin)
112
+ */
113
+ isAdmin(userId: string, tenantId: string): Promise<boolean>;
114
+ /**
115
+ * Add a member to tenant
116
+ */
117
+ addMember(input: AddMemberInput): Promise<AdapterMembership>;
118
+ /**
119
+ * Update member role/permissions
120
+ */
121
+ updateMember(userId: string, tenantId: string, updates: UpdateMemberInput): Promise<AdapterMembership>;
122
+ /**
123
+ * Remove member from tenant
124
+ */
125
+ removeMember(userId: string, tenantId: string): Promise<void>;
126
+ /**
127
+ * Get membership for user in tenant
128
+ */
129
+ getMembership(userId: string, tenantId: string): Promise<AdapterMembership | null>;
130
+ /**
131
+ * Get all tenants for a user
132
+ */
133
+ getUserTenants(userId: string): Promise<UserTenantMembership[]>;
134
+ /**
135
+ * Get all members of a tenant
136
+ * Note: This requires iterating through users, which is not efficient
137
+ * Consider adding findMembershipsByTenantId to the adapter
138
+ */
139
+ getMembersByTenant(_tenantId: string): Promise<AdapterMembership[]>;
140
+ /**
141
+ * Transfer ownership to another member
142
+ */
143
+ transferOwnership(tenantId: string, currentOwnerId: string, newOwnerId: string): Promise<void>;
144
+ /**
145
+ * Validate tenant switch
146
+ * Returns the tenant if switch is allowed
147
+ */
148
+ validateTenantSwitch(userId: string, targetTenantId: string): Promise<{
149
+ tenant: AdapterTenant;
150
+ membership: AdapterMembership;
151
+ }>;
152
+ /**
153
+ * Get default tenant for user
154
+ * Returns the first active tenant membership
155
+ */
156
+ getDefaultTenant(userId: string): Promise<UserTenantMembership | null>;
157
+ /**
158
+ * Generate URL-friendly slug from name
159
+ */
160
+ private generateSlug;
161
+ /**
162
+ * Generate unique tenant slug
163
+ */
164
+ generateUniqueSlug(name: string): Promise<string>;
165
+ }
166
+ /**
167
+ * Create a tenant manager
168
+ */
169
+ declare function createTenantManager(adapter: AuthAdapter): TenantManager;
170
+
171
+ /**
172
+ * Tenant Resolution
173
+ * Extracts tenant from incoming requests using configurable strategies
174
+ */
175
+
176
+ /**
177
+ * Tenant resolver configuration
178
+ */
179
+ interface TenantResolverConfig {
180
+ /** Resolution strategy */
181
+ strategy: TenantResolutionStrategy;
182
+ /** Header name for 'header' strategy (default: 'x-tenant-id') */
183
+ headerName?: string;
184
+ /** Path prefix for 'path' strategy (default: '/t/') */
185
+ pathPrefix?: string;
186
+ /** Query parameter name for 'query' strategy (default: 'tenant') */
187
+ queryParam?: string;
188
+ /** Custom resolver function for 'custom' strategy */
189
+ resolver?: (request: Request) => Promise<string | null>;
190
+ /** Fallback tenant ID when none is resolved */
191
+ fallbackTenantId?: string;
192
+ /** Whether tenant is required (default: false) */
193
+ required?: boolean;
194
+ }
195
+ /**
196
+ * Tenant resolution result
197
+ */
198
+ interface TenantResolutionResult {
199
+ /** Resolved tenant ID */
200
+ tenantId: string | null;
201
+ /** Resolution method used */
202
+ resolvedFrom: 'subdomain' | 'header' | 'path' | 'query' | 'custom' | 'fallback' | null;
203
+ /** Original value before resolution */
204
+ originalValue?: string;
205
+ }
206
+ /**
207
+ * Tenant Resolver
208
+ * Extracts tenant identifier from requests using various strategies
209
+ */
210
+ declare class TenantResolver {
211
+ private config;
212
+ constructor(config: TenantResolverConfig);
213
+ /**
214
+ * Resolve tenant from request
215
+ */
216
+ resolve(request: Request): Promise<TenantResolutionResult>;
217
+ /**
218
+ * Resolve tenant from subdomain
219
+ * e.g., acme.example.com -> 'acme'
220
+ */
221
+ private resolveFromSubdomain;
222
+ /**
223
+ * Resolve tenant from header
224
+ * e.g., X-Tenant-ID: acme
225
+ */
226
+ private resolveFromHeader;
227
+ /**
228
+ * Resolve tenant from URL path
229
+ * e.g., /t/acme/api/users -> 'acme'
230
+ */
231
+ private resolveFromPath;
232
+ /**
233
+ * Resolve tenant from query parameter
234
+ * e.g., /api/users?tenant=acme -> 'acme'
235
+ */
236
+ private resolveFromQuery;
237
+ /**
238
+ * Resolve tenant using custom resolver
239
+ */
240
+ private resolveFromCustom;
241
+ /**
242
+ * Check if tenant is required but not found
243
+ */
244
+ isRequired(): boolean;
245
+ /**
246
+ * Get the path without tenant prefix (for path strategy)
247
+ */
248
+ stripTenantFromPath(pathname: string): string;
249
+ }
250
+ /**
251
+ * Create a tenant resolver
252
+ */
253
+ declare function createTenantResolver(config: TenantResolverConfig): TenantResolver;
254
+ /**
255
+ * Multi-strategy tenant resolver
256
+ * Tries multiple strategies in order until one succeeds
257
+ */
258
+ declare class MultiStrategyTenantResolver {
259
+ private resolvers;
260
+ private fallbackTenantId?;
261
+ constructor(strategies: TenantResolverConfig[], options?: {
262
+ fallbackTenantId?: string;
263
+ });
264
+ /**
265
+ * Resolve tenant trying each strategy in order
266
+ */
267
+ resolve(request: Request): Promise<TenantResolutionResult>;
268
+ }
269
+ /**
270
+ * Create a multi-strategy tenant resolver
271
+ */
272
+ declare function createMultiStrategyResolver(strategies: TenantResolverConfig[], options?: {
273
+ fallbackTenantId?: string;
274
+ }): MultiStrategyTenantResolver;
275
+
276
+ /**
277
+ * Invitation System
278
+ * Handles tenant invitations and membership requests
279
+ */
280
+
281
+ /**
282
+ * Invitation configuration
283
+ */
284
+ interface InvitationConfig {
285
+ /** Base URL for invitation links */
286
+ baseUrl: string;
287
+ /** Invitation callback path (default: /auth/invitation) */
288
+ callbackPath?: string;
289
+ /** Token expiration in seconds (default: 604800 = 7 days) */
290
+ expiresIn?: number;
291
+ /** Token length in bytes (default: 32) */
292
+ tokenLength?: number;
293
+ }
294
+ /**
295
+ * Invitation record stored in KV
296
+ */
297
+ interface InvitationRecord {
298
+ /** Unique invitation ID */
299
+ id: string;
300
+ /** Invited email address */
301
+ email: string;
302
+ /** Target tenant ID */
303
+ tenantId: string;
304
+ /** Role to assign */
305
+ role: string;
306
+ /** Permissions to assign */
307
+ permissions?: string[];
308
+ /** Who sent the invitation */
309
+ invitedBy: string;
310
+ /** Token hash for verification */
311
+ tokenHash: string;
312
+ /** Expiration timestamp */
313
+ expiresAt: string;
314
+ /** Status */
315
+ status: 'pending' | 'accepted' | 'expired' | 'cancelled';
316
+ /** When invitation was accepted */
317
+ acceptedAt?: string;
318
+ /** User ID who accepted (if different from invited email) */
319
+ acceptedBy?: string;
320
+ /** Created timestamp */
321
+ createdAt: string;
322
+ /** Custom message */
323
+ message?: string;
324
+ }
325
+ /**
326
+ * Send invitation input
327
+ */
328
+ interface SendInvitationInput {
329
+ /** Email to invite */
330
+ email: string;
331
+ /** Tenant ID */
332
+ tenantId: string;
333
+ /** Role to assign */
334
+ role: string;
335
+ /** Permissions to assign */
336
+ permissions?: string[];
337
+ /** User ID sending the invitation */
338
+ invitedBy: string;
339
+ /** Optional message to include */
340
+ message?: string;
341
+ }
342
+ /**
343
+ * Send invitation result
344
+ */
345
+ interface SendInvitationResult {
346
+ success: boolean;
347
+ invitation?: InvitationRecord;
348
+ invitationUrl?: string;
349
+ token?: string;
350
+ error?: string;
351
+ }
352
+ /**
353
+ * Accept invitation input
354
+ */
355
+ interface AcceptInvitationInput {
356
+ /** Invitation token */
357
+ token: string;
358
+ /** User ID accepting the invitation */
359
+ userId: string;
360
+ }
361
+ /**
362
+ * Accept invitation result
363
+ */
364
+ interface AcceptInvitationResult {
365
+ success: boolean;
366
+ membership?: AdapterMembership;
367
+ tenant?: AdapterTenant;
368
+ error?: string;
369
+ }
370
+ /**
371
+ * Invitation status check result
372
+ */
373
+ interface InvitationStatusResult {
374
+ valid: boolean;
375
+ invitation?: InvitationRecord;
376
+ tenant?: AdapterTenant;
377
+ error?: string;
378
+ }
379
+ /**
380
+ * Invitation Service
381
+ */
382
+ declare class InvitationService {
383
+ private storage;
384
+ private adapter;
385
+ private config;
386
+ constructor(storage: KVStorage, adapter: AuthAdapter, config: InvitationConfig);
387
+ /**
388
+ * Send an invitation to join a tenant
389
+ */
390
+ sendInvitation(input: SendInvitationInput): Promise<SendInvitationResult>;
391
+ /**
392
+ * Accept an invitation
393
+ */
394
+ acceptInvitation(input: AcceptInvitationInput): Promise<AcceptInvitationResult>;
395
+ /**
396
+ * Check invitation status
397
+ */
398
+ checkInvitation(token: string): Promise<InvitationStatusResult>;
399
+ /**
400
+ * Cancel an invitation
401
+ */
402
+ cancelInvitation(invitationId: string): Promise<boolean>;
403
+ /**
404
+ * Get invitation by ID
405
+ */
406
+ getInvitationById(id: string): Promise<InvitationRecord | null>;
407
+ /**
408
+ * Get invitation by email and tenant
409
+ */
410
+ getInvitationByEmail(email: string, tenantId: string): Promise<InvitationRecord | null>;
411
+ /**
412
+ * Resend invitation (generates new token)
413
+ */
414
+ resendInvitation(invitationId: string, invitedBy: string): Promise<SendInvitationResult>;
415
+ /**
416
+ * Get pending invitations for a tenant
417
+ * Note: This requires listing keys which may not be efficient for all storage backends
418
+ */
419
+ getPendingInvitations(_tenantId: string): Promise<InvitationRecord[]>;
420
+ /**
421
+ * Update invitation record
422
+ */
423
+ private updateInvitation;
424
+ }
425
+ /**
426
+ * Create invitation service
427
+ */
428
+ declare function createInvitationService(storage: KVStorage, adapter: AuthAdapter, config: InvitationConfig): InvitationService;
429
+
430
+ /**
431
+ * Pars Auth Engine
432
+ * Main orchestrator for authentication
433
+ */
434
+
435
+ /**
436
+ * Auth context passed to handlers
437
+ */
438
+ interface AuthContext$1 {
439
+ userId?: string;
440
+ sessionId?: string;
441
+ tenantId?: string;
442
+ payload?: JwtPayload;
443
+ }
444
+ /**
445
+ * Sign in input
446
+ */
447
+ interface SignInInput {
448
+ /** Provider name (e.g., 'otp', 'password', 'google') */
449
+ provider: string;
450
+ /** Identifier (email, phone, etc.) */
451
+ identifier: string;
452
+ /** Credential (OTP code, password, etc.) */
453
+ credential?: string;
454
+ /** Provider-specific data */
455
+ data?: Record<string, unknown>;
456
+ /** Request metadata */
457
+ metadata?: {
458
+ ipAddress?: string;
459
+ userAgent?: string;
460
+ deviceType?: string;
461
+ deviceName?: string;
462
+ tenantId?: string;
463
+ };
464
+ }
465
+ /**
466
+ * Sign in result
467
+ */
468
+ interface SignInResult {
469
+ success: boolean;
470
+ user?: AdapterUser;
471
+ session?: AdapterSession;
472
+ tokens?: TokenPair;
473
+ requiresTwoFactor?: boolean;
474
+ twoFactorChallengeId?: string;
475
+ error?: string;
476
+ errorCode?: string;
477
+ }
478
+ /**
479
+ * Sign up input
480
+ */
481
+ interface SignUpInput {
482
+ /** Email address */
483
+ email?: string;
484
+ /** Phone number */
485
+ phone?: string;
486
+ /** Display name */
487
+ name?: string;
488
+ /** Avatar URL */
489
+ avatar?: string;
490
+ /** Request metadata */
491
+ metadata?: {
492
+ ipAddress?: string;
493
+ userAgent?: string;
494
+ tenantId?: string;
495
+ };
496
+ }
497
+ /**
498
+ * Sign up result
499
+ */
500
+ interface SignUpResult {
501
+ success: boolean;
502
+ user?: AdapterUser;
503
+ session?: AdapterSession;
504
+ tokens?: TokenPair;
505
+ requiresVerification?: boolean;
506
+ error?: string;
507
+ errorCode?: string;
508
+ }
509
+ /**
510
+ * Verify token result
511
+ */
512
+ interface VerifyTokenResult {
513
+ valid: boolean;
514
+ payload?: JwtPayload;
515
+ error?: string;
516
+ }
517
+ /**
518
+ * Refresh token result
519
+ */
520
+ interface RefreshTokenResult {
521
+ success: boolean;
522
+ tokens?: TokenPair;
523
+ error?: string;
524
+ }
525
+ /**
526
+ * Session info
527
+ */
528
+ interface SessionInfo {
529
+ id: string;
530
+ userId: string;
531
+ tenantId?: string;
532
+ deviceType?: string;
533
+ deviceName?: string;
534
+ ipAddress?: string;
535
+ createdAt: Date;
536
+ expiresAt: Date;
537
+ isCurrent: boolean;
538
+ }
539
+ /**
540
+ * Pars Auth Engine
541
+ */
542
+ declare class ParsAuthEngine {
543
+ private config;
544
+ private storage;
545
+ private providers;
546
+ private jwtManager;
547
+ private sessionBlocklist;
548
+ private adapter;
549
+ private callbacks;
550
+ private initialized;
551
+ private tenantManager;
552
+ private tenantResolver?;
553
+ private invitationService?;
554
+ constructor(config: ParsAuthConfig);
555
+ /**
556
+ * Initialize the auth engine (async operations)
557
+ * Must be called before using the engine
558
+ */
559
+ initialize(): Promise<void>;
560
+ /**
561
+ * Ensure engine is initialized
562
+ */
563
+ private ensureInitialized;
564
+ /**
565
+ * Get all registered providers
566
+ */
567
+ getProviders(): ProviderInfo[];
568
+ /**
569
+ * Check if a provider is enabled
570
+ */
571
+ isProviderEnabled(name: string): boolean;
572
+ /**
573
+ * Request OTP (for OTP provider)
574
+ */
575
+ requestOTP(input: RequestOTPInput): Promise<RequestOTPResult>;
576
+ /**
577
+ * Sign in with any provider
578
+ */
579
+ signIn(input: SignInInput): Promise<SignInResult>;
580
+ /**
581
+ * Sign up a new user
582
+ */
583
+ signUp(input: SignUpInput): Promise<SignUpResult>;
584
+ /**
585
+ * Sign out (revoke session)
586
+ */
587
+ signOut(sessionId: string, options?: {
588
+ revokeAll?: boolean;
589
+ userId?: string;
590
+ }): Promise<void>;
591
+ /**
592
+ * Verify access token
593
+ */
594
+ verifyAccessToken(token: string): Promise<VerifyTokenResult>;
595
+ /**
596
+ * Refresh tokens
597
+ */
598
+ refreshTokens(refreshToken: string): Promise<RefreshTokenResult>;
599
+ /**
600
+ * Get user sessions
601
+ */
602
+ getSessions(userId: string, currentSessionId?: string): Promise<SessionInfo[]>;
603
+ /**
604
+ * Revoke a specific session
605
+ */
606
+ revokeSession(sessionId: string): Promise<void>;
607
+ /**
608
+ * Revoke all sessions for a user
609
+ */
610
+ revokeAllSessions(userId: string): Promise<void>;
611
+ /**
612
+ * Get the underlying storage instance
613
+ */
614
+ getStorage(): KVStorage;
615
+ /**
616
+ * Get the JWT manager
617
+ */
618
+ getJwtManager(): JwtManager;
619
+ /**
620
+ * Get the database adapter
621
+ */
622
+ getAdapter(): AuthAdapter;
623
+ /**
624
+ * Get configuration
625
+ */
626
+ getConfig(): Required<ParsAuthConfig>;
627
+ /**
628
+ * Find user by identifier based on provider
629
+ */
630
+ private findUserByIdentifier;
631
+ /**
632
+ * Create a new session
633
+ */
634
+ private createSession;
635
+ /**
636
+ * Resolve tenant from request
637
+ */
638
+ resolveTenant(request: Request): Promise<TenantResolutionResult>;
639
+ /**
640
+ * Switch current session to a different tenant
641
+ */
642
+ switchTenant(sessionId: string, targetTenantId: string): Promise<{
643
+ success: boolean;
644
+ tokens?: TokenPair;
645
+ error?: string;
646
+ }>;
647
+ /**
648
+ * Get all tenants for current user
649
+ */
650
+ getUserTenants(userId: string): Promise<Array<{
651
+ tenant: AdapterTenant;
652
+ membership: AdapterMembership;
653
+ }>>;
654
+ /**
655
+ * Check if user is member of tenant
656
+ */
657
+ isTenantMember(userId: string, tenantId: string): Promise<boolean>;
658
+ /**
659
+ * Check if user has role in tenant
660
+ */
661
+ hasRoleInTenant(userId: string, tenantId: string, role: string): Promise<boolean>;
662
+ /**
663
+ * Get user's membership in a tenant
664
+ */
665
+ getTenantMembership(userId: string, tenantId: string): Promise<AdapterMembership | null>;
666
+ /**
667
+ * Add member to tenant
668
+ */
669
+ addTenantMember(input: {
670
+ userId: string;
671
+ tenantId: string;
672
+ role: string;
673
+ permissions?: string[];
674
+ }): Promise<AdapterMembership>;
675
+ /**
676
+ * Update member's role/permissions in tenant
677
+ */
678
+ updateTenantMember(userId: string, tenantId: string, updates: {
679
+ role?: string;
680
+ permissions?: string[];
681
+ status?: 'active' | 'inactive';
682
+ }): Promise<AdapterMembership>;
683
+ /**
684
+ * Remove member from tenant
685
+ */
686
+ removeTenantMember(userId: string, tenantId: string): Promise<void>;
687
+ /**
688
+ * Send invitation to join tenant
689
+ */
690
+ inviteToTenant(input: {
691
+ email: string;
692
+ tenantId: string;
693
+ role: string;
694
+ permissions?: string[];
695
+ invitedBy: string;
696
+ message?: string;
697
+ }): Promise<SendInvitationResult>;
698
+ /**
699
+ * Accept an invitation
700
+ */
701
+ acceptInvitation(token: string, userId: string): Promise<AcceptInvitationResult>;
702
+ /**
703
+ * Check invitation status
704
+ */
705
+ checkInvitation(token: string): Promise<{
706
+ valid: boolean;
707
+ tenantName?: string;
708
+ role?: string;
709
+ email?: string;
710
+ error?: string;
711
+ }>;
712
+ /**
713
+ * Get tenant manager instance
714
+ */
715
+ getTenantManager(): TenantManager;
716
+ /**
717
+ * Get invitation service instance
718
+ */
719
+ getInvitationService(): InvitationService | undefined;
720
+ /**
721
+ * Get tenant resolver instance
722
+ */
723
+ getTenantResolver(): TenantResolver | undefined;
724
+ }
725
+
726
+ /**
727
+ * Adapter Types
728
+ * Common interfaces for framework adapters
729
+ */
730
+
731
+ /**
732
+ * Auth context attached to requests
733
+ */
734
+ interface AuthContext {
735
+ /** Authenticated user ID */
736
+ userId: string;
737
+ /** Session ID */
738
+ sessionId?: string;
739
+ /** Tenant ID (for multi-tenant) */
740
+ tenantId?: string;
741
+ /** User roles */
742
+ roles?: string[];
743
+ /** User permissions */
744
+ permissions?: string[];
745
+ /** Full JWT payload */
746
+ payload: JwtPayload;
747
+ }
748
+ /**
749
+ * Cookie options
750
+ */
751
+ interface CookieOptions {
752
+ /** Cookie name */
753
+ name: string;
754
+ /** Cookie value */
755
+ value: string;
756
+ /** Max age in seconds */
757
+ maxAge?: number;
758
+ /** Expiration date */
759
+ expires?: Date;
760
+ /** Path */
761
+ path?: string;
762
+ /** Domain */
763
+ domain?: string;
764
+ /** Secure flag */
765
+ secure?: boolean;
766
+ /** HttpOnly flag */
767
+ httpOnly?: boolean;
768
+ /** SameSite attribute */
769
+ sameSite?: 'strict' | 'lax' | 'none';
770
+ }
771
+ /**
772
+ * Auth response with cookies
773
+ */
774
+ interface AuthResponse {
775
+ success: boolean;
776
+ tokens?: TokenPair;
777
+ cookies?: CookieOptions[];
778
+ error?: string;
779
+ errorCode?: string;
780
+ user?: {
781
+ id: string;
782
+ email?: string;
783
+ name?: string;
784
+ };
785
+ }
786
+ /**
787
+ * Request OTP input
788
+ */
789
+ interface RequestOtpBody {
790
+ identifier: string;
791
+ type: 'email' | 'sms';
792
+ }
793
+ /**
794
+ * Verify OTP input
795
+ */
796
+ interface VerifyOtpBody {
797
+ identifier: string;
798
+ code: string;
799
+ type?: 'email' | 'sms';
800
+ }
801
+ /**
802
+ * Sign in input
803
+ */
804
+ interface SignInBody {
805
+ provider: string;
806
+ identifier: string;
807
+ credential?: string;
808
+ data?: Record<string, unknown>;
809
+ }
810
+ /**
811
+ * Refresh token input
812
+ */
813
+ interface RefreshBody {
814
+ refreshToken?: string;
815
+ }
816
+ /**
817
+ * Create auth cookies from token pair
818
+ */
819
+ declare function createAuthCookies(tokens: TokenPair, config: {
820
+ prefix?: string;
821
+ path?: string;
822
+ domain?: string;
823
+ secure?: boolean;
824
+ sameSite?: 'strict' | 'lax' | 'none';
825
+ httpOnly?: boolean;
826
+ }): CookieOptions[];
827
+ /**
828
+ * Create logout cookies (clear auth cookies)
829
+ */
830
+ declare function createLogoutCookies(config: {
831
+ prefix?: string;
832
+ path?: string;
833
+ domain?: string;
834
+ }): CookieOptions[];
835
+
836
+ /**
837
+ * Hono auth context variables
838
+ */
839
+ interface AuthVariables {
840
+ auth: AuthContext;
841
+ }
842
+ /**
843
+ * Hono adapter configuration
844
+ */
845
+ interface HonoAdapterConfig {
846
+ /** Auth engine instance */
847
+ auth: ParsAuthEngine;
848
+ /** Cookie configuration */
849
+ cookies?: {
850
+ prefix?: string;
851
+ path?: string;
852
+ domain?: string;
853
+ secure?: boolean;
854
+ sameSite?: 'strict' | 'lax' | 'none';
855
+ httpOnly?: boolean;
856
+ };
857
+ /** Custom error handler */
858
+ onError?: (error: Error, c: Context) => Response | Promise<Response>;
859
+ /** Custom unauthorized handler */
860
+ onUnauthorized?: (c: Context, message?: string) => Response | Promise<Response>;
861
+ }
862
+ /**
863
+ * Create Hono auth middleware
864
+ * Validates JWT and attaches auth context to request
865
+ */
866
+ declare function createAuthMiddleware(config: HonoAdapterConfig): MiddlewareHandler<{
867
+ Variables: AuthVariables;
868
+ }>;
869
+ /**
870
+ * Create optional auth middleware
871
+ * Attaches auth context if token is valid, but doesn't block if not
872
+ */
873
+ declare function createOptionalAuthMiddleware(config: HonoAdapterConfig): MiddlewareHandler<{
874
+ Variables: Partial<AuthVariables>;
875
+ }>;
876
+ /**
877
+ * Create auth routes
878
+ * Provides standard auth endpoints: /otp/request, /otp/verify, /sign-in, /sign-out, /refresh
879
+ */
880
+ declare function createAuthRoutes<E extends {
881
+ Variables: Partial<AuthVariables>;
882
+ }>(app: Hono<E>, config: HonoAdapterConfig): Hono<E>;
883
+ /**
884
+ * Create complete Hono auth integration
885
+ */
886
+ declare function createHonoAuth(config: HonoAdapterConfig): {
887
+ /** Auth middleware (requires authentication) */
888
+ middleware: MiddlewareHandler<{
889
+ Variables: AuthVariables;
890
+ }>;
891
+ /** Optional auth middleware (attaches auth if present) */
892
+ optionalMiddleware: MiddlewareHandler<{
893
+ Variables: Partial<AuthVariables>;
894
+ }>;
895
+ /** Create auth routes on an app */
896
+ createRoutes: <E extends {
897
+ Variables: Partial<AuthVariables>;
898
+ }>(app: Hono<E>) => Hono<E, hono_types.BlankSchema, "/">;
899
+ };
900
+ /**
901
+ * Require specific role(s)
902
+ * Use after createAuthMiddleware
903
+ *
904
+ * @example
905
+ * ```ts
906
+ * app.get('/admin', authMiddleware, requireRole('admin'), handler);
907
+ * app.get('/managers', authMiddleware, requireRole('admin', 'manager'), handler);
908
+ * ```
909
+ */
910
+ declare function requireRole(...allowedRoles: string[]): MiddlewareHandler<{
911
+ Variables: AuthVariables;
912
+ }>;
913
+ /**
914
+ * Require specific permission(s)
915
+ * Supports wildcards: 'users:*', '*:read', '*'
916
+ *
917
+ * @example
918
+ * ```ts
919
+ * app.get('/users', authMiddleware, requirePermission('users:read'), handler);
920
+ * app.delete('/users/:id', authMiddleware, requirePermission('users:delete'), handler);
921
+ * ```
922
+ */
923
+ declare function requirePermission(...permissions: PermissionPattern[]): MiddlewareHandler<{
924
+ Variables: AuthVariables;
925
+ }>;
926
+ /**
927
+ * Require any of the specified permissions
928
+ * User only needs one of the permissions
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * app.get('/content', authMiddleware, requireAnyPermission('content:read', 'content:admin'), handler);
933
+ * ```
934
+ */
935
+ declare function requireAnyPermission(...permissions: PermissionPattern[]): MiddlewareHandler<{
936
+ Variables: AuthVariables;
937
+ }>;
938
+ /**
939
+ * Require tenant context
940
+ * Ensures user has an active tenant selected
941
+ *
942
+ * @example
943
+ * ```ts
944
+ * app.use('/api/tenant/*', authMiddleware, requireTenant());
945
+ * ```
946
+ */
947
+ declare function requireTenant(): MiddlewareHandler<{
948
+ Variables: AuthVariables;
949
+ }>;
950
+ /**
951
+ * Require access to specific tenant
952
+ * Validates that user can access the tenant specified in the request
953
+ *
954
+ * @example
955
+ * ```ts
956
+ * // Check tenant from URL param
957
+ * app.get('/tenants/:tenantId/*', authMiddleware, requireTenantAccess(c => c.req.param('tenantId')), handler);
958
+ *
959
+ * // Check tenant from header
960
+ * app.use('/api/*', authMiddleware, requireTenantAccess(c => c.req.header('x-tenant-id')), handler);
961
+ * ```
962
+ */
963
+ declare function requireTenantAccess(getTenantId: (c: Context) => string | undefined, options?: {
964
+ /** Roles that can access any tenant (e.g., ['super_admin']) */
965
+ bypassRoles?: string[];
966
+ }): MiddlewareHandler<{
967
+ Variables: AuthVariables;
968
+ }>;
969
+ /**
970
+ * Require admin access
971
+ * Checks for 'admin' or 'owner' role, or '*' permission
972
+ *
973
+ * @example
974
+ * ```ts
975
+ * app.use('/admin/*', authMiddleware, requireAdmin(), handler);
976
+ * ```
977
+ */
978
+ declare function requireAdmin(): MiddlewareHandler<{
979
+ Variables: AuthVariables;
980
+ }>;
981
+ /**
982
+ * Require resource ownership or permission
983
+ * Allows access if user owns the resource OR has the specified permission
984
+ *
985
+ * @example
986
+ * ```ts
987
+ * app.put('/posts/:id', authMiddleware, requireOwnerOrPermission(
988
+ * async (c) => (await getPost(c.req.param('id'))).authorId,
989
+ * 'posts:edit'
990
+ * ), handler);
991
+ * ```
992
+ */
993
+ declare function requireOwnerOrPermission(getOwnerId: (c: Context) => string | Promise<string>, permission: PermissionPattern): MiddlewareHandler<{
994
+ Variables: AuthVariables;
995
+ }>;
996
+ /**
997
+ * Combine multiple authorization requirements
998
+ * All requirements must pass
999
+ *
1000
+ * @example
1001
+ * ```ts
1002
+ * app.delete('/projects/:id',
1003
+ * authMiddleware,
1004
+ * requireAll(
1005
+ * requireTenant(),
1006
+ * requireRole('admin', 'manager'),
1007
+ * requirePermission('projects:delete')
1008
+ * ),
1009
+ * handler
1010
+ * );
1011
+ * ```
1012
+ */
1013
+ declare function requireAll(...middlewares: MiddlewareHandler<{
1014
+ Variables: AuthVariables;
1015
+ }>[]): MiddlewareHandler<{
1016
+ Variables: AuthVariables;
1017
+ }>;
1018
+ /**
1019
+ * Combine multiple authorization requirements
1020
+ * At least one requirement must pass
1021
+ *
1022
+ * @example
1023
+ * ```ts
1024
+ * app.get('/content/:id',
1025
+ * authMiddleware,
1026
+ * requireAny(
1027
+ * requireRole('admin'),
1028
+ * requirePermission('content:read'),
1029
+ * requireOwnerOrPermission(getContentOwnerId, 'content:view-own')
1030
+ * ),
1031
+ * handler
1032
+ * );
1033
+ * ```
1034
+ */
1035
+ declare function requireAny(...middlewares: MiddlewareHandler<{
1036
+ Variables: AuthVariables;
1037
+ }>[]): MiddlewareHandler<{
1038
+ Variables: AuthVariables;
1039
+ }>;
1040
+
1041
+ export { type VerifyOtpBody as $, type AuthContext$1 as A, createAuthCookies as B, type CreateTenantInput as C, createLogoutCookies as D, requireRole as E, requirePermission as F, requireAnyPermission as G, requireTenant as H, InvitationService as I, requireTenantAccess as J, requireAdmin as K, requireOwnerOrPermission as L, MultiStrategyTenantResolver as M, requireAll as N, requireAny as O, ParsAuthEngine as P, type AuthVariables as Q, type RefreshTokenResult as R, type SignInInput as S, TenantResolver as T, type UpdateTenantInput as U, type VerifyTokenResult as V, type HonoAdapterConfig as W, type AuthContext as X, type CookieOptions as Y, type AuthResponse as Z, type RequestOtpBody as _, type SignInResult as a, type SignInBody as a0, type RefreshBody as a1, type SignUpInput as b, type SignUpResult as c, type SessionInfo as d, createTenantResolver as e, createMultiStrategyResolver as f, type TenantResolverConfig as g, type TenantResolutionResult as h, TenantManager as i, createTenantManager as j, type AddMemberInput as k, type UpdateMemberInput as l, type TenantWithMembers as m, type UserTenantMembership as n, createInvitationService as o, type InvitationConfig as p, type InvitationRecord as q, type SendInvitationInput as r, type SendInvitationResult as s, type AcceptInvitationInput as t, type AcceptInvitationResult as u, type InvitationStatusResult as v, createAuthMiddleware as w, createOptionalAuthMiddleware as x, createAuthRoutes as y, createHonoAuth as z };