@revealui/core 0.3.0 → 0.5.2
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/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.js +20 -3
- package/dist/client/richtext/index.d.ts.map +1 -1
- package/dist/client/richtext/plugins/FloatingToolbarPlugin.js +1 -3
- package/dist/collections/operations/create.d.ts +2 -1
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +28 -1
- package/dist/database/type-adapter.d.ts.map +1 -1
- package/dist/features.d.ts +13 -3
- package/dist/features.d.ts.map +1 -1
- package/dist/features.js +17 -0
- package/dist/globals/GlobalOperations.d.ts.map +1 -1
- package/dist/globals/GlobalOperations.js +12 -2
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/license.d.ts +6 -0
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +14 -1
- package/dist/monitoring/alerts.d.ts +4 -4
- package/dist/monitoring/alerts.d.ts.map +1 -1
- package/dist/plugins/nested-docs.d.ts.map +1 -1
- package/dist/plugins/nested-docs.js +0 -1
- package/dist/queries/queryBuilder.d.ts.map +1 -1
- package/dist/queries/queryBuilder.js +4 -3
- package/dist/richtext/index.d.ts.map +1 -1
- package/dist/storage/vercel-blob.d.ts.map +1 -1
- package/dist/storage/vercel-blob.js +3 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/extensions.d.ts.map +1 -1
- package/dist/types/frontend.d.ts.map +1 -1
- package/dist/types/legacy.d.ts.map +1 -1
- package/dist/types/query.d.ts.map +1 -1
- package/dist/types/runtime.d.ts +1 -0
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/utils/error-responses.d.ts.map +1 -1
- package/dist/utils/error-responses.js +2 -3
- package/package.json +24 -24
- package/dist/caching/app-cache.d.ts +0 -242
- package/dist/caching/app-cache.d.ts.map +0 -1
- package/dist/caching/app-cache.js +0 -438
- package/dist/caching/cdn-config.d.ts +0 -155
- package/dist/caching/cdn-config.d.ts.map +0 -1
- package/dist/caching/cdn-config.js +0 -415
- package/dist/caching/edge-cache.d.ts +0 -177
- package/dist/caching/edge-cache.d.ts.map +0 -1
- package/dist/caching/edge-cache.js +0 -414
- package/dist/caching/service-worker.d.ts +0 -157
- package/dist/caching/service-worker.d.ts.map +0 -1
- package/dist/caching/service-worker.js +0 -438
- package/dist/client/admin/utils/auth.d.ts +0 -23
- package/dist/client/admin/utils/auth.d.ts.map +0 -1
- package/dist/client/admin/utils/auth.js +0 -52
- package/dist/client/http/client.d.ts +0 -15
- package/dist/client/http/client.d.ts.map +0 -1
- package/dist/client/http/client.js +0 -49
- package/dist/client/http/fetchBanner.d.ts +0 -18
- package/dist/client/http/fetchBanner.d.ts.map +0 -1
- package/dist/client/http/fetchBanner.js +0 -44
- package/dist/client/http/fetchCard.d.ts +0 -18
- package/dist/client/http/fetchCard.d.ts.map +0 -1
- package/dist/client/http/fetchCard.js +0 -46
- package/dist/client/http/fetchEvents.d.ts +0 -18
- package/dist/client/http/fetchEvents.d.ts.map +0 -1
- package/dist/client/http/fetchEvents.js +0 -44
- package/dist/client/http/fetchHero.d.ts +0 -17
- package/dist/client/http/fetchHero.d.ts.map +0 -1
- package/dist/client/http/fetchHero.js +0 -55
- package/dist/client/http/fetchMainInfos.d.ts +0 -17
- package/dist/client/http/fetchMainInfos.d.ts.map +0 -1
- package/dist/client/http/fetchMainInfos.js +0 -44
- package/dist/client/http/fetchVideos.d.ts +0 -13
- package/dist/client/http/fetchVideos.d.ts.map +0 -1
- package/dist/client/http/fetchVideos.js +0 -36
- package/dist/client/http/index.d.ts +0 -19
- package/dist/client/http/index.d.ts.map +0 -1
- package/dist/client/http/index.js +0 -11
- package/dist/error-handling/circuit-breaker.d.ts +0 -262
- package/dist/error-handling/circuit-breaker.d.ts.map +0 -1
- package/dist/error-handling/circuit-breaker.js +0 -550
- package/dist/error-handling/retry.d.ts +0 -194
- package/dist/error-handling/retry.d.ts.map +0 -1
- package/dist/error-handling/retry.js +0 -455
- package/dist/errors/index.d.ts +0 -23
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -40
- package/dist/generated/agents/index.d.ts +0 -8
- package/dist/generated/agents/index.d.ts.map +0 -1
- package/dist/generated/agents/index.js +0 -7
- package/dist/generated/components/index.d.ts +0 -8
- package/dist/generated/components/index.d.ts.map +0 -1
- package/dist/generated/components/index.js +0 -7
- package/dist/generated/functions/index.d.ts +0 -8
- package/dist/generated/functions/index.d.ts.map +0 -1
- package/dist/generated/functions/index.js +0 -7
- package/dist/generated/hooks/index.d.ts +0 -8
- package/dist/generated/hooks/index.d.ts.map +0 -1
- package/dist/generated/hooks/index.js +0 -7
- package/dist/generated/plans/index.d.ts +0 -8
- package/dist/generated/plans/index.d.ts.map +0 -1
- package/dist/generated/plans/index.js +0 -7
- package/dist/generated/prompts/index.d.ts +0 -8
- package/dist/generated/prompts/index.d.ts.map +0 -1
- package/dist/generated/prompts/index.js +0 -7
- package/dist/generated/tools/index.d.ts +0 -8
- package/dist/generated/tools/index.d.ts.map +0 -1
- package/dist/generated/tools/index.js +0 -7
- package/dist/generated/types/supabase.d.ts +0 -193
- package/dist/generated/types/supabase.d.ts.map +0 -1
- package/dist/generated/types/supabase.js +0 -5
- package/dist/optimization/asset-optimizer.d.ts +0 -206
- package/dist/optimization/asset-optimizer.d.ts.map +0 -1
- package/dist/optimization/asset-optimizer.js +0 -336
- package/dist/optimization/build-optimizer.d.ts +0 -202
- package/dist/optimization/build-optimizer.d.ts.map +0 -1
- package/dist/optimization/build-optimizer.js +0 -271
- package/dist/optimization/bundle-analyzer.d.ts +0 -98
- package/dist/optimization/bundle-analyzer.d.ts.map +0 -1
- package/dist/optimization/bundle-analyzer.js +0 -346
- package/dist/optimization/code-splitting.d.ts +0 -121
- package/dist/optimization/code-splitting.d.ts.map +0 -1
- package/dist/optimization/code-splitting.js +0 -261
- package/dist/plugin/index.d.ts +0 -12
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js +0 -4
- package/dist/security/audit.d.ts +0 -188
- package/dist/security/audit.d.ts.map +0 -1
- package/dist/security/audit.js +0 -433
- package/dist/security/auth.d.ts +0 -110
- package/dist/security/auth.d.ts.map +0 -1
- package/dist/security/auth.js +0 -257
- package/dist/security/authorization.d.ts +0 -211
- package/dist/security/authorization.d.ts.map +0 -1
- package/dist/security/authorization.js +0 -492
- package/dist/security/encryption.d.ts +0 -226
- package/dist/security/encryption.d.ts.map +0 -1
- package/dist/security/encryption.js +0 -534
- package/dist/security/gdpr-storage.d.ts +0 -102
- package/dist/security/gdpr-storage.d.ts.map +0 -1
- package/dist/security/gdpr-storage.js +0 -65
- package/dist/security/gdpr.d.ts +0 -320
- package/dist/security/gdpr.d.ts.map +0 -1
- package/dist/security/gdpr.js +0 -531
- package/dist/security/headers.d.ts +0 -184
- package/dist/security/headers.d.ts.map +0 -1
- package/dist/security/headers.js +0 -420
- package/dist/utils/jwt-validation.d.ts +0 -14
- package/dist/utils/jwt-validation.d.ts.map +0 -1
- package/dist/utils/jwt-validation.js +0 -36
- package/dist/utils/request-headers.d.ts +0 -15
- package/dist/utils/request-headers.d.ts.map +0 -1
- package/dist/utils/request-headers.js +0 -31
|
@@ -1,492 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authorization System
|
|
3
|
-
*
|
|
4
|
-
* Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC)
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Authorization system
|
|
8
|
-
*/
|
|
9
|
-
export class AuthorizationSystem {
|
|
10
|
-
roles = new Map();
|
|
11
|
-
policies = new Map();
|
|
12
|
-
/**
|
|
13
|
-
* Register role
|
|
14
|
-
*/
|
|
15
|
-
registerRole(role) {
|
|
16
|
-
this.roles.set(role.id, role);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Get role
|
|
20
|
-
*/
|
|
21
|
-
getRole(roleId) {
|
|
22
|
-
return this.roles.get(roleId);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Register policy
|
|
26
|
-
*/
|
|
27
|
-
registerPolicy(policy) {
|
|
28
|
-
this.policies.set(policy.id, policy);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Check if user has permission (RBAC)
|
|
32
|
-
*/
|
|
33
|
-
hasPermission(userRoles, resource, action) {
|
|
34
|
-
// Get all permissions for user's roles
|
|
35
|
-
const permissions = this.getUserPermissions(userRoles);
|
|
36
|
-
// Check if any permission matches
|
|
37
|
-
return permissions.some((permission) => this.matchesResource(permission.resource, resource) &&
|
|
38
|
-
this.matchesAction(permission.action, action));
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Check access with policies (ABAC)
|
|
42
|
-
*/
|
|
43
|
-
checkAccess(context, resource, action) {
|
|
44
|
-
// Check RBAC first
|
|
45
|
-
if (this.hasPermission(context.user.roles, resource, action)) {
|
|
46
|
-
return { allowed: true };
|
|
47
|
-
}
|
|
48
|
-
// Check policies
|
|
49
|
-
const applicablePolicies = this.getApplicablePolicies(resource, action, context);
|
|
50
|
-
// Sort by priority (higher priority first)
|
|
51
|
-
applicablePolicies.sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
52
|
-
// Apply first matching policy
|
|
53
|
-
for (const policy of applicablePolicies) {
|
|
54
|
-
if (this.evaluateConditions(policy.conditions || [], context)) {
|
|
55
|
-
return {
|
|
56
|
-
allowed: policy.effect === 'allow',
|
|
57
|
-
reason: policy.effect === 'deny' ? `Denied by policy: ${policy.name}` : undefined,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return { allowed: false, reason: 'No matching policy' };
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Get all permissions for roles
|
|
65
|
-
*/
|
|
66
|
-
getUserPermissions(roleIds) {
|
|
67
|
-
const permissions = [];
|
|
68
|
-
const visited = new Set();
|
|
69
|
-
const addRolePermissions = (roleId) => {
|
|
70
|
-
if (visited.has(roleId))
|
|
71
|
-
return;
|
|
72
|
-
visited.add(roleId);
|
|
73
|
-
const role = this.roles.get(roleId);
|
|
74
|
-
if (!role)
|
|
75
|
-
return;
|
|
76
|
-
// Add role permissions
|
|
77
|
-
permissions.push(...role.permissions);
|
|
78
|
-
// Add inherited permissions
|
|
79
|
-
if (role.inherits) {
|
|
80
|
-
role.inherits.forEach((inheritedRoleId) => {
|
|
81
|
-
addRolePermissions(inheritedRoleId);
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
roleIds.forEach(addRolePermissions);
|
|
86
|
-
return permissions;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Get applicable policies
|
|
90
|
-
*/
|
|
91
|
-
getApplicablePolicies(resource, action, _context) {
|
|
92
|
-
return Array.from(this.policies.values()).filter((policy) => {
|
|
93
|
-
// Check if resource matches
|
|
94
|
-
const resourceMatches = policy.resources.some((r) => this.matchesResource(r, resource));
|
|
95
|
-
// Check if action matches
|
|
96
|
-
const actionMatches = policy.actions.some((a) => this.matchesAction(a, action));
|
|
97
|
-
return resourceMatches && actionMatches;
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Match resource pattern
|
|
102
|
-
*/
|
|
103
|
-
matchesResource(pattern, resource) {
|
|
104
|
-
if (pattern === '*')
|
|
105
|
-
return true;
|
|
106
|
-
if (pattern === resource)
|
|
107
|
-
return true;
|
|
108
|
-
// Convert glob pattern to regex
|
|
109
|
-
const regex = new RegExp(`^${pattern.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.')}$`);
|
|
110
|
-
return regex.test(resource);
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Match action pattern
|
|
114
|
-
*/
|
|
115
|
-
matchesAction(pattern, action) {
|
|
116
|
-
if (pattern === '*')
|
|
117
|
-
return true;
|
|
118
|
-
if (pattern === action)
|
|
119
|
-
return true;
|
|
120
|
-
// Support wildcards like "read:*"
|
|
121
|
-
const regex = new RegExp(`^${pattern.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.')}$`);
|
|
122
|
-
return regex.test(action);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Evaluate policy conditions
|
|
126
|
-
*/
|
|
127
|
-
evaluateConditions(conditions, context) {
|
|
128
|
-
return conditions.every((condition) => {
|
|
129
|
-
const value = this.getContextValue(condition.field, context);
|
|
130
|
-
return this.evaluateCondition(condition, value);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Get value from context
|
|
135
|
-
*/
|
|
136
|
-
getContextValue(field, context) {
|
|
137
|
-
const parts = field.split('.');
|
|
138
|
-
let value = context;
|
|
139
|
-
for (const part of parts) {
|
|
140
|
-
if (value && typeof value === 'object' && part in value) {
|
|
141
|
-
value = value[part];
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
return undefined;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return value;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Evaluate single condition
|
|
151
|
-
*/
|
|
152
|
-
evaluateCondition(condition, value) {
|
|
153
|
-
switch (condition.operator) {
|
|
154
|
-
case 'eq':
|
|
155
|
-
return value === condition.value;
|
|
156
|
-
case 'ne':
|
|
157
|
-
return value !== condition.value;
|
|
158
|
-
case 'gt':
|
|
159
|
-
return typeof value === 'number' && value > condition.value;
|
|
160
|
-
case 'gte':
|
|
161
|
-
return typeof value === 'number' && value >= condition.value;
|
|
162
|
-
case 'lt':
|
|
163
|
-
return typeof value === 'number' && value < condition.value;
|
|
164
|
-
case 'lte':
|
|
165
|
-
return typeof value === 'number' && value <= condition.value;
|
|
166
|
-
case 'in':
|
|
167
|
-
return Array.isArray(condition.value) && condition.value.includes(value);
|
|
168
|
-
case 'contains':
|
|
169
|
-
return (typeof value === 'string' &&
|
|
170
|
-
typeof condition.value === 'string' &&
|
|
171
|
-
value.includes(condition.value));
|
|
172
|
-
default:
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Check if user owns resource
|
|
178
|
-
*/
|
|
179
|
-
ownsResource(userId, resource) {
|
|
180
|
-
return resource.owner === userId;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Clear all roles and policies
|
|
184
|
-
*/
|
|
185
|
-
clear() {
|
|
186
|
-
this.roles.clear();
|
|
187
|
-
this.policies.clear();
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Global authorization instance
|
|
192
|
-
*/
|
|
193
|
-
export const authorization = new AuthorizationSystem();
|
|
194
|
-
/**
|
|
195
|
-
* Common roles — aligned with DB schema (`users.role` column)
|
|
196
|
-
* and `UserRoleSchema` in @revealui/contracts.
|
|
197
|
-
*
|
|
198
|
-
* Values: owner | admin | editor | viewer | agent | contributor
|
|
199
|
-
*/
|
|
200
|
-
export const CommonRoles = {
|
|
201
|
-
owner: {
|
|
202
|
-
id: 'owner',
|
|
203
|
-
name: 'Owner',
|
|
204
|
-
description: 'Full control — inherits admin',
|
|
205
|
-
permissions: [{ resource: '*', action: '*' }],
|
|
206
|
-
inherits: ['admin'],
|
|
207
|
-
},
|
|
208
|
-
admin: {
|
|
209
|
-
id: 'admin',
|
|
210
|
-
name: 'Administrator',
|
|
211
|
-
description: 'Full system access',
|
|
212
|
-
permissions: [{ resource: '*', action: '*' }],
|
|
213
|
-
},
|
|
214
|
-
editor: {
|
|
215
|
-
id: 'editor',
|
|
216
|
-
name: 'Editor',
|
|
217
|
-
description: 'Can read and modify content',
|
|
218
|
-
permissions: [
|
|
219
|
-
{ resource: 'content', action: 'read' },
|
|
220
|
-
{ resource: 'content', action: 'create' },
|
|
221
|
-
{ resource: 'content', action: 'update' },
|
|
222
|
-
{ resource: 'profile', action: 'read' },
|
|
223
|
-
{ resource: 'profile', action: 'update' },
|
|
224
|
-
{ resource: 'sites', action: 'read' },
|
|
225
|
-
{ resource: 'marketplace', action: 'read' },
|
|
226
|
-
],
|
|
227
|
-
},
|
|
228
|
-
viewer: {
|
|
229
|
-
id: 'viewer',
|
|
230
|
-
name: 'Viewer',
|
|
231
|
-
description: 'Read-only access',
|
|
232
|
-
permissions: [
|
|
233
|
-
{ resource: 'content', action: 'read' },
|
|
234
|
-
{ resource: 'profile', action: 'read' },
|
|
235
|
-
{ resource: 'sites', action: 'read' },
|
|
236
|
-
{ resource: 'public', action: 'read' },
|
|
237
|
-
],
|
|
238
|
-
},
|
|
239
|
-
agent: {
|
|
240
|
-
id: 'agent',
|
|
241
|
-
name: 'AI Agent',
|
|
242
|
-
description: 'Can execute tasks and read content',
|
|
243
|
-
permissions: [
|
|
244
|
-
{ resource: 'tasks', action: 'create' },
|
|
245
|
-
{ resource: 'tasks', action: 'read' },
|
|
246
|
-
{ resource: 'content', action: 'read' },
|
|
247
|
-
{ resource: 'rag', action: 'read' },
|
|
248
|
-
{ resource: 'rag', action: 'create' },
|
|
249
|
-
],
|
|
250
|
-
},
|
|
251
|
-
contributor: {
|
|
252
|
-
id: 'contributor',
|
|
253
|
-
name: 'Contributor',
|
|
254
|
-
description: 'Can suggest changes — create drafts but not publish or delete',
|
|
255
|
-
permissions: [
|
|
256
|
-
{ resource: 'content', action: 'read' },
|
|
257
|
-
{ resource: 'content', action: 'create' },
|
|
258
|
-
{ resource: 'profile', action: 'read' },
|
|
259
|
-
{ resource: 'profile', action: 'update' },
|
|
260
|
-
],
|
|
261
|
-
},
|
|
262
|
-
};
|
|
263
|
-
/**
|
|
264
|
-
* Permission builder
|
|
265
|
-
*/
|
|
266
|
-
export class PermissionBuilder {
|
|
267
|
-
permission = {};
|
|
268
|
-
resource(resource) {
|
|
269
|
-
this.permission.resource = resource;
|
|
270
|
-
return this;
|
|
271
|
-
}
|
|
272
|
-
action(action) {
|
|
273
|
-
this.permission.action = action;
|
|
274
|
-
return this;
|
|
275
|
-
}
|
|
276
|
-
conditions(conditions) {
|
|
277
|
-
this.permission.conditions = conditions;
|
|
278
|
-
return this;
|
|
279
|
-
}
|
|
280
|
-
build() {
|
|
281
|
-
if (!(this.permission.resource && this.permission.action)) {
|
|
282
|
-
throw new Error('Resource and action are required');
|
|
283
|
-
}
|
|
284
|
-
return this.permission;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Policy builder
|
|
289
|
-
*/
|
|
290
|
-
export class PolicyBuilder {
|
|
291
|
-
policy = {
|
|
292
|
-
effect: 'allow',
|
|
293
|
-
resources: [],
|
|
294
|
-
actions: [],
|
|
295
|
-
conditions: [],
|
|
296
|
-
};
|
|
297
|
-
id(id) {
|
|
298
|
-
this.policy.id = id;
|
|
299
|
-
return this;
|
|
300
|
-
}
|
|
301
|
-
name(name) {
|
|
302
|
-
this.policy.name = name;
|
|
303
|
-
return this;
|
|
304
|
-
}
|
|
305
|
-
allow() {
|
|
306
|
-
this.policy.effect = 'allow';
|
|
307
|
-
return this;
|
|
308
|
-
}
|
|
309
|
-
deny() {
|
|
310
|
-
this.policy.effect = 'deny';
|
|
311
|
-
return this;
|
|
312
|
-
}
|
|
313
|
-
resources(...resources) {
|
|
314
|
-
this.policy.resources = resources;
|
|
315
|
-
return this;
|
|
316
|
-
}
|
|
317
|
-
actions(...actions) {
|
|
318
|
-
this.policy.actions = actions;
|
|
319
|
-
return this;
|
|
320
|
-
}
|
|
321
|
-
condition(field, operator, value) {
|
|
322
|
-
if (!this.policy.conditions) {
|
|
323
|
-
this.policy.conditions = [];
|
|
324
|
-
}
|
|
325
|
-
this.policy.conditions.push({ field, operator, value });
|
|
326
|
-
return this;
|
|
327
|
-
}
|
|
328
|
-
priority(priority) {
|
|
329
|
-
this.policy.priority = priority;
|
|
330
|
-
return this;
|
|
331
|
-
}
|
|
332
|
-
build() {
|
|
333
|
-
if (!(this.policy.id && this.policy.name)) {
|
|
334
|
-
throw new Error('ID and name are required');
|
|
335
|
-
}
|
|
336
|
-
return this.policy;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Authorization decorators
|
|
341
|
-
*/
|
|
342
|
-
export function RequirePermission(resource, action) {
|
|
343
|
-
return (_target, _propertyKey, descriptor) => {
|
|
344
|
-
const originalMethod = descriptor.value;
|
|
345
|
-
descriptor.value = function (...args) {
|
|
346
|
-
const userRoles = this.user?.roles || [];
|
|
347
|
-
if (!authorization.hasPermission(userRoles, resource, action)) {
|
|
348
|
-
throw new Error(`Permission denied: ${resource}:${action}`);
|
|
349
|
-
}
|
|
350
|
-
return originalMethod.apply(this, args);
|
|
351
|
-
};
|
|
352
|
-
return descriptor;
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
export function RequireRole(requiredRole) {
|
|
356
|
-
return (_target, _propertyKey, descriptor) => {
|
|
357
|
-
const originalMethod = descriptor.value;
|
|
358
|
-
descriptor.value = function (...args) {
|
|
359
|
-
const userRoles = this.user?.roles || [];
|
|
360
|
-
if (!userRoles.includes(requiredRole)) {
|
|
361
|
-
throw new Error(`Role required: ${requiredRole}`);
|
|
362
|
-
}
|
|
363
|
-
return originalMethod.apply(this, args);
|
|
364
|
-
};
|
|
365
|
-
return descriptor;
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Authorization middleware
|
|
370
|
-
*/
|
|
371
|
-
export function createAuthorizationMiddleware(getUser, resource, action) {
|
|
372
|
-
return (request, next) => {
|
|
373
|
-
const user = getUser(request);
|
|
374
|
-
if (!authorization.hasPermission(user.roles, resource, action)) {
|
|
375
|
-
throw new Error(`Permission denied: ${resource}:${action}`);
|
|
376
|
-
}
|
|
377
|
-
return next();
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* Resource ownership check
|
|
382
|
-
*/
|
|
383
|
-
export function canAccessResource(userId, userRoles, resource, action) {
|
|
384
|
-
// Check if user has permission
|
|
385
|
-
if (authorization.hasPermission(userRoles, resource.type, action)) {
|
|
386
|
-
return true;
|
|
387
|
-
}
|
|
388
|
-
// Check if user owns the resource
|
|
389
|
-
if (authorization.ownsResource(userId, resource)) {
|
|
390
|
-
return true;
|
|
391
|
-
}
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Attribute-based access control helper
|
|
396
|
-
*/
|
|
397
|
-
export function checkAttributeAccess(context, resource, action, requiredAttributes) {
|
|
398
|
-
// Check basic permission
|
|
399
|
-
const { allowed } = authorization.checkAccess(context, resource, action);
|
|
400
|
-
if (!allowed) {
|
|
401
|
-
return false;
|
|
402
|
-
}
|
|
403
|
-
// Check required attributes
|
|
404
|
-
if (requiredAttributes) {
|
|
405
|
-
const userAttributes = context.user.attributes || {};
|
|
406
|
-
return Object.entries(requiredAttributes).every(([key, value]) => userAttributes[key] === value);
|
|
407
|
-
}
|
|
408
|
-
return true;
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Permission cache for performance
|
|
412
|
-
*/
|
|
413
|
-
export class PermissionCache {
|
|
414
|
-
cache = new Map();
|
|
415
|
-
ttl;
|
|
416
|
-
maxEntries;
|
|
417
|
-
constructor(ttl = 300000, maxEntries = 10_000) {
|
|
418
|
-
// 5 minutes default, 10k max entries
|
|
419
|
-
this.ttl = ttl;
|
|
420
|
-
this.maxEntries = maxEntries;
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Get cached permission
|
|
424
|
-
*/
|
|
425
|
-
get(userId, resource, action) {
|
|
426
|
-
const key = this.getCacheKey(userId, resource, action);
|
|
427
|
-
const cached = this.cache.get(key);
|
|
428
|
-
if (!cached) {
|
|
429
|
-
return undefined;
|
|
430
|
-
}
|
|
431
|
-
// Check expiration
|
|
432
|
-
if (Date.now() > cached.expiresAt) {
|
|
433
|
-
this.cache.delete(key);
|
|
434
|
-
return undefined;
|
|
435
|
-
}
|
|
436
|
-
return cached.allowed;
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Set cached permission
|
|
440
|
-
*/
|
|
441
|
-
set(userId, resource, action, allowed) {
|
|
442
|
-
const key = this.getCacheKey(userId, resource, action);
|
|
443
|
-
// Evict expired entries when approaching max size
|
|
444
|
-
if (this.cache.size >= this.maxEntries) {
|
|
445
|
-
const now = Date.now();
|
|
446
|
-
for (const [k, v] of this.cache) {
|
|
447
|
-
if (now > v.expiresAt)
|
|
448
|
-
this.cache.delete(k);
|
|
449
|
-
}
|
|
450
|
-
// If still over limit after purge, drop oldest entries (FIFO via Map insertion order)
|
|
451
|
-
if (this.cache.size >= this.maxEntries) {
|
|
452
|
-
const excess = this.cache.size - this.maxEntries + 1;
|
|
453
|
-
const keys = this.cache.keys();
|
|
454
|
-
for (let i = 0; i < excess; i++) {
|
|
455
|
-
const next = keys.next();
|
|
456
|
-
if (!next.done)
|
|
457
|
-
this.cache.delete(next.value);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
this.cache.set(key, {
|
|
462
|
-
allowed,
|
|
463
|
-
expiresAt: Date.now() + this.ttl,
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Clear cache for user
|
|
468
|
-
*/
|
|
469
|
-
clearUser(userId) {
|
|
470
|
-
for (const key of this.cache.keys()) {
|
|
471
|
-
if (key.startsWith(`${userId}:`)) {
|
|
472
|
-
this.cache.delete(key);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* Clear all cache
|
|
478
|
-
*/
|
|
479
|
-
clear() {
|
|
480
|
-
this.cache.clear();
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Get cache key
|
|
484
|
-
*/
|
|
485
|
-
getCacheKey(userId, resource, action) {
|
|
486
|
-
return `${userId}:${resource}:${action}`;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Global permission cache
|
|
491
|
-
*/
|
|
492
|
-
export const permissionCache = new PermissionCache();
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Encryption Utilities
|
|
3
|
-
*
|
|
4
|
-
* Data encryption for at-rest and in-transit protection
|
|
5
|
-
*/
|
|
6
|
-
export interface EncryptionConfig {
|
|
7
|
-
algorithm: 'AES-GCM' | 'AES-CTR';
|
|
8
|
-
keySize: 128 | 192 | 256;
|
|
9
|
-
ivSize?: number;
|
|
10
|
-
}
|
|
11
|
-
export interface EncryptedData {
|
|
12
|
-
data: string;
|
|
13
|
-
iv: string;
|
|
14
|
-
tag?: string;
|
|
15
|
-
algorithm: string;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Encryption system
|
|
19
|
-
*/
|
|
20
|
-
export declare class EncryptionSystem {
|
|
21
|
-
private config;
|
|
22
|
-
private keys;
|
|
23
|
-
constructor(config?: Partial<EncryptionConfig>);
|
|
24
|
-
/**
|
|
25
|
-
* Generate encryption key
|
|
26
|
-
*/
|
|
27
|
-
generateKey(keyId?: string): Promise<CryptoKey>;
|
|
28
|
-
/**
|
|
29
|
-
* Import key from raw data
|
|
30
|
-
*/
|
|
31
|
-
importKey(keyData: ArrayBuffer, keyId?: string): Promise<CryptoKey>;
|
|
32
|
-
/**
|
|
33
|
-
* Export key to raw data
|
|
34
|
-
*/
|
|
35
|
-
exportKey(key: CryptoKey): Promise<ArrayBuffer>;
|
|
36
|
-
/**
|
|
37
|
-
* Encrypt data
|
|
38
|
-
*/
|
|
39
|
-
encrypt(data: string, keyOrId: CryptoKey | string): Promise<EncryptedData>;
|
|
40
|
-
/**
|
|
41
|
-
* Decrypt data
|
|
42
|
-
*/
|
|
43
|
-
decrypt(encryptedData: EncryptedData, keyOrId: CryptoKey | string): Promise<string>;
|
|
44
|
-
/**
|
|
45
|
-
* Encrypt object
|
|
46
|
-
*/
|
|
47
|
-
encryptObject<T extends Record<string, unknown>>(obj: T, keyOrId: CryptoKey | string): Promise<EncryptedData>;
|
|
48
|
-
/**
|
|
49
|
-
* Decrypt object
|
|
50
|
-
*/
|
|
51
|
-
decryptObject<T extends Record<string, unknown>>(encryptedData: EncryptedData, keyOrId: CryptoKey | string): Promise<T>;
|
|
52
|
-
/**
|
|
53
|
-
* Hash data
|
|
54
|
-
*/
|
|
55
|
-
hash(data: string, algorithm?: 'SHA-256' | 'SHA-384' | 'SHA-512'): Promise<string>;
|
|
56
|
-
/**
|
|
57
|
-
* Generate random bytes
|
|
58
|
-
*/
|
|
59
|
-
randomBytes(length: number): Uint8Array;
|
|
60
|
-
/**
|
|
61
|
-
* Generate random string
|
|
62
|
-
*/
|
|
63
|
-
randomString(length: number, charset?: string): string;
|
|
64
|
-
/**
|
|
65
|
-
* Convert ArrayBuffer to base64
|
|
66
|
-
*/
|
|
67
|
-
private arrayBufferToBase64;
|
|
68
|
-
/**
|
|
69
|
-
* Convert base64 to ArrayBuffer
|
|
70
|
-
*/
|
|
71
|
-
private base64ToArrayBuffer;
|
|
72
|
-
/**
|
|
73
|
-
* Store key
|
|
74
|
-
*/
|
|
75
|
-
storeKey(keyId: string, key: CryptoKey): void;
|
|
76
|
-
/**
|
|
77
|
-
* Get key
|
|
78
|
-
*/
|
|
79
|
-
getKey(keyId: string): CryptoKey | undefined;
|
|
80
|
-
/**
|
|
81
|
-
* Remove key
|
|
82
|
-
*/
|
|
83
|
-
removeKey(keyId: string): void;
|
|
84
|
-
/**
|
|
85
|
-
* Clear all keys
|
|
86
|
-
*/
|
|
87
|
-
clearKeys(): void;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Global encryption instance
|
|
91
|
-
*/
|
|
92
|
-
export declare const encryption: EncryptionSystem;
|
|
93
|
-
/**
|
|
94
|
-
* Field-level encryption
|
|
95
|
-
*/
|
|
96
|
-
export declare class FieldEncryption {
|
|
97
|
-
private encryption;
|
|
98
|
-
private key;
|
|
99
|
-
constructor(encryption: EncryptionSystem);
|
|
100
|
-
/**
|
|
101
|
-
* Initialize with key
|
|
102
|
-
*/
|
|
103
|
-
initialize(key: CryptoKey): Promise<void>;
|
|
104
|
-
/**
|
|
105
|
-
* Encrypt field
|
|
106
|
-
*/
|
|
107
|
-
encryptField(value: unknown): Promise<EncryptedData>;
|
|
108
|
-
/**
|
|
109
|
-
* Decrypt field
|
|
110
|
-
*/
|
|
111
|
-
decryptField(encryptedData: EncryptedData): Promise<unknown>;
|
|
112
|
-
/**
|
|
113
|
-
* Encrypt object fields
|
|
114
|
-
*/
|
|
115
|
-
encryptFields<T extends Record<string, unknown>>(obj: T, fields: (keyof T)[]): Promise<T>;
|
|
116
|
-
/**
|
|
117
|
-
* Decrypt object fields
|
|
118
|
-
*/
|
|
119
|
-
decryptFields<T extends Record<string, unknown>>(obj: T, fields: (keyof T)[]): Promise<T>;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Key rotation
|
|
123
|
-
*/
|
|
124
|
-
export declare class KeyRotationManager {
|
|
125
|
-
private encryption;
|
|
126
|
-
private currentKeyId;
|
|
127
|
-
private oldKeys;
|
|
128
|
-
private keyCreationDates;
|
|
129
|
-
constructor(encryption: EncryptionSystem, initialKeyId: string);
|
|
130
|
-
/**
|
|
131
|
-
* Rotate to new key
|
|
132
|
-
*/
|
|
133
|
-
rotate(newKeyId: string, newKey: CryptoKey): Promise<void>;
|
|
134
|
-
/**
|
|
135
|
-
* Re-encrypt data with new key
|
|
136
|
-
*/
|
|
137
|
-
reencrypt(encryptedData: EncryptedData, oldKeyId: string): Promise<EncryptedData>;
|
|
138
|
-
/**
|
|
139
|
-
* Get current key ID
|
|
140
|
-
*/
|
|
141
|
-
getCurrentKeyId(): string;
|
|
142
|
-
/**
|
|
143
|
-
* Clean up old keys created before the specified date.
|
|
144
|
-
* Never removes the current active key.
|
|
145
|
-
*/
|
|
146
|
-
cleanupOldKeys(olderThan: Date): void;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Envelope encryption for large data
|
|
150
|
-
*/
|
|
151
|
-
export declare class EnvelopeEncryption {
|
|
152
|
-
private encryption;
|
|
153
|
-
private masterKey;
|
|
154
|
-
constructor(encryption: EncryptionSystem, masterKey: CryptoKey);
|
|
155
|
-
/**
|
|
156
|
-
* Encrypt with envelope encryption
|
|
157
|
-
*/
|
|
158
|
-
encrypt(data: string): Promise<{
|
|
159
|
-
encryptedData: EncryptedData;
|
|
160
|
-
encryptedKey: EncryptedData;
|
|
161
|
-
}>;
|
|
162
|
-
/**
|
|
163
|
-
* Decrypt with envelope encryption
|
|
164
|
-
*/
|
|
165
|
-
decrypt(encryptedData: EncryptedData, encryptedKey: EncryptedData): Promise<string>;
|
|
166
|
-
private arrayBufferToBase64;
|
|
167
|
-
private base64ToArrayBuffer;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Data masking utilities
|
|
171
|
-
*/
|
|
172
|
-
/**
|
|
173
|
-
* Mask email
|
|
174
|
-
*/
|
|
175
|
-
declare function maskEmail(email: string): string;
|
|
176
|
-
/**
|
|
177
|
-
* Mask phone number
|
|
178
|
-
*/
|
|
179
|
-
declare function maskPhone(phone: string): string;
|
|
180
|
-
/**
|
|
181
|
-
* Mask credit card
|
|
182
|
-
*/
|
|
183
|
-
declare function maskCreditCard(card: string): string;
|
|
184
|
-
/**
|
|
185
|
-
* Mask SSN
|
|
186
|
-
*/
|
|
187
|
-
declare function maskSSN(ssn: string): string;
|
|
188
|
-
/**
|
|
189
|
-
* Mask string (keep first and last character)
|
|
190
|
-
*/
|
|
191
|
-
declare function maskString(str: string, keepChars?: number): string;
|
|
192
|
-
export declare const DataMasking: {
|
|
193
|
-
readonly maskEmail: typeof maskEmail;
|
|
194
|
-
readonly maskPhone: typeof maskPhone;
|
|
195
|
-
readonly maskCreditCard: typeof maskCreditCard;
|
|
196
|
-
readonly maskSSN: typeof maskSSN;
|
|
197
|
-
readonly maskString: typeof maskString;
|
|
198
|
-
};
|
|
199
|
-
/**
|
|
200
|
-
* Secure random token generator
|
|
201
|
-
*/
|
|
202
|
-
/**
|
|
203
|
-
* Generate secure token. `length` is the number of random bytes;
|
|
204
|
-
* the returned string is hex-encoded, so it will be `length * 2` characters.
|
|
205
|
-
*/
|
|
206
|
-
declare function generateToken(length?: number): string;
|
|
207
|
-
/**
|
|
208
|
-
* Generate UUID v4
|
|
209
|
-
*/
|
|
210
|
-
declare function generateUUID(): string;
|
|
211
|
-
/**
|
|
212
|
-
* Generate API key
|
|
213
|
-
*/
|
|
214
|
-
declare function generateAPIKey(prefix?: string): string;
|
|
215
|
-
/**
|
|
216
|
-
* Generate session ID
|
|
217
|
-
*/
|
|
218
|
-
declare function generateSessionID(): string;
|
|
219
|
-
export declare const TokenGenerator: {
|
|
220
|
-
readonly generate: typeof generateToken;
|
|
221
|
-
readonly generateUUID: typeof generateUUID;
|
|
222
|
-
readonly generateAPIKey: typeof generateAPIKey;
|
|
223
|
-
readonly generateSessionID: typeof generateSessionID;
|
|
224
|
-
};
|
|
225
|
-
export {};
|
|
226
|
-
//# sourceMappingURL=encryption.d.ts.map
|