@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.
- package/README.md +133 -0
- package/dist/adapters/hono.d.ts +9 -0
- package/dist/adapters/hono.js +6 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/authorization-By1Xp8Za.d.ts +213 -0
- package/dist/base-BKyR8rcE.d.ts +646 -0
- package/dist/chunk-42MGHABB.js +263 -0
- package/dist/chunk-42MGHABB.js.map +1 -0
- package/dist/chunk-7GOBAL4G.js +3 -0
- package/dist/chunk-7GOBAL4G.js.map +1 -0
- package/dist/chunk-G5I3T73A.js +152 -0
- package/dist/chunk-G5I3T73A.js.map +1 -0
- package/dist/chunk-IB4WUQDZ.js +410 -0
- package/dist/chunk-IB4WUQDZ.js.map +1 -0
- package/dist/chunk-MOG4Y6I7.js +415 -0
- package/dist/chunk-MOG4Y6I7.js.map +1 -0
- package/dist/chunk-NK4TJV2W.js +295 -0
- package/dist/chunk-NK4TJV2W.js.map +1 -0
- package/dist/chunk-RHNVRCF3.js +838 -0
- package/dist/chunk-RHNVRCF3.js.map +1 -0
- package/dist/chunk-YTCPXJR5.js +570 -0
- package/dist/chunk-YTCPXJR5.js.map +1 -0
- package/dist/cloudflare-kv-L64CZKDK.js +105 -0
- package/dist/cloudflare-kv-L64CZKDK.js.map +1 -0
- package/dist/deno-kv-F55HKKP6.js +111 -0
- package/dist/deno-kv-F55HKKP6.js.map +1 -0
- package/dist/index-C3kz9XqE.d.ts +226 -0
- package/dist/index-DOGcetyD.d.ts +1041 -0
- package/dist/index.d.ts +1579 -0
- package/dist/index.js +4294 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt-manager-CH8H0kmm.d.ts +182 -0
- package/dist/providers/index.d.ts +90 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/otp/index.d.ts +3 -0
- package/dist/providers/otp/index.js +4 -0
- package/dist/providers/otp/index.js.map +1 -0
- package/dist/redis-5TIS6XCA.js +121 -0
- package/dist/redis-5TIS6XCA.js.map +1 -0
- package/dist/security/index.d.ts +301 -0
- package/dist/security/index.js +5 -0
- package/dist/security/index.js.map +1 -0
- package/dist/session/index.d.ts +117 -0
- package/dist/session/index.js +4 -0
- package/dist/session/index.js.map +1 -0
- package/dist/storage/index.d.ts +97 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types-DSjafxJ4.d.ts +193 -0
- 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 };
|