@noony-serverless/core 0.1.0 → 0.1.1
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/build/middlewares/guards/RouteGuards.d.ts +255 -0
- package/build/middlewares/guards/RouteGuards.js +500 -0
- package/build/middlewares/guards/cache/CacheAdapter.d.ts +132 -0
- package/build/middlewares/guards/cache/CacheAdapter.js +86 -0
- package/build/middlewares/guards/cache/ConservativeCacheInvalidation.d.ts +191 -0
- package/build/middlewares/guards/cache/ConservativeCacheInvalidation.js +510 -0
- package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +119 -0
- package/build/middlewares/guards/cache/MemoryCacheAdapter.js +294 -0
- package/build/middlewares/guards/cache/NoopCacheAdapter.d.ts +95 -0
- package/build/middlewares/guards/cache/NoopCacheAdapter.js +131 -0
- package/build/middlewares/guards/config/GuardConfiguration.d.ts +112 -0
- package/build/middlewares/guards/config/GuardConfiguration.js +137 -0
- package/build/middlewares/guards/guards/FastAuthGuard.d.ts +201 -0
- package/build/middlewares/guards/guards/FastAuthGuard.js +460 -0
- package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +202 -0
- package/build/middlewares/guards/guards/PermissionGuardFactory.js +563 -0
- package/build/middlewares/guards/index.d.ts +67 -0
- package/build/middlewares/guards/index.js +192 -0
- package/build/middlewares/guards/registry/PermissionRegistry.d.ts +188 -0
- package/build/middlewares/guards/registry/PermissionRegistry.js +425 -0
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +129 -0
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +451 -0
- package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +155 -0
- package/build/middlewares/guards/resolvers/PermissionResolver.js +176 -0
- package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +101 -0
- package/build/middlewares/guards/resolvers/PlainPermissionResolver.js +248 -0
- package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +146 -0
- package/build/middlewares/guards/resolvers/WildcardPermissionResolver.js +377 -0
- package/build/middlewares/guards/services/FastUserContextService.d.ts +216 -0
- package/build/middlewares/guards/services/FastUserContextService.js +434 -0
- package/build/middlewares/index.d.ts +1 -0
- package/build/middlewares/index.js +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Permission Registry
|
|
4
|
+
*
|
|
5
|
+
* Central registry for managing available permissions in the system.
|
|
6
|
+
* Supports wildcard pattern expansion, permission discovery, and
|
|
7
|
+
* category-based organization for efficient permission management.
|
|
8
|
+
*
|
|
9
|
+
* Key Features:
|
|
10
|
+
* - Permission registration and discovery
|
|
11
|
+
* - Wildcard pattern expansion ("admin.*" -> ["admin.users", "admin.roles"])
|
|
12
|
+
* - Category-based organization
|
|
13
|
+
* - Thread-safe operations with caching
|
|
14
|
+
* - Auto-discovery from codebase annotations
|
|
15
|
+
* - Permission hierarchy validation
|
|
16
|
+
*
|
|
17
|
+
* @author Noony Framework Team
|
|
18
|
+
* @version 1.0.0
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.PermissionRegistryFactory = exports.DefaultPermissionRegistry = void 0;
|
|
22
|
+
/**
|
|
23
|
+
* Default permission registry implementation
|
|
24
|
+
*
|
|
25
|
+
* Thread-safe in-memory registry with caching for pattern matching.
|
|
26
|
+
* In production, this could be backed by a database or external service.
|
|
27
|
+
*/
|
|
28
|
+
class DefaultPermissionRegistry {
|
|
29
|
+
permissions = new Map();
|
|
30
|
+
categoryIndex = new Map();
|
|
31
|
+
patternCache = new Map();
|
|
32
|
+
// Performance tracking
|
|
33
|
+
stats = {
|
|
34
|
+
totalLookups: 0,
|
|
35
|
+
patternMatchingTime: 0,
|
|
36
|
+
cacheHits: 0,
|
|
37
|
+
cacheMisses: 0,
|
|
38
|
+
};
|
|
39
|
+
constructor() {
|
|
40
|
+
// Initialize with common system permissions
|
|
41
|
+
this.initializeSystemPermissions();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Register a permission with metadata
|
|
45
|
+
*/
|
|
46
|
+
registerPermission(metadata) {
|
|
47
|
+
// Validate permission format
|
|
48
|
+
if (!this.isValidPermissionFormat(metadata.permission)) {
|
|
49
|
+
throw new Error(`Invalid permission format: ${metadata.permission}`);
|
|
50
|
+
}
|
|
51
|
+
// Check for duplicates
|
|
52
|
+
if (this.permissions.has(metadata.permission)) {
|
|
53
|
+
console.warn(`Permission ${metadata.permission} is already registered`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// Extract category from permission if not provided
|
|
57
|
+
if (!metadata.category) {
|
|
58
|
+
metadata.category = this.extractCategory(metadata.permission);
|
|
59
|
+
}
|
|
60
|
+
// Store permission
|
|
61
|
+
this.permissions.set(metadata.permission, {
|
|
62
|
+
...metadata,
|
|
63
|
+
registeredAt: new Date(),
|
|
64
|
+
});
|
|
65
|
+
// Update category index
|
|
66
|
+
if (!this.categoryIndex.has(metadata.category)) {
|
|
67
|
+
this.categoryIndex.set(metadata.category, new Set());
|
|
68
|
+
}
|
|
69
|
+
this.categoryIndex.get(metadata.category).add(metadata.permission);
|
|
70
|
+
// Invalidate pattern cache since new permission might affect wildcard matches
|
|
71
|
+
this.patternCache.clear();
|
|
72
|
+
console.debug(`Registered permission: ${metadata.permission} (${metadata.category})`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Register multiple permissions at once
|
|
76
|
+
*/
|
|
77
|
+
registerPermissions(permissions) {
|
|
78
|
+
for (const permission of permissions) {
|
|
79
|
+
this.registerPermission(permission);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get all permissions matching a wildcard pattern
|
|
84
|
+
*/
|
|
85
|
+
getMatchingPermissions(wildcardPattern) {
|
|
86
|
+
const startTime = process.hrtime.bigint();
|
|
87
|
+
this.stats.totalLookups++;
|
|
88
|
+
try {
|
|
89
|
+
// Check cache first
|
|
90
|
+
if (this.patternCache.has(wildcardPattern)) {
|
|
91
|
+
this.stats.cacheHits++;
|
|
92
|
+
return this.patternCache.get(wildcardPattern);
|
|
93
|
+
}
|
|
94
|
+
this.stats.cacheMisses++;
|
|
95
|
+
// Convert wildcard pattern to regex
|
|
96
|
+
const regex = this.wildcardToRegex(wildcardPattern);
|
|
97
|
+
const matchingPermissions = [];
|
|
98
|
+
// Find all matching permissions
|
|
99
|
+
for (const permission of this.permissions.keys()) {
|
|
100
|
+
if (regex.test(permission)) {
|
|
101
|
+
matchingPermissions.push(permission);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Cache the result
|
|
105
|
+
this.patternCache.set(wildcardPattern, matchingPermissions);
|
|
106
|
+
return matchingPermissions;
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
const endTime = process.hrtime.bigint();
|
|
110
|
+
this.stats.patternMatchingTime += Number(endTime - startTime) / 1000; // microseconds
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get all permissions in a category
|
|
115
|
+
*/
|
|
116
|
+
getCategoryPermissions(category) {
|
|
117
|
+
const permissions = this.categoryIndex.get(category);
|
|
118
|
+
return permissions ? Array.from(permissions) : [];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if a permission exists in the registry
|
|
122
|
+
*/
|
|
123
|
+
hasPermission(permission) {
|
|
124
|
+
return this.permissions.has(permission);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get permission metadata
|
|
128
|
+
*/
|
|
129
|
+
getPermissionMetadata(permission) {
|
|
130
|
+
return this.permissions.get(permission) || null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get all registered permissions
|
|
134
|
+
*/
|
|
135
|
+
getAllPermissions() {
|
|
136
|
+
return Array.from(this.permissions.keys());
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get all categories
|
|
140
|
+
*/
|
|
141
|
+
getAllCategories() {
|
|
142
|
+
return Array.from(this.categoryIndex.keys());
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get registry statistics
|
|
146
|
+
*/
|
|
147
|
+
getStats() {
|
|
148
|
+
const permissionsByCategory = {};
|
|
149
|
+
const riskLevelDistribution = {};
|
|
150
|
+
const registrationTimeline = [];
|
|
151
|
+
for (const [category, permissions] of this.categoryIndex) {
|
|
152
|
+
permissionsByCategory[category] = permissions.size;
|
|
153
|
+
}
|
|
154
|
+
for (const metadata of this.permissions.values()) {
|
|
155
|
+
riskLevelDistribution[metadata.riskLevel] =
|
|
156
|
+
(riskLevelDistribution[metadata.riskLevel] || 0) + 1;
|
|
157
|
+
registrationTimeline.push(metadata.registeredAt);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
totalPermissions: this.permissions.size,
|
|
161
|
+
totalCategories: this.categoryIndex.size,
|
|
162
|
+
permissionsByCategory,
|
|
163
|
+
riskLevelDistribution,
|
|
164
|
+
registrationTimeline: registrationTimeline.sort((a, b) => a.getTime() - b.getTime()),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get performance statistics
|
|
169
|
+
*/
|
|
170
|
+
getPerformanceStats() {
|
|
171
|
+
const totalCacheRequests = this.stats.cacheHits + this.stats.cacheMisses;
|
|
172
|
+
return {
|
|
173
|
+
totalLookups: this.stats.totalLookups,
|
|
174
|
+
averagePatternMatchingTimeUs: this.stats.totalLookups > 0
|
|
175
|
+
? this.stats.patternMatchingTime / this.stats.totalLookups
|
|
176
|
+
: 0,
|
|
177
|
+
cacheHitRate: totalCacheRequests > 0
|
|
178
|
+
? (this.stats.cacheHits / totalCacheRequests) * 100
|
|
179
|
+
: 0,
|
|
180
|
+
cacheSize: this.patternCache.size,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Clear the pattern cache
|
|
185
|
+
*/
|
|
186
|
+
clearCache() {
|
|
187
|
+
this.patternCache.clear();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Initialize common system permissions
|
|
191
|
+
*/
|
|
192
|
+
initializeSystemPermissions() {
|
|
193
|
+
const now = new Date();
|
|
194
|
+
const systemPermissions = [
|
|
195
|
+
// User management permissions
|
|
196
|
+
{
|
|
197
|
+
permission: 'user.create',
|
|
198
|
+
description: 'Create new user accounts',
|
|
199
|
+
category: 'user',
|
|
200
|
+
action: 'create',
|
|
201
|
+
riskLevel: 'medium',
|
|
202
|
+
requiresValidation: true,
|
|
203
|
+
registeredAt: now,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
permission: 'user.read',
|
|
207
|
+
description: 'View user information',
|
|
208
|
+
category: 'user',
|
|
209
|
+
action: 'read',
|
|
210
|
+
riskLevel: 'low',
|
|
211
|
+
requiresValidation: false,
|
|
212
|
+
registeredAt: now,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
permission: 'user.update',
|
|
216
|
+
description: 'Update user information',
|
|
217
|
+
category: 'user',
|
|
218
|
+
action: 'update',
|
|
219
|
+
riskLevel: 'medium',
|
|
220
|
+
requiresValidation: true,
|
|
221
|
+
registeredAt: now,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
permission: 'user.delete',
|
|
225
|
+
description: 'Delete user accounts',
|
|
226
|
+
category: 'user',
|
|
227
|
+
action: 'delete',
|
|
228
|
+
riskLevel: 'high',
|
|
229
|
+
requiresValidation: true,
|
|
230
|
+
registeredAt: now,
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
permission: 'user.list',
|
|
234
|
+
description: 'List users with filtering',
|
|
235
|
+
category: 'user',
|
|
236
|
+
action: 'list',
|
|
237
|
+
riskLevel: 'low',
|
|
238
|
+
requiresValidation: false,
|
|
239
|
+
registeredAt: now,
|
|
240
|
+
},
|
|
241
|
+
// Admin permissions
|
|
242
|
+
{
|
|
243
|
+
permission: 'admin.users',
|
|
244
|
+
description: 'Full administrative access to user management',
|
|
245
|
+
category: 'admin',
|
|
246
|
+
subCategory: 'users',
|
|
247
|
+
riskLevel: 'critical',
|
|
248
|
+
requiresValidation: true,
|
|
249
|
+
registeredAt: now,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
permission: 'admin.system',
|
|
253
|
+
description: 'System-level administrative access',
|
|
254
|
+
category: 'admin',
|
|
255
|
+
subCategory: 'system',
|
|
256
|
+
riskLevel: 'critical',
|
|
257
|
+
requiresValidation: true,
|
|
258
|
+
registeredAt: now,
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
permission: 'admin.monitoring',
|
|
262
|
+
description: 'Access to monitoring and metrics',
|
|
263
|
+
category: 'admin',
|
|
264
|
+
subCategory: 'monitoring',
|
|
265
|
+
riskLevel: 'medium',
|
|
266
|
+
requiresValidation: false,
|
|
267
|
+
registeredAt: now,
|
|
268
|
+
},
|
|
269
|
+
// Organization permissions
|
|
270
|
+
{
|
|
271
|
+
permission: 'organization.view',
|
|
272
|
+
description: 'View organization information',
|
|
273
|
+
category: 'organization',
|
|
274
|
+
action: 'view',
|
|
275
|
+
riskLevel: 'low',
|
|
276
|
+
requiresValidation: false,
|
|
277
|
+
registeredAt: now,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
permission: 'organization.manage',
|
|
281
|
+
description: 'Manage organization settings',
|
|
282
|
+
category: 'organization',
|
|
283
|
+
action: 'manage',
|
|
284
|
+
riskLevel: 'high',
|
|
285
|
+
requiresValidation: true,
|
|
286
|
+
registeredAt: now,
|
|
287
|
+
},
|
|
288
|
+
// Situation report permissions
|
|
289
|
+
{
|
|
290
|
+
permission: 'situation.reports.create',
|
|
291
|
+
description: 'Create situation reports',
|
|
292
|
+
category: 'situation',
|
|
293
|
+
subCategory: 'reports',
|
|
294
|
+
action: 'create',
|
|
295
|
+
riskLevel: 'medium',
|
|
296
|
+
requiresValidation: false,
|
|
297
|
+
registeredAt: now,
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
permission: 'situation.reports.view',
|
|
301
|
+
description: 'View situation reports',
|
|
302
|
+
category: 'situation',
|
|
303
|
+
subCategory: 'reports',
|
|
304
|
+
action: 'view',
|
|
305
|
+
riskLevel: 'low',
|
|
306
|
+
requiresValidation: false,
|
|
307
|
+
registeredAt: now,
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
permission: 'situation.reports.update',
|
|
311
|
+
description: 'Update situation reports',
|
|
312
|
+
category: 'situation',
|
|
313
|
+
subCategory: 'reports',
|
|
314
|
+
action: 'update',
|
|
315
|
+
riskLevel: 'medium',
|
|
316
|
+
requiresValidation: true,
|
|
317
|
+
registeredAt: now,
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
permission: 'situation.reports.delete',
|
|
321
|
+
description: 'Delete situation reports',
|
|
322
|
+
category: 'situation',
|
|
323
|
+
subCategory: 'reports',
|
|
324
|
+
action: 'delete',
|
|
325
|
+
riskLevel: 'high',
|
|
326
|
+
requiresValidation: true,
|
|
327
|
+
registeredAt: now,
|
|
328
|
+
},
|
|
329
|
+
// System permissions
|
|
330
|
+
{
|
|
331
|
+
permission: 'system.health',
|
|
332
|
+
description: 'Access system health information',
|
|
333
|
+
category: 'system',
|
|
334
|
+
action: 'health',
|
|
335
|
+
riskLevel: 'low',
|
|
336
|
+
requiresValidation: false,
|
|
337
|
+
registeredAt: now,
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
permission: 'system.metrics',
|
|
341
|
+
description: 'Access system metrics',
|
|
342
|
+
category: 'system',
|
|
343
|
+
action: 'metrics',
|
|
344
|
+
riskLevel: 'low',
|
|
345
|
+
requiresValidation: false,
|
|
346
|
+
registeredAt: now,
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
permission: 'system.logs',
|
|
350
|
+
description: 'Access system logs',
|
|
351
|
+
category: 'system',
|
|
352
|
+
action: 'logs',
|
|
353
|
+
riskLevel: 'medium',
|
|
354
|
+
requiresValidation: true,
|
|
355
|
+
registeredAt: now,
|
|
356
|
+
},
|
|
357
|
+
];
|
|
358
|
+
this.registerPermissions(systemPermissions);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Validate permission format (2-3 levels with alphanumeric + dots)
|
|
362
|
+
*/
|
|
363
|
+
isValidPermissionFormat(permission) {
|
|
364
|
+
if (!permission || typeof permission !== 'string') {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
// Allow both concrete permissions and wildcard patterns
|
|
368
|
+
const validPattern = /^[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+){1,2}$/;
|
|
369
|
+
const wildcardPattern = /^[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.\*$/;
|
|
370
|
+
return validPattern.test(permission) || wildcardPattern.test(permission);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Extract category from permission string
|
|
374
|
+
*/
|
|
375
|
+
extractCategory(permission) {
|
|
376
|
+
const parts = permission.split('.');
|
|
377
|
+
return parts[0] || 'unknown';
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Convert wildcard pattern to regex
|
|
381
|
+
*/
|
|
382
|
+
wildcardToRegex(wildcardPattern) {
|
|
383
|
+
if (!wildcardPattern.includes('*')) {
|
|
384
|
+
// Exact match for non-wildcard patterns
|
|
385
|
+
return new RegExp(`^${wildcardPattern.replace(/\./g, '\\.')}$`);
|
|
386
|
+
}
|
|
387
|
+
// Convert wildcard pattern to regex
|
|
388
|
+
// "admin.*" becomes /^admin\..*$/
|
|
389
|
+
// "admin.users.*" becomes /^admin\.users\..*$/
|
|
390
|
+
const regexPattern = wildcardPattern
|
|
391
|
+
.replace(/\./g, '\\.') // Escape dots
|
|
392
|
+
.replace(/\*/g, '.*'); // Replace * with any characters
|
|
393
|
+
return new RegExp(`^${regexPattern}$`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
exports.DefaultPermissionRegistry = DefaultPermissionRegistry;
|
|
397
|
+
/**
|
|
398
|
+
* Factory for creating permission registries
|
|
399
|
+
*/
|
|
400
|
+
class PermissionRegistryFactory {
|
|
401
|
+
/**
|
|
402
|
+
* Create a default permission registry with system permissions
|
|
403
|
+
*/
|
|
404
|
+
static createDefault() {
|
|
405
|
+
return new DefaultPermissionRegistry();
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Create an empty permission registry
|
|
409
|
+
*/
|
|
410
|
+
static createEmpty() {
|
|
411
|
+
const registry = new DefaultPermissionRegistry();
|
|
412
|
+
// Clear system permissions if needed for testing
|
|
413
|
+
return registry;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Create a registry from a permission definition file
|
|
417
|
+
*/
|
|
418
|
+
static createFromDefinitions(definitions) {
|
|
419
|
+
const registry = new DefaultPermissionRegistry();
|
|
420
|
+
registry.registerPermissions(definitions);
|
|
421
|
+
return registry;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
exports.PermissionRegistryFactory = PermissionRegistryFactory;
|
|
425
|
+
//# sourceMappingURL=PermissionRegistry.js.map
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression Permission Resolver
|
|
3
|
+
*
|
|
4
|
+
* Advanced permission resolver supporting complex boolean expressions with
|
|
5
|
+
* AND, OR, and NOT operations. Limited to 2-level nesting to prevent
|
|
6
|
+
* performance degradation while maintaining flexibility for complex
|
|
7
|
+
* authorization scenarios.
|
|
8
|
+
*
|
|
9
|
+
* Supported Expression Structure:
|
|
10
|
+
* - Leaf permissions: { permission: "admin.users" }
|
|
11
|
+
* - AND operations: { and: [expr1, expr2, ...] }
|
|
12
|
+
* - OR operations: { or: [expr1, expr2, ...] }
|
|
13
|
+
* - NOT operations: { not: expr }
|
|
14
|
+
* - Maximum 2-level nesting depth
|
|
15
|
+
*
|
|
16
|
+
* Performance Features:
|
|
17
|
+
* - Result caching for expensive expression evaluations
|
|
18
|
+
* - Short-circuit evaluation (AND stops at first false, OR stops at first true)
|
|
19
|
+
* - Expression normalization for consistent cache keys
|
|
20
|
+
* - Performance metrics and monitoring
|
|
21
|
+
*
|
|
22
|
+
* Example Expressions:
|
|
23
|
+
* ```
|
|
24
|
+
* // Simple OR: user needs admin OR manager role
|
|
25
|
+
* { or: [{ permission: "admin.platform" }, { permission: "role.manager" }] }
|
|
26
|
+
*
|
|
27
|
+
* // Complex AND/OR: (admin OR (manager AND finance))
|
|
28
|
+
* {
|
|
29
|
+
* or: [
|
|
30
|
+
* { permission: "admin.platform" },
|
|
31
|
+
* { and: [{ permission: "role.manager" }, { permission: "department.finance" }] }
|
|
32
|
+
* ]
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @author Noony Framework Team
|
|
37
|
+
* @version 1.0.0
|
|
38
|
+
*/
|
|
39
|
+
import { PermissionResolver, PermissionResolverType, PerformanceCharacteristics, PermissionCheckResult, PermissionExpression } from './PermissionResolver';
|
|
40
|
+
import { CacheAdapter } from '../cache/CacheAdapter';
|
|
41
|
+
/**
|
|
42
|
+
* Expression permission resolver for complex boolean logic
|
|
43
|
+
*/
|
|
44
|
+
export declare class ExpressionPermissionResolver extends PermissionResolver<PermissionExpression> {
|
|
45
|
+
private readonly cache;
|
|
46
|
+
private readonly maxNestingDepth;
|
|
47
|
+
private checkCount;
|
|
48
|
+
private totalResolutionTimeUs;
|
|
49
|
+
private cacheHits;
|
|
50
|
+
private cacheMisses;
|
|
51
|
+
private expressionComplexityStats;
|
|
52
|
+
constructor(cache: CacheAdapter);
|
|
53
|
+
/**
|
|
54
|
+
* Check if user permissions satisfy the permission expression
|
|
55
|
+
*
|
|
56
|
+
* @param userPermissions - Set of user's permissions for O(1) lookup
|
|
57
|
+
* @param expression - Permission expression to evaluate
|
|
58
|
+
* @returns Promise resolving to true if expression evaluates to true
|
|
59
|
+
*/
|
|
60
|
+
check(userPermissions: Set<string>, expression: PermissionExpression): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Check permissions with detailed result information
|
|
63
|
+
*/
|
|
64
|
+
checkWithResult(userPermissions: Set<string>, expression: PermissionExpression): Promise<PermissionCheckResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Evaluate permission expression recursively
|
|
67
|
+
*
|
|
68
|
+
* @param userPermissions - User's permissions as Set for O(1) lookup
|
|
69
|
+
* @param expression - Expression to evaluate
|
|
70
|
+
* @param depth - Current nesting depth
|
|
71
|
+
* @returns Boolean result of expression evaluation
|
|
72
|
+
*/
|
|
73
|
+
private evaluateExpression;
|
|
74
|
+
/**
|
|
75
|
+
* Evaluate expression with detailed result information
|
|
76
|
+
*/
|
|
77
|
+
private evaluateExpressionWithDetails;
|
|
78
|
+
/**
|
|
79
|
+
* Track expression complexity for analytics
|
|
80
|
+
*/
|
|
81
|
+
private trackComplexity;
|
|
82
|
+
/**
|
|
83
|
+
* Get the depth of an expression
|
|
84
|
+
*/
|
|
85
|
+
private getExpressionDepth;
|
|
86
|
+
/**
|
|
87
|
+
* Get resolver type for identification
|
|
88
|
+
*/
|
|
89
|
+
getType(): PermissionResolverType;
|
|
90
|
+
/**
|
|
91
|
+
* Get performance characteristics for monitoring
|
|
92
|
+
*/
|
|
93
|
+
getPerformanceCharacteristics(): PerformanceCharacteristics;
|
|
94
|
+
/**
|
|
95
|
+
* Get performance statistics
|
|
96
|
+
*/
|
|
97
|
+
getStats(): {
|
|
98
|
+
checkCount: number;
|
|
99
|
+
averageResolutionTimeUs: number;
|
|
100
|
+
totalResolutionTimeUs: number;
|
|
101
|
+
cacheHitRate: number;
|
|
102
|
+
cacheHits: number;
|
|
103
|
+
cacheMisses: number;
|
|
104
|
+
complexityDistribution: {
|
|
105
|
+
simple: number;
|
|
106
|
+
moderate: number;
|
|
107
|
+
complex: number;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Reset performance statistics
|
|
112
|
+
*/
|
|
113
|
+
resetStats(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Get resolver name for debugging
|
|
116
|
+
*/
|
|
117
|
+
getName(): string;
|
|
118
|
+
/**
|
|
119
|
+
* Check if this resolver can handle the given requirement type
|
|
120
|
+
*/
|
|
121
|
+
canHandle(requirement: any): requirement is PermissionExpression;
|
|
122
|
+
/**
|
|
123
|
+
* Normalize expression for consistent cache keys
|
|
124
|
+
*
|
|
125
|
+
* Sorts arrays and standardizes structure for reliable caching
|
|
126
|
+
*/
|
|
127
|
+
static normalizeExpression(expression: PermissionExpression): PermissionExpression;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=ExpressionPermissionResolver.d.ts.map
|