@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,295 @@
|
|
|
1
|
+
// src/security/authorization.ts
|
|
2
|
+
var AuthorizationGuard = class {
|
|
3
|
+
context;
|
|
4
|
+
constructor(context) {
|
|
5
|
+
this.context = context;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Check if user is authenticated
|
|
9
|
+
*/
|
|
10
|
+
isAuthenticated() {
|
|
11
|
+
return !!this.context.userId;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Check if user has a tenant context
|
|
15
|
+
*/
|
|
16
|
+
hasTenant() {
|
|
17
|
+
return !!this.context.tenantId;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if user is member of a specific tenant
|
|
21
|
+
*/
|
|
22
|
+
isMemberOf(tenantId) {
|
|
23
|
+
if (this.context.tenantId === tenantId) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
if (this.context.memberships) {
|
|
27
|
+
return this.context.memberships.some(
|
|
28
|
+
(m) => m.tenantId === tenantId && m.status === "active"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if user has a specific role
|
|
35
|
+
*/
|
|
36
|
+
hasRole(role) {
|
|
37
|
+
return this.context.roles?.includes(role) ?? false;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if user has any of the specified roles
|
|
41
|
+
*/
|
|
42
|
+
hasAnyRole(roles) {
|
|
43
|
+
return roles.some((role) => this.hasRole(role));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if user has all of the specified roles
|
|
47
|
+
*/
|
|
48
|
+
hasAllRoles(roles) {
|
|
49
|
+
return roles.every((role) => this.hasRole(role));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if user has a specific permission
|
|
53
|
+
* Supports wildcards: 'users:*', '*:read', '*'
|
|
54
|
+
*/
|
|
55
|
+
hasPermission(permission) {
|
|
56
|
+
const userPermissions = this.context.permissions ?? [];
|
|
57
|
+
if (userPermissions.includes(permission)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (userPermissions.includes("*")) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const [resource, action] = permission.split(":");
|
|
64
|
+
for (const userPerm of userPermissions) {
|
|
65
|
+
const [userResource, userAction] = userPerm.split(":");
|
|
66
|
+
if (userResource === resource && userAction === "*") {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (userResource === "*" && userAction === action) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if user has any of the specified permissions
|
|
77
|
+
*/
|
|
78
|
+
hasAnyPermission(permissions) {
|
|
79
|
+
return permissions.some((perm) => this.hasPermission(perm));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if user has all of the specified permissions
|
|
83
|
+
*/
|
|
84
|
+
hasAllPermissions(permissions) {
|
|
85
|
+
return permissions.every((perm) => this.hasPermission(perm));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if user has role in specific tenant
|
|
89
|
+
*/
|
|
90
|
+
hasRoleInTenant(tenantId, role) {
|
|
91
|
+
if (!this.context.memberships) {
|
|
92
|
+
return this.context.tenantId === tenantId && this.hasRole(role);
|
|
93
|
+
}
|
|
94
|
+
const membership = this.context.memberships.find(
|
|
95
|
+
(m) => m.tenantId === tenantId && m.status === "active"
|
|
96
|
+
);
|
|
97
|
+
return membership?.role === role;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if user has permission in specific tenant
|
|
101
|
+
*/
|
|
102
|
+
hasPermissionInTenant(tenantId, permission) {
|
|
103
|
+
if (!this.context.memberships) {
|
|
104
|
+
return this.context.tenantId === tenantId && this.hasPermission(permission);
|
|
105
|
+
}
|
|
106
|
+
const membership = this.context.memberships.find(
|
|
107
|
+
(m) => m.tenantId === tenantId && m.status === "active"
|
|
108
|
+
);
|
|
109
|
+
if (!membership) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const permissions = membership.permissions;
|
|
113
|
+
if (permissions.includes(permission) || permissions.includes("*")) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
const [resource, action] = permission.split(":");
|
|
117
|
+
for (const perm of permissions) {
|
|
118
|
+
const [permResource, permAction] = perm.split(":");
|
|
119
|
+
if (permResource === resource && permAction === "*") return true;
|
|
120
|
+
if (permResource === "*" && permAction === action) return true;
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Comprehensive authorization check
|
|
126
|
+
*/
|
|
127
|
+
authorize(requirements) {
|
|
128
|
+
const result = { allowed: true };
|
|
129
|
+
if (requirements.authenticated && !this.isAuthenticated()) {
|
|
130
|
+
return { allowed: false, reason: "Authentication required" };
|
|
131
|
+
}
|
|
132
|
+
if (requirements.tenant && !this.hasTenant()) {
|
|
133
|
+
return { allowed: false, reason: "Tenant context required" };
|
|
134
|
+
}
|
|
135
|
+
if (requirements.memberOf && !this.isMemberOf(requirements.memberOf)) {
|
|
136
|
+
return { allowed: false, reason: `Membership in tenant ${requirements.memberOf} required` };
|
|
137
|
+
}
|
|
138
|
+
if (requirements.roles) {
|
|
139
|
+
const mode = requirements.rolesMode ?? "any";
|
|
140
|
+
const hasRoles = mode === "any" ? this.hasAnyRole(requirements.roles) : this.hasAllRoles(requirements.roles);
|
|
141
|
+
if (!hasRoles) {
|
|
142
|
+
return {
|
|
143
|
+
allowed: false,
|
|
144
|
+
reason: `Missing required roles`,
|
|
145
|
+
missingRoles: requirements.roles.filter((r) => !this.hasRole(r))
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (requirements.permissions) {
|
|
150
|
+
const mode = requirements.permissionsMode ?? "all";
|
|
151
|
+
const hasPermissions = mode === "any" ? this.hasAnyPermission(requirements.permissions) : this.hasAllPermissions(requirements.permissions);
|
|
152
|
+
if (!hasPermissions) {
|
|
153
|
+
return {
|
|
154
|
+
allowed: false,
|
|
155
|
+
reason: `Missing required permissions`,
|
|
156
|
+
missingPermissions: requirements.permissions.filter((p) => !this.hasPermission(p))
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (requirements.custom && !requirements.custom(this.context)) {
|
|
161
|
+
return { allowed: false, reason: requirements.customReason ?? "Custom authorization check failed" };
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get current tenant ID
|
|
167
|
+
*/
|
|
168
|
+
getTenantId() {
|
|
169
|
+
return this.context.tenantId ?? null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get current user ID
|
|
173
|
+
*/
|
|
174
|
+
getUserId() {
|
|
175
|
+
return this.context.userId;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get all user roles
|
|
179
|
+
*/
|
|
180
|
+
getRoles() {
|
|
181
|
+
return this.context.roles ?? [];
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get all user permissions
|
|
185
|
+
*/
|
|
186
|
+
getPermissions() {
|
|
187
|
+
return this.context.permissions ?? [];
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get all tenant memberships
|
|
191
|
+
*/
|
|
192
|
+
getMemberships() {
|
|
193
|
+
return this.context.memberships ?? [];
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
function createAuthorizationGuard(context) {
|
|
197
|
+
return new AuthorizationGuard(context);
|
|
198
|
+
}
|
|
199
|
+
var authorize = {
|
|
200
|
+
/**
|
|
201
|
+
* Check if authenticated
|
|
202
|
+
*/
|
|
203
|
+
isAuthenticated(context) {
|
|
204
|
+
return new AuthorizationGuard(context).authorize({ authenticated: true });
|
|
205
|
+
},
|
|
206
|
+
/**
|
|
207
|
+
* Check if has tenant
|
|
208
|
+
*/
|
|
209
|
+
hasTenant(context) {
|
|
210
|
+
return new AuthorizationGuard(context).authorize({ tenant: true });
|
|
211
|
+
},
|
|
212
|
+
/**
|
|
213
|
+
* Check if has specific role
|
|
214
|
+
*/
|
|
215
|
+
hasRole(context, role) {
|
|
216
|
+
return new AuthorizationGuard(context).authorize({ roles: [role] });
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* Check if has specific permission
|
|
220
|
+
*/
|
|
221
|
+
hasPermission(context, permission) {
|
|
222
|
+
return new AuthorizationGuard(context).authorize({ permissions: [permission] });
|
|
223
|
+
},
|
|
224
|
+
/**
|
|
225
|
+
* Check if is member of tenant
|
|
226
|
+
*/
|
|
227
|
+
isMemberOf(context, tenantId) {
|
|
228
|
+
return new AuthorizationGuard(context).authorize({ memberOf: tenantId });
|
|
229
|
+
},
|
|
230
|
+
/**
|
|
231
|
+
* Check if is admin (has 'admin' role or '*' permission)
|
|
232
|
+
*/
|
|
233
|
+
isAdmin(context) {
|
|
234
|
+
const guard = new AuthorizationGuard(context);
|
|
235
|
+
if (guard.hasRole("admin") || guard.hasRole("superadmin") || guard.hasPermission("*")) {
|
|
236
|
+
return { allowed: true };
|
|
237
|
+
}
|
|
238
|
+
return { allowed: false, reason: "Admin access required" };
|
|
239
|
+
},
|
|
240
|
+
/**
|
|
241
|
+
* Check if is owner of resource
|
|
242
|
+
*/
|
|
243
|
+
isOwner(context, ownerId) {
|
|
244
|
+
if (context.userId === ownerId) {
|
|
245
|
+
return { allowed: true };
|
|
246
|
+
}
|
|
247
|
+
return { allowed: false, reason: "Resource owner access required" };
|
|
248
|
+
},
|
|
249
|
+
/**
|
|
250
|
+
* Check if is owner or has permission
|
|
251
|
+
*/
|
|
252
|
+
isOwnerOrHasPermission(context, ownerId, permission) {
|
|
253
|
+
const guard = new AuthorizationGuard(context);
|
|
254
|
+
if (context.userId === ownerId || guard.hasPermission(permission)) {
|
|
255
|
+
return { allowed: true };
|
|
256
|
+
}
|
|
257
|
+
return { allowed: false, reason: "Owner or permission required" };
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
var Permissions = {
|
|
261
|
+
// User management
|
|
262
|
+
USERS_READ: "users:read",
|
|
263
|
+
USERS_WRITE: "users:write",
|
|
264
|
+
USERS_DELETE: "users:delete",
|
|
265
|
+
USERS_ADMIN: "users:*",
|
|
266
|
+
// Tenant management
|
|
267
|
+
TENANTS_READ: "tenants:read",
|
|
268
|
+
TENANTS_WRITE: "tenants:write",
|
|
269
|
+
TENANTS_DELETE: "tenants:delete",
|
|
270
|
+
TENANTS_ADMIN: "tenants:*",
|
|
271
|
+
// Member management
|
|
272
|
+
MEMBERS_READ: "members:read",
|
|
273
|
+
MEMBERS_INVITE: "members:invite",
|
|
274
|
+
MEMBERS_REMOVE: "members:remove",
|
|
275
|
+
MEMBERS_ADMIN: "members:*",
|
|
276
|
+
// Role management
|
|
277
|
+
ROLES_READ: "roles:read",
|
|
278
|
+
ROLES_WRITE: "roles:write",
|
|
279
|
+
ROLES_DELETE: "roles:delete",
|
|
280
|
+
ROLES_ADMIN: "roles:*",
|
|
281
|
+
// Super admin
|
|
282
|
+
SUPER_ADMIN: "*"
|
|
283
|
+
};
|
|
284
|
+
var Roles = {
|
|
285
|
+
OWNER: "owner",
|
|
286
|
+
ADMIN: "admin",
|
|
287
|
+
MANAGER: "manager",
|
|
288
|
+
MEMBER: "member",
|
|
289
|
+
VIEWER: "viewer",
|
|
290
|
+
GUEST: "guest"
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
export { AuthorizationGuard, Permissions, Roles, authorize, createAuthorizationGuard };
|
|
294
|
+
//# sourceMappingURL=chunk-NK4TJV2W.js.map
|
|
295
|
+
//# sourceMappingURL=chunk-NK4TJV2W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security/authorization.ts"],"names":[],"mappings":"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","file":"chunk-NK4TJV2W.js","sourcesContent":["/**\n * Authorization & Access Control\n * Guards for tenant, role, and permission-based access control\n */\n\n/**\n * Authorization context - usually extracted from JWT\n */\nexport interface AuthorizationContext {\n userId: string;\n tenantId?: string | null;\n roles?: string[];\n permissions?: string[];\n memberships?: TenantMembershipInfo[];\n}\n\n/**\n * Tenant membership information\n */\nexport interface TenantMembershipInfo {\n tenantId: string;\n role: string;\n permissions: string[];\n status: 'active' | 'inactive' | 'pending';\n}\n\n/**\n * Authorization check result\n */\nexport interface AuthorizationResult {\n allowed: boolean;\n reason?: string;\n missingPermissions?: string[];\n missingRoles?: string[];\n}\n\n/**\n * Permission pattern for matching\n * Supports wildcards: 'users:*', '*:read', '*'\n */\nexport type PermissionPattern = string;\n\n/**\n * Authorization Guard\n * Checks if a user has required permissions/roles for an action\n */\nexport class AuthorizationGuard {\n private context: AuthorizationContext;\n\n constructor(context: AuthorizationContext) {\n this.context = context;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n return !!this.context.userId;\n }\n\n /**\n * Check if user has a tenant context\n */\n hasTenant(): boolean {\n return !!this.context.tenantId;\n }\n\n /**\n * Check if user is member of a specific tenant\n */\n isMemberOf(tenantId: string): boolean {\n if (this.context.tenantId === tenantId) {\n return true;\n }\n\n if (this.context.memberships) {\n return this.context.memberships.some(\n m => m.tenantId === tenantId && m.status === 'active'\n );\n }\n\n return false;\n }\n\n /**\n * Check if user has a specific role\n */\n hasRole(role: string): boolean {\n return this.context.roles?.includes(role) ?? false;\n }\n\n /**\n * Check if user has any of the specified roles\n */\n hasAnyRole(roles: string[]): boolean {\n return roles.some(role => this.hasRole(role));\n }\n\n /**\n * Check if user has all of the specified roles\n */\n hasAllRoles(roles: string[]): boolean {\n return roles.every(role => this.hasRole(role));\n }\n\n /**\n * Check if user has a specific permission\n * Supports wildcards: 'users:*', '*:read', '*'\n */\n hasPermission(permission: PermissionPattern): boolean {\n const userPermissions = this.context.permissions ?? [];\n\n // Check for exact match\n if (userPermissions.includes(permission)) {\n return true;\n }\n\n // Check for super admin wildcard\n if (userPermissions.includes('*')) {\n return true;\n }\n\n // Check for pattern matching\n const [resource, action] = permission.split(':');\n\n for (const userPerm of userPermissions) {\n const [userResource, userAction] = userPerm.split(':');\n\n // Match 'resource:*' patterns\n if (userResource === resource && userAction === '*') {\n return true;\n }\n\n // Match '*:action' patterns\n if (userResource === '*' && userAction === action) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if user has any of the specified permissions\n */\n hasAnyPermission(permissions: PermissionPattern[]): boolean {\n return permissions.some(perm => this.hasPermission(perm));\n }\n\n /**\n * Check if user has all of the specified permissions\n */\n hasAllPermissions(permissions: PermissionPattern[]): boolean {\n return permissions.every(perm => this.hasPermission(perm));\n }\n\n /**\n * Check if user has role in specific tenant\n */\n hasRoleInTenant(tenantId: string, role: string): boolean {\n if (!this.context.memberships) {\n // Fallback to current context if no memberships\n return this.context.tenantId === tenantId && this.hasRole(role);\n }\n\n const membership = this.context.memberships.find(\n m => m.tenantId === tenantId && m.status === 'active'\n );\n\n return membership?.role === role;\n }\n\n /**\n * Check if user has permission in specific tenant\n */\n hasPermissionInTenant(tenantId: string, permission: PermissionPattern): boolean {\n if (!this.context.memberships) {\n // Fallback to current context if no memberships\n return this.context.tenantId === tenantId && this.hasPermission(permission);\n }\n\n const membership = this.context.memberships.find(\n m => m.tenantId === tenantId && m.status === 'active'\n );\n\n if (!membership) {\n return false;\n }\n\n // Check permissions from membership\n const permissions = membership.permissions;\n if (permissions.includes(permission) || permissions.includes('*')) {\n return true;\n }\n\n // Pattern matching\n const [resource, action] = permission.split(':');\n for (const perm of permissions) {\n const [permResource, permAction] = perm.split(':');\n if (permResource === resource && permAction === '*') return true;\n if (permResource === '*' && permAction === action) return true;\n }\n\n return false;\n }\n\n /**\n * Comprehensive authorization check\n */\n authorize(requirements: AuthorizationRequirements): AuthorizationResult {\n const result: AuthorizationResult = { allowed: true };\n\n // Check authentication\n if (requirements.authenticated && !this.isAuthenticated()) {\n return { allowed: false, reason: 'Authentication required' };\n }\n\n // Check tenant\n if (requirements.tenant && !this.hasTenant()) {\n return { allowed: false, reason: 'Tenant context required' };\n }\n\n // Check specific tenant membership\n if (requirements.memberOf && !this.isMemberOf(requirements.memberOf)) {\n return { allowed: false, reason: `Membership in tenant ${requirements.memberOf} required` };\n }\n\n // Check roles\n if (requirements.roles) {\n const mode = requirements.rolesMode ?? 'any';\n const hasRoles = mode === 'any'\n ? this.hasAnyRole(requirements.roles)\n : this.hasAllRoles(requirements.roles);\n\n if (!hasRoles) {\n return {\n allowed: false,\n reason: `Missing required roles`,\n missingRoles: requirements.roles.filter(r => !this.hasRole(r)),\n };\n }\n }\n\n // Check permissions\n if (requirements.permissions) {\n const mode = requirements.permissionsMode ?? 'all';\n const hasPermissions = mode === 'any'\n ? this.hasAnyPermission(requirements.permissions)\n : this.hasAllPermissions(requirements.permissions);\n\n if (!hasPermissions) {\n return {\n allowed: false,\n reason: `Missing required permissions`,\n missingPermissions: requirements.permissions.filter(p => !this.hasPermission(p)),\n };\n }\n }\n\n // Custom check\n if (requirements.custom && !requirements.custom(this.context)) {\n return { allowed: false, reason: requirements.customReason ?? 'Custom authorization check failed' };\n }\n\n return result;\n }\n\n /**\n * Get current tenant ID\n */\n getTenantId(): string | null {\n return this.context.tenantId ?? null;\n }\n\n /**\n * Get current user ID\n */\n getUserId(): string {\n return this.context.userId;\n }\n\n /**\n * Get all user roles\n */\n getRoles(): string[] {\n return this.context.roles ?? [];\n }\n\n /**\n * Get all user permissions\n */\n getPermissions(): string[] {\n return this.context.permissions ?? [];\n }\n\n /**\n * Get all tenant memberships\n */\n getMemberships(): TenantMembershipInfo[] {\n return this.context.memberships ?? [];\n }\n}\n\n/**\n * Authorization requirements\n */\nexport interface AuthorizationRequirements {\n /** User must be authenticated */\n authenticated?: boolean;\n /** User must have tenant context */\n tenant?: boolean;\n /** User must be member of specific tenant */\n memberOf?: string;\n /** Required roles */\n roles?: string[];\n /** Role check mode: 'any' (at least one) or 'all' */\n rolesMode?: 'any' | 'all';\n /** Required permissions */\n permissions?: PermissionPattern[];\n /** Permission check mode: 'any' (at least one) or 'all' */\n permissionsMode?: 'any' | 'all';\n /** Custom authorization function */\n custom?: (context: AuthorizationContext) => boolean;\n /** Custom failure reason */\n customReason?: string;\n}\n\n/**\n * Create an authorization guard\n */\nexport function createAuthorizationGuard(context: AuthorizationContext): AuthorizationGuard {\n return new AuthorizationGuard(context);\n}\n\n/**\n * Quick authorization checks\n */\nexport const authorize = {\n /**\n * Check if authenticated\n */\n isAuthenticated(context: AuthorizationContext): AuthorizationResult {\n return new AuthorizationGuard(context).authorize({ authenticated: true });\n },\n\n /**\n * Check if has tenant\n */\n hasTenant(context: AuthorizationContext): AuthorizationResult {\n return new AuthorizationGuard(context).authorize({ tenant: true });\n },\n\n /**\n * Check if has specific role\n */\n hasRole(context: AuthorizationContext, role: string): AuthorizationResult {\n return new AuthorizationGuard(context).authorize({ roles: [role] });\n },\n\n /**\n * Check if has specific permission\n */\n hasPermission(context: AuthorizationContext, permission: string): AuthorizationResult {\n return new AuthorizationGuard(context).authorize({ permissions: [permission] });\n },\n\n /**\n * Check if is member of tenant\n */\n isMemberOf(context: AuthorizationContext, tenantId: string): AuthorizationResult {\n return new AuthorizationGuard(context).authorize({ memberOf: tenantId });\n },\n\n /**\n * Check if is admin (has 'admin' role or '*' permission)\n */\n isAdmin(context: AuthorizationContext): AuthorizationResult {\n const guard = new AuthorizationGuard(context);\n if (guard.hasRole('admin') || guard.hasRole('superadmin') || guard.hasPermission('*')) {\n return { allowed: true };\n }\n return { allowed: false, reason: 'Admin access required' };\n },\n\n /**\n * Check if is owner of resource\n */\n isOwner(context: AuthorizationContext, ownerId: string): AuthorizationResult {\n if (context.userId === ownerId) {\n return { allowed: true };\n }\n return { allowed: false, reason: 'Resource owner access required' };\n },\n\n /**\n * Check if is owner or has permission\n */\n isOwnerOrHasPermission(\n context: AuthorizationContext,\n ownerId: string,\n permission: string\n ): AuthorizationResult {\n const guard = new AuthorizationGuard(context);\n if (context.userId === ownerId || guard.hasPermission(permission)) {\n return { allowed: true };\n }\n return { allowed: false, reason: 'Owner or permission required' };\n },\n};\n\n/**\n * Common permission patterns\n */\nexport const Permissions = {\n // User management\n USERS_READ: 'users:read',\n USERS_WRITE: 'users:write',\n USERS_DELETE: 'users:delete',\n USERS_ADMIN: 'users:*',\n\n // Tenant management\n TENANTS_READ: 'tenants:read',\n TENANTS_WRITE: 'tenants:write',\n TENANTS_DELETE: 'tenants:delete',\n TENANTS_ADMIN: 'tenants:*',\n\n // Member management\n MEMBERS_READ: 'members:read',\n MEMBERS_INVITE: 'members:invite',\n MEMBERS_REMOVE: 'members:remove',\n MEMBERS_ADMIN: 'members:*',\n\n // Role management\n ROLES_READ: 'roles:read',\n ROLES_WRITE: 'roles:write',\n ROLES_DELETE: 'roles:delete',\n ROLES_ADMIN: 'roles:*',\n\n // Super admin\n SUPER_ADMIN: '*',\n} as const;\n\n/**\n * Common roles\n */\nexport const Roles = {\n OWNER: 'owner',\n ADMIN: 'admin',\n MANAGER: 'manager',\n MEMBER: 'member',\n VIEWER: 'viewer',\n GUEST: 'guest',\n} as const;\n"]}
|