tasq/node_modules/@claude-flow/security/dist/domain/entities/security-context.js

132 lines
4.5 KiB
JavaScript

/**
* Security Context Entity - Domain Layer
*
* Represents security context for operations with validation and policy enforcement.
*
* @module v3/security/domain/entities
*/
import { randomUUID } from 'crypto';
/**
* Security Context - Entity
*/
export class SecurityContext {
_id;
_principalId;
_principalType;
_permissions;
_allowedPaths;
_blockedPaths;
_allowedCommands;
_blockedCommands;
_metadata;
_expiresAt;
_createdAt;
constructor(props) {
this._id = props.id ?? randomUUID();
this._principalId = props.principalId;
this._principalType = props.principalType;
this._permissions = new Set(props.permissions);
this._allowedPaths = new Set(props.allowedPaths ?? []);
this._blockedPaths = new Set(props.blockedPaths ?? []);
this._allowedCommands = new Set(props.allowedCommands ?? []);
this._blockedCommands = new Set(props.blockedCommands ?? []);
this._metadata = props.metadata ?? {};
this._expiresAt = props.expiresAt;
this._createdAt = props.createdAt ?? new Date();
}
static create(props) {
return new SecurityContext(props);
}
static fromPersistence(props) {
return new SecurityContext(props);
}
get id() { return this._id; }
get principalId() { return this._principalId; }
get principalType() { return this._principalType; }
get permissions() { return Array.from(this._permissions); }
get allowedPaths() { return Array.from(this._allowedPaths); }
get blockedPaths() { return Array.from(this._blockedPaths); }
get allowedCommands() { return Array.from(this._allowedCommands); }
get blockedCommands() { return Array.from(this._blockedCommands); }
get metadata() { return { ...this._metadata }; }
get expiresAt() { return this._expiresAt; }
get createdAt() { return new Date(this._createdAt); }
// Business Logic
hasPermission(level) {
return this._permissions.has(level) || this._permissions.has('admin');
}
isExpired() {
if (!this._expiresAt)
return false;
return Date.now() > this._expiresAt.getTime();
}
canAccessPath(path) {
if (this.isExpired())
return false;
// Check blocked paths first
for (const blocked of this._blockedPaths) {
if (path.startsWith(blocked) || this.matchGlob(path, blocked)) {
return false;
}
}
// If no allowed paths specified, allow all non-blocked
if (this._allowedPaths.size === 0)
return true;
// Check allowed paths
for (const allowed of this._allowedPaths) {
if (path.startsWith(allowed) || this.matchGlob(path, allowed)) {
return true;
}
}
return false;
}
canExecuteCommand(command) {
if (this.isExpired())
return false;
const cmdBase = command.split(' ')[0];
// Check blocked commands first
if (this._blockedCommands.has(cmdBase) || this._blockedCommands.has(command)) {
return false;
}
// If no allowed commands specified, allow all non-blocked
if (this._allowedCommands.size === 0)
return true;
// Check allowed commands
return this._allowedCommands.has(cmdBase) || this._allowedCommands.has(command);
}
matchGlob(path, pattern) {
const regex = pattern
.replace(/\*\*/g, '.*')
.replace(/\*/g, '[^/]*')
.replace(/\?/g, '.');
return new RegExp(`^${regex}$`).test(path);
}
grantPermission(level) {
this._permissions.add(level);
}
revokePermission(level) {
this._permissions.delete(level);
}
addAllowedPath(path) {
this._allowedPaths.add(path);
}
addBlockedPath(path) {
this._blockedPaths.add(path);
}
toPersistence() {
return {
id: this._id,
principalId: this._principalId,
principalType: this._principalType,
permissions: Array.from(this._permissions),
allowedPaths: Array.from(this._allowedPaths),
blockedPaths: Array.from(this._blockedPaths),
allowedCommands: Array.from(this._allowedCommands),
blockedCommands: Array.from(this._blockedCommands),
metadata: this._metadata,
expiresAt: this._expiresAt?.toISOString(),
createdAt: this._createdAt.toISOString(),
};
}
}
//# sourceMappingURL=security-context.js.map