@objectstack/core 1.0.4 → 1.0.5
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/.turbo/turbo-build.log +58 -0
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +4294 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1777 -0
- package/dist/index.d.ts +1776 -21
- package/dist/index.js +4246 -23
- package/dist/index.js.map +1 -0
- package/package.json +4 -4
- package/tsconfig.json +1 -3
- package/dist/api-registry-plugin.d.ts +0 -54
- package/dist/api-registry-plugin.d.ts.map +0 -1
- package/dist/api-registry-plugin.js +0 -53
- package/dist/api-registry-plugin.test.d.ts +0 -2
- package/dist/api-registry-plugin.test.d.ts.map +0 -1
- package/dist/api-registry-plugin.test.js +0 -334
- package/dist/api-registry.d.ts +0 -259
- package/dist/api-registry.d.ts.map +0 -1
- package/dist/api-registry.js +0 -600
- package/dist/api-registry.test.d.ts +0 -2
- package/dist/api-registry.test.d.ts.map +0 -1
- package/dist/api-registry.test.js +0 -957
- package/dist/contracts/data-engine.d.ts +0 -62
- package/dist/contracts/data-engine.d.ts.map +0 -1
- package/dist/contracts/data-engine.js +0 -1
- package/dist/contracts/http-server.d.ts +0 -119
- package/dist/contracts/http-server.d.ts.map +0 -1
- package/dist/contracts/http-server.js +0 -11
- package/dist/contracts/logger.d.ts +0 -63
- package/dist/contracts/logger.d.ts.map +0 -1
- package/dist/contracts/logger.js +0 -1
- package/dist/dependency-resolver.d.ts +0 -62
- package/dist/dependency-resolver.d.ts.map +0 -1
- package/dist/dependency-resolver.js +0 -317
- package/dist/dependency-resolver.test.d.ts +0 -2
- package/dist/dependency-resolver.test.d.ts.map +0 -1
- package/dist/dependency-resolver.test.js +0 -241
- package/dist/health-monitor.d.ts +0 -65
- package/dist/health-monitor.d.ts.map +0 -1
- package/dist/health-monitor.js +0 -269
- package/dist/health-monitor.test.d.ts +0 -2
- package/dist/health-monitor.test.d.ts.map +0 -1
- package/dist/health-monitor.test.js +0 -68
- package/dist/hot-reload.d.ts +0 -79
- package/dist/hot-reload.d.ts.map +0 -1
- package/dist/hot-reload.js +0 -313
- package/dist/index.d.ts.map +0 -1
- package/dist/kernel-base.d.ts +0 -84
- package/dist/kernel-base.d.ts.map +0 -1
- package/dist/kernel-base.js +0 -219
- package/dist/kernel.d.ts +0 -113
- package/dist/kernel.d.ts.map +0 -1
- package/dist/kernel.js +0 -472
- package/dist/kernel.test.d.ts +0 -2
- package/dist/kernel.test.d.ts.map +0 -1
- package/dist/kernel.test.js +0 -414
- package/dist/lite-kernel.d.ts +0 -55
- package/dist/lite-kernel.d.ts.map +0 -1
- package/dist/lite-kernel.js +0 -112
- package/dist/lite-kernel.test.d.ts +0 -2
- package/dist/lite-kernel.test.d.ts.map +0 -1
- package/dist/lite-kernel.test.js +0 -161
- package/dist/logger.d.ts +0 -71
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -312
- package/dist/logger.test.d.ts +0 -2
- package/dist/logger.test.d.ts.map +0 -1
- package/dist/logger.test.js +0 -92
- package/dist/plugin-loader.d.ts +0 -164
- package/dist/plugin-loader.d.ts.map +0 -1
- package/dist/plugin-loader.js +0 -319
- package/dist/plugin-loader.test.d.ts +0 -2
- package/dist/plugin-loader.test.d.ts.map +0 -1
- package/dist/plugin-loader.test.js +0 -348
- package/dist/qa/adapter.d.ts +0 -14
- package/dist/qa/adapter.d.ts.map +0 -1
- package/dist/qa/adapter.js +0 -1
- package/dist/qa/http-adapter.d.ts +0 -16
- package/dist/qa/http-adapter.d.ts.map +0 -1
- package/dist/qa/http-adapter.js +0 -107
- package/dist/qa/index.d.ts +0 -4
- package/dist/qa/index.d.ts.map +0 -1
- package/dist/qa/index.js +0 -3
- package/dist/qa/runner.d.ts +0 -27
- package/dist/qa/runner.d.ts.map +0 -1
- package/dist/qa/runner.js +0 -157
- package/dist/security/index.d.ts +0 -17
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -17
- package/dist/security/permission-manager.d.ts +0 -96
- package/dist/security/permission-manager.d.ts.map +0 -1
- package/dist/security/permission-manager.js +0 -235
- package/dist/security/permission-manager.test.d.ts +0 -2
- package/dist/security/permission-manager.test.d.ts.map +0 -1
- package/dist/security/permission-manager.test.js +0 -220
- package/dist/security/plugin-config-validator.d.ts +0 -79
- package/dist/security/plugin-config-validator.d.ts.map +0 -1
- package/dist/security/plugin-config-validator.js +0 -166
- package/dist/security/plugin-config-validator.test.d.ts +0 -2
- package/dist/security/plugin-config-validator.test.d.ts.map +0 -1
- package/dist/security/plugin-config-validator.test.js +0 -223
- package/dist/security/plugin-permission-enforcer.d.ts +0 -154
- package/dist/security/plugin-permission-enforcer.d.ts.map +0 -1
- package/dist/security/plugin-permission-enforcer.js +0 -323
- package/dist/security/plugin-permission-enforcer.test.d.ts +0 -2
- package/dist/security/plugin-permission-enforcer.test.d.ts.map +0 -1
- package/dist/security/plugin-permission-enforcer.test.js +0 -205
- package/dist/security/plugin-signature-verifier.d.ts +0 -96
- package/dist/security/plugin-signature-verifier.d.ts.map +0 -1
- package/dist/security/plugin-signature-verifier.js +0 -250
- package/dist/security/sandbox-runtime.d.ts +0 -115
- package/dist/security/sandbox-runtime.d.ts.map +0 -1
- package/dist/security/sandbox-runtime.js +0 -311
- package/dist/security/security-scanner.d.ts +0 -92
- package/dist/security/security-scanner.d.ts.map +0 -1
- package/dist/security/security-scanner.js +0 -273
- package/dist/types.d.ts +0 -89
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/env.d.ts +0 -20
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/env.js +0 -46
- package/dist/utils/env.test.d.ts +0 -2
- package/dist/utils/env.test.d.ts.map +0 -1
- package/dist/utils/env.test.js +0 -52
package/dist/qa/runner.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
export class TestRunner {
|
|
2
|
-
constructor(adapter) {
|
|
3
|
-
this.adapter = adapter;
|
|
4
|
-
}
|
|
5
|
-
async runSuite(suite) {
|
|
6
|
-
const results = [];
|
|
7
|
-
for (const scenario of suite.scenarios) {
|
|
8
|
-
results.push(await this.runScenario(scenario));
|
|
9
|
-
}
|
|
10
|
-
return results;
|
|
11
|
-
}
|
|
12
|
-
async runScenario(scenario) {
|
|
13
|
-
const startTime = Date.now();
|
|
14
|
-
const context = {}; // Variable context
|
|
15
|
-
// Initialize context from initial payload if needed? Currently schema doesn't have initial context prop on Scenario
|
|
16
|
-
// But we defined TestContextSchema separately.
|
|
17
|
-
// Setup
|
|
18
|
-
if (scenario.setup) {
|
|
19
|
-
for (const step of scenario.setup) {
|
|
20
|
-
try {
|
|
21
|
-
await this.runStep(step, context);
|
|
22
|
-
}
|
|
23
|
-
catch (e) {
|
|
24
|
-
return {
|
|
25
|
-
scenarioId: scenario.id,
|
|
26
|
-
passed: false,
|
|
27
|
-
steps: [],
|
|
28
|
-
error: `Setup failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
29
|
-
duration: Date.now() - startTime
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const stepResults = [];
|
|
35
|
-
let scenarioPassed = true;
|
|
36
|
-
let scenarioError = undefined;
|
|
37
|
-
// Main Steps
|
|
38
|
-
for (const step of scenario.steps) {
|
|
39
|
-
const stepStartTime = Date.now();
|
|
40
|
-
try {
|
|
41
|
-
const output = await this.runStep(step, context);
|
|
42
|
-
stepResults.push({
|
|
43
|
-
stepName: step.name,
|
|
44
|
-
passed: true,
|
|
45
|
-
output,
|
|
46
|
-
duration: Date.now() - stepStartTime
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
scenarioPassed = false;
|
|
51
|
-
scenarioError = e;
|
|
52
|
-
stepResults.push({
|
|
53
|
-
stepName: step.name,
|
|
54
|
-
passed: false,
|
|
55
|
-
error: e,
|
|
56
|
-
duration: Date.now() - stepStartTime
|
|
57
|
-
});
|
|
58
|
-
break; // Stop on first failure
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Teardown (run even if failed)
|
|
62
|
-
if (scenario.teardown) {
|
|
63
|
-
for (const step of scenario.teardown) {
|
|
64
|
-
try {
|
|
65
|
-
await this.runStep(step, context);
|
|
66
|
-
}
|
|
67
|
-
catch (e) {
|
|
68
|
-
// Log teardown failure but don't override main failure if it exists
|
|
69
|
-
if (scenarioPassed) {
|
|
70
|
-
scenarioPassed = false;
|
|
71
|
-
scenarioError = `Teardown failed: ${e instanceof Error ? e.message : String(e)}`;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
scenarioId: scenario.id,
|
|
78
|
-
passed: scenarioPassed,
|
|
79
|
-
steps: stepResults,
|
|
80
|
-
error: scenarioError,
|
|
81
|
-
duration: Date.now() - startTime
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
async runStep(step, context) {
|
|
85
|
-
// 1. Resolve Variables with Context (Simple interpolation or just pass context?)
|
|
86
|
-
// For now, assume adpater handles context resolution or we do basic replacement
|
|
87
|
-
const resolvedAction = this.resolveVariables(step.action, context);
|
|
88
|
-
// 2. Execute Action
|
|
89
|
-
const result = await this.adapter.execute(resolvedAction, context);
|
|
90
|
-
// 3. Capture Outputs
|
|
91
|
-
if (step.capture) {
|
|
92
|
-
for (const [varName, path] of Object.entries(step.capture)) {
|
|
93
|
-
context[varName] = this.getValueByPath(result, path);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// 4. Run Assertions
|
|
97
|
-
if (step.assertions) {
|
|
98
|
-
for (const assertion of step.assertions) {
|
|
99
|
-
this.assert(result, assertion, context);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
resolveVariables(action, _context) {
|
|
105
|
-
// TODO: Implement JSON path variable substitution stringify/parse
|
|
106
|
-
// For now returning as is
|
|
107
|
-
return action;
|
|
108
|
-
}
|
|
109
|
-
getValueByPath(obj, path) {
|
|
110
|
-
if (!path)
|
|
111
|
-
return obj;
|
|
112
|
-
const parts = path.split('.');
|
|
113
|
-
let current = obj;
|
|
114
|
-
for (const part of parts) {
|
|
115
|
-
if (current === null || current === undefined)
|
|
116
|
-
return undefined;
|
|
117
|
-
current = current[part];
|
|
118
|
-
}
|
|
119
|
-
return current;
|
|
120
|
-
}
|
|
121
|
-
assert(result, assertion, _context) {
|
|
122
|
-
const actual = this.getValueByPath(result, assertion.field);
|
|
123
|
-
// Resolve expected value if it's a variable ref?
|
|
124
|
-
const expected = assertion.expectedValue; // Simplify for now
|
|
125
|
-
switch (assertion.operator) {
|
|
126
|
-
case 'equals':
|
|
127
|
-
if (actual !== expected)
|
|
128
|
-
throw new Error(`Assertion failed: ${assertion.field} expected ${expected}, got ${actual}`);
|
|
129
|
-
break;
|
|
130
|
-
case 'not_equals':
|
|
131
|
-
if (actual === expected)
|
|
132
|
-
throw new Error(`Assertion failed: ${assertion.field} expected not ${expected}, got ${actual}`);
|
|
133
|
-
break;
|
|
134
|
-
case 'contains':
|
|
135
|
-
if (Array.isArray(actual)) {
|
|
136
|
-
if (!actual.includes(expected))
|
|
137
|
-
throw new Error(`Assertion failed: ${assertion.field} array does not contain ${expected}`);
|
|
138
|
-
}
|
|
139
|
-
else if (typeof actual === 'string') {
|
|
140
|
-
if (!actual.includes(String(expected)))
|
|
141
|
-
throw new Error(`Assertion failed: ${assertion.field} string does not contain ${expected}`);
|
|
142
|
-
}
|
|
143
|
-
break;
|
|
144
|
-
case 'not_null':
|
|
145
|
-
if (actual === null || actual === undefined)
|
|
146
|
-
throw new Error(`Assertion failed: ${assertion.field} is null`);
|
|
147
|
-
break;
|
|
148
|
-
case 'is_null':
|
|
149
|
-
if (actual !== null && actual !== undefined)
|
|
150
|
-
throw new Error(`Assertion failed: ${assertion.field} is not null`);
|
|
151
|
-
break;
|
|
152
|
-
// ... Add other operators
|
|
153
|
-
default:
|
|
154
|
-
throw new Error(`Unknown assertion operator: ${assertion.operator}`);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
package/dist/security/index.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security Module
|
|
3
|
-
*
|
|
4
|
-
* Provides security features for the ObjectStack microkernel:
|
|
5
|
-
* - Plugin signature verification
|
|
6
|
-
* - Plugin configuration validation
|
|
7
|
-
* - Permission and capability enforcement
|
|
8
|
-
*
|
|
9
|
-
* @module @objectstack/core/security
|
|
10
|
-
*/
|
|
11
|
-
export { PluginSignatureVerifier, type PluginSignatureConfig, type SignatureVerificationResult, } from './plugin-signature-verifier.js';
|
|
12
|
-
export { PluginConfigValidator, createPluginConfigValidator, } from './plugin-config-validator.js';
|
|
13
|
-
export { PluginPermissionEnforcer, SecurePluginContext, createPluginPermissionEnforcer, type PluginPermissions, type PermissionCheckResult, } from './plugin-permission-enforcer.js';
|
|
14
|
-
export { PluginPermissionManager, type PermissionGrant, type PermissionCheckResult as PluginPermissionCheckResult, } from './permission-manager.js';
|
|
15
|
-
export { PluginSandboxRuntime, type SandboxContext, type ResourceUsage, } from './sandbox-runtime.js';
|
|
16
|
-
export { PluginSecurityScanner, type ScanTarget, type SecurityIssue, } from './security-scanner.js';
|
|
17
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,8BAA8B,EAC9B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,IAAI,2BAA2B,GAC1D,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,qBAAqB,EACrB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,uBAAuB,CAAC"}
|
package/dist/security/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security Module
|
|
3
|
-
*
|
|
4
|
-
* Provides security features for the ObjectStack microkernel:
|
|
5
|
-
* - Plugin signature verification
|
|
6
|
-
* - Plugin configuration validation
|
|
7
|
-
* - Permission and capability enforcement
|
|
8
|
-
*
|
|
9
|
-
* @module @objectstack/core/security
|
|
10
|
-
*/
|
|
11
|
-
export { PluginSignatureVerifier, } from './plugin-signature-verifier.js';
|
|
12
|
-
export { PluginConfigValidator, createPluginConfigValidator, } from './plugin-config-validator.js';
|
|
13
|
-
export { PluginPermissionEnforcer, SecurePluginContext, createPluginPermissionEnforcer, } from './plugin-permission-enforcer.js';
|
|
14
|
-
// Advanced security components (Phase 2)
|
|
15
|
-
export { PluginPermissionManager, } from './permission-manager.js';
|
|
16
|
-
export { PluginSandboxRuntime, } from './sandbox-runtime.js';
|
|
17
|
-
export { PluginSecurityScanner, } from './security-scanner.js';
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { Permission, PermissionSet, PermissionAction, ResourceType } from '@objectstack/spec/kernel';
|
|
2
|
-
import type { ObjectLogger } from '../logger.js';
|
|
3
|
-
/**
|
|
4
|
-
* Permission Grant
|
|
5
|
-
* Represents a granted permission at runtime
|
|
6
|
-
*/
|
|
7
|
-
export interface PermissionGrant {
|
|
8
|
-
permissionId: string;
|
|
9
|
-
pluginId: string;
|
|
10
|
-
grantedAt: Date;
|
|
11
|
-
grantedBy?: string;
|
|
12
|
-
expiresAt?: Date;
|
|
13
|
-
conditions?: Record<string, any>;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Permission Check Result
|
|
17
|
-
*/
|
|
18
|
-
export interface PermissionCheckResult {
|
|
19
|
-
allowed: boolean;
|
|
20
|
-
reason?: string;
|
|
21
|
-
requiredPermission?: string;
|
|
22
|
-
grantedPermissions?: string[];
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Plugin Permission Manager
|
|
26
|
-
*
|
|
27
|
-
* Manages fine-grained permissions for plugin security and access control
|
|
28
|
-
*/
|
|
29
|
-
export declare class PluginPermissionManager {
|
|
30
|
-
private logger;
|
|
31
|
-
private permissionSets;
|
|
32
|
-
private grants;
|
|
33
|
-
private grantDetails;
|
|
34
|
-
constructor(logger: ObjectLogger);
|
|
35
|
-
/**
|
|
36
|
-
* Register permission requirements for a plugin
|
|
37
|
-
*/
|
|
38
|
-
registerPermissions(pluginId: string, permissionSet: PermissionSet): void;
|
|
39
|
-
/**
|
|
40
|
-
* Grant a permission to a plugin
|
|
41
|
-
*/
|
|
42
|
-
grantPermission(pluginId: string, permissionId: string, grantedBy?: string, expiresAt?: Date): void;
|
|
43
|
-
/**
|
|
44
|
-
* Revoke a permission from a plugin
|
|
45
|
-
*/
|
|
46
|
-
revokePermission(pluginId: string, permissionId: string): void;
|
|
47
|
-
/**
|
|
48
|
-
* Grant all permissions for a plugin
|
|
49
|
-
*/
|
|
50
|
-
grantAllPermissions(pluginId: string, grantedBy?: string): void;
|
|
51
|
-
/**
|
|
52
|
-
* Check if a plugin has a specific permission
|
|
53
|
-
*/
|
|
54
|
-
hasPermission(pluginId: string, permissionId: string): boolean;
|
|
55
|
-
/**
|
|
56
|
-
* Check if plugin can perform an action on a resource
|
|
57
|
-
*/
|
|
58
|
-
checkAccess(pluginId: string, resource: ResourceType, action: PermissionAction, resourceId?: string): PermissionCheckResult;
|
|
59
|
-
/**
|
|
60
|
-
* Get all permissions for a plugin
|
|
61
|
-
*/
|
|
62
|
-
getPluginPermissions(pluginId: string): Permission[];
|
|
63
|
-
/**
|
|
64
|
-
* Get granted permissions for a plugin
|
|
65
|
-
*/
|
|
66
|
-
getGrantedPermissions(pluginId: string): string[];
|
|
67
|
-
/**
|
|
68
|
-
* Get required but not granted permissions
|
|
69
|
-
*/
|
|
70
|
-
getMissingPermissions(pluginId: string): Permission[];
|
|
71
|
-
/**
|
|
72
|
-
* Check if all required permissions are granted
|
|
73
|
-
*/
|
|
74
|
-
hasAllRequiredPermissions(pluginId: string): boolean;
|
|
75
|
-
/**
|
|
76
|
-
* Get permission grant details
|
|
77
|
-
*/
|
|
78
|
-
getGrantDetails(pluginId: string, permissionId: string): PermissionGrant | undefined;
|
|
79
|
-
/**
|
|
80
|
-
* Validate permission against scope constraints
|
|
81
|
-
*/
|
|
82
|
-
validatePermissionScope(permission: Permission, context: {
|
|
83
|
-
tenantId?: string;
|
|
84
|
-
userId?: string;
|
|
85
|
-
resourceId?: string;
|
|
86
|
-
}): boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Clear all permissions for a plugin
|
|
89
|
-
*/
|
|
90
|
-
clearPluginPermissions(pluginId: string): void;
|
|
91
|
-
/**
|
|
92
|
-
* Shutdown permission manager
|
|
93
|
-
*/
|
|
94
|
-
shutdown(): void;
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=permission-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permission-manager.d.ts","sourceRoot":"","sources":["../../src/security/permission-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,YAAY,EACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAe;IAG7B,OAAO,CAAC,cAAc,CAAoC;IAG1D,OAAO,CAAC,MAAM,CAAkC;IAGhD,OAAO,CAAC,YAAY,CAAsC;gBAE9C,MAAM,EAAE,YAAY;IAIhC;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI;IASzE;;OAEG;IACH,eAAe,CACb,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,IAAI,GACf,IAAI;IAmCP;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAY9D;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAa/D;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAsB9D;;OAEG;IACH,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,gBAAgB,EACxB,UAAU,CAAC,EAAE,MAAM,GAClB,qBAAqB;IAyDxB;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAKpD;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAKjD;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAarD;;OAEG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIpD;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAKpF;;OAEG;IACH,uBAAuB,CACrB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACA,OAAO;IAsBV;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAe9C;;OAEG;IACH,QAAQ,IAAI,IAAI;CAOjB"}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin Permission Manager
|
|
3
|
-
*
|
|
4
|
-
* Manages fine-grained permissions for plugin security and access control
|
|
5
|
-
*/
|
|
6
|
-
export class PluginPermissionManager {
|
|
7
|
-
constructor(logger) {
|
|
8
|
-
// Plugin permission definitions
|
|
9
|
-
this.permissionSets = new Map();
|
|
10
|
-
// Granted permissions (pluginId -> Set of permission IDs)
|
|
11
|
-
this.grants = new Map();
|
|
12
|
-
// Permission grant details
|
|
13
|
-
this.grantDetails = new Map();
|
|
14
|
-
this.logger = logger.child({ component: 'PermissionManager' });
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Register permission requirements for a plugin
|
|
18
|
-
*/
|
|
19
|
-
registerPermissions(pluginId, permissionSet) {
|
|
20
|
-
this.permissionSets.set(pluginId, permissionSet);
|
|
21
|
-
this.logger.info('Permissions registered for plugin', {
|
|
22
|
-
pluginId,
|
|
23
|
-
permissionCount: permissionSet.permissions.length
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Grant a permission to a plugin
|
|
28
|
-
*/
|
|
29
|
-
grantPermission(pluginId, permissionId, grantedBy, expiresAt) {
|
|
30
|
-
// Verify permission exists in plugin's declared permissions
|
|
31
|
-
const permissionSet = this.permissionSets.get(pluginId);
|
|
32
|
-
if (!permissionSet) {
|
|
33
|
-
throw new Error(`No permissions registered for plugin: ${pluginId}`);
|
|
34
|
-
}
|
|
35
|
-
const permission = permissionSet.permissions.find(p => p.id === permissionId);
|
|
36
|
-
if (!permission) {
|
|
37
|
-
throw new Error(`Permission ${permissionId} not declared by plugin ${pluginId}`);
|
|
38
|
-
}
|
|
39
|
-
// Create grant
|
|
40
|
-
if (!this.grants.has(pluginId)) {
|
|
41
|
-
this.grants.set(pluginId, new Set());
|
|
42
|
-
}
|
|
43
|
-
this.grants.get(pluginId).add(permissionId);
|
|
44
|
-
// Store grant details
|
|
45
|
-
const grantKey = `${pluginId}:${permissionId}`;
|
|
46
|
-
this.grantDetails.set(grantKey, {
|
|
47
|
-
permissionId,
|
|
48
|
-
pluginId,
|
|
49
|
-
grantedAt: new Date(),
|
|
50
|
-
grantedBy,
|
|
51
|
-
expiresAt,
|
|
52
|
-
});
|
|
53
|
-
this.logger.info('Permission granted', {
|
|
54
|
-
pluginId,
|
|
55
|
-
permissionId,
|
|
56
|
-
grantedBy
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Revoke a permission from a plugin
|
|
61
|
-
*/
|
|
62
|
-
revokePermission(pluginId, permissionId) {
|
|
63
|
-
const grants = this.grants.get(pluginId);
|
|
64
|
-
if (grants) {
|
|
65
|
-
grants.delete(permissionId);
|
|
66
|
-
const grantKey = `${pluginId}:${permissionId}`;
|
|
67
|
-
this.grantDetails.delete(grantKey);
|
|
68
|
-
this.logger.info('Permission revoked', { pluginId, permissionId });
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Grant all permissions for a plugin
|
|
73
|
-
*/
|
|
74
|
-
grantAllPermissions(pluginId, grantedBy) {
|
|
75
|
-
const permissionSet = this.permissionSets.get(pluginId);
|
|
76
|
-
if (!permissionSet) {
|
|
77
|
-
throw new Error(`No permissions registered for plugin: ${pluginId}`);
|
|
78
|
-
}
|
|
79
|
-
for (const permission of permissionSet.permissions) {
|
|
80
|
-
this.grantPermission(pluginId, permission.id, grantedBy);
|
|
81
|
-
}
|
|
82
|
-
this.logger.info('All permissions granted', { pluginId, grantedBy });
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Check if a plugin has a specific permission
|
|
86
|
-
*/
|
|
87
|
-
hasPermission(pluginId, permissionId) {
|
|
88
|
-
const grants = this.grants.get(pluginId);
|
|
89
|
-
if (!grants) {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
// Check if granted
|
|
93
|
-
if (!grants.has(permissionId)) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
// Check expiration
|
|
97
|
-
const grantKey = `${pluginId}:${permissionId}`;
|
|
98
|
-
const grantDetails = this.grantDetails.get(grantKey);
|
|
99
|
-
if (grantDetails?.expiresAt && grantDetails.expiresAt < new Date()) {
|
|
100
|
-
this.revokePermission(pluginId, permissionId);
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Check if plugin can perform an action on a resource
|
|
107
|
-
*/
|
|
108
|
-
checkAccess(pluginId, resource, action, resourceId) {
|
|
109
|
-
const permissionSet = this.permissionSets.get(pluginId);
|
|
110
|
-
if (!permissionSet) {
|
|
111
|
-
return {
|
|
112
|
-
allowed: false,
|
|
113
|
-
reason: 'No permissions registered for plugin',
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
// Find matching permissions
|
|
117
|
-
const matchingPermissions = permissionSet.permissions.filter(p => {
|
|
118
|
-
// Check resource type
|
|
119
|
-
if (p.resource !== resource) {
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
// Check action
|
|
123
|
-
if (!p.actions.includes(action)) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
// Check resource filter if specified
|
|
127
|
-
if (resourceId && p.filter?.resourceIds) {
|
|
128
|
-
if (!p.filter.resourceIds.includes(resourceId)) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return true;
|
|
133
|
-
});
|
|
134
|
-
if (matchingPermissions.length === 0) {
|
|
135
|
-
return {
|
|
136
|
-
allowed: false,
|
|
137
|
-
reason: `No permission found for ${action} on ${resource}`,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
// Check if any matching permission is granted
|
|
141
|
-
const grantedPermissions = matchingPermissions.filter(p => this.hasPermission(pluginId, p.id));
|
|
142
|
-
if (grantedPermissions.length === 0) {
|
|
143
|
-
return {
|
|
144
|
-
allowed: false,
|
|
145
|
-
reason: 'Required permissions not granted',
|
|
146
|
-
requiredPermission: matchingPermissions[0].id,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
return {
|
|
150
|
-
allowed: true,
|
|
151
|
-
grantedPermissions: grantedPermissions.map(p => p.id),
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Get all permissions for a plugin
|
|
156
|
-
*/
|
|
157
|
-
getPluginPermissions(pluginId) {
|
|
158
|
-
const permissionSet = this.permissionSets.get(pluginId);
|
|
159
|
-
return permissionSet?.permissions || [];
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Get granted permissions for a plugin
|
|
163
|
-
*/
|
|
164
|
-
getGrantedPermissions(pluginId) {
|
|
165
|
-
const grants = this.grants.get(pluginId);
|
|
166
|
-
return grants ? Array.from(grants) : [];
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Get required but not granted permissions
|
|
170
|
-
*/
|
|
171
|
-
getMissingPermissions(pluginId) {
|
|
172
|
-
const permissionSet = this.permissionSets.get(pluginId);
|
|
173
|
-
if (!permissionSet) {
|
|
174
|
-
return [];
|
|
175
|
-
}
|
|
176
|
-
const granted = this.grants.get(pluginId) || new Set();
|
|
177
|
-
return permissionSet.permissions.filter(p => p.required && !granted.has(p.id));
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Check if all required permissions are granted
|
|
181
|
-
*/
|
|
182
|
-
hasAllRequiredPermissions(pluginId) {
|
|
183
|
-
return this.getMissingPermissions(pluginId).length === 0;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Get permission grant details
|
|
187
|
-
*/
|
|
188
|
-
getGrantDetails(pluginId, permissionId) {
|
|
189
|
-
const grantKey = `${pluginId}:${permissionId}`;
|
|
190
|
-
return this.grantDetails.get(grantKey);
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Validate permission against scope constraints
|
|
194
|
-
*/
|
|
195
|
-
validatePermissionScope(permission, context) {
|
|
196
|
-
switch (permission.scope) {
|
|
197
|
-
case 'global':
|
|
198
|
-
return true;
|
|
199
|
-
case 'tenant':
|
|
200
|
-
return !!context.tenantId;
|
|
201
|
-
case 'user':
|
|
202
|
-
return !!context.userId;
|
|
203
|
-
case 'resource':
|
|
204
|
-
return !!context.resourceId;
|
|
205
|
-
case 'plugin':
|
|
206
|
-
return true;
|
|
207
|
-
default:
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Clear all permissions for a plugin
|
|
213
|
-
*/
|
|
214
|
-
clearPluginPermissions(pluginId) {
|
|
215
|
-
this.permissionSets.delete(pluginId);
|
|
216
|
-
const grants = this.grants.get(pluginId);
|
|
217
|
-
if (grants) {
|
|
218
|
-
for (const permissionId of grants) {
|
|
219
|
-
const grantKey = `${pluginId}:${permissionId}`;
|
|
220
|
-
this.grantDetails.delete(grantKey);
|
|
221
|
-
}
|
|
222
|
-
this.grants.delete(pluginId);
|
|
223
|
-
}
|
|
224
|
-
this.logger.info('All permissions cleared', { pluginId });
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Shutdown permission manager
|
|
228
|
-
*/
|
|
229
|
-
shutdown() {
|
|
230
|
-
this.permissionSets.clear();
|
|
231
|
-
this.grants.clear();
|
|
232
|
-
this.grantDetails.clear();
|
|
233
|
-
this.logger.info('Permission manager shutdown complete');
|
|
234
|
-
}
|
|
235
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permission-manager.test.d.ts","sourceRoot":"","sources":["../../src/security/permission-manager.test.ts"],"names":[],"mappings":""}
|