openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
43 lines (42 loc) • 2.1 kB
JavaScript
//#region src/shared/operator-scope-compat.ts
const OPERATOR_ROLE = "operator";
const OPERATOR_ADMIN_SCOPE = "operator.admin";
const OPERATOR_READ_SCOPE = "operator.read";
const OPERATOR_TALK_SCOPE = "operator.talk";
const OPERATOR_WRITE_SCOPE = "operator.write";
const OPERATOR_SCOPE_PREFIX = "operator.";
function operatorScopeSatisfied(requestedScope, granted) {
if (!requestedScope.startsWith(OPERATOR_SCOPE_PREFIX)) return false;
if (granted.has(OPERATOR_ADMIN_SCOPE)) return true;
if (requestedScope === OPERATOR_READ_SCOPE) return granted.has(OPERATOR_READ_SCOPE) || granted.has(OPERATOR_WRITE_SCOPE);
if (requestedScope === OPERATOR_WRITE_SCOPE) return granted.has(OPERATOR_WRITE_SCOPE);
if (requestedScope === OPERATOR_TALK_SCOPE) return granted.has(OPERATOR_TALK_SCOPE) || granted.has(OPERATOR_WRITE_SCOPE);
return granted.has(requestedScope);
}
/** Returns true when a role grant satisfies requested scopes, including operator implications. */
function roleScopesAllow(params) {
return resolveMissingRequestedScope(params) === null;
}
/** Returns the original first requested scope not covered by the role's allowed scopes. */
function resolveMissingRequestedScope(params) {
const role = params.role.trim();
const prefix = `${role}.`;
const allowedSet = new Set(params.allowedScopes.map((scope) => scope.trim()));
for (const scope of params.requestedScopes) {
const requestedScope = scope.trim();
if (!requestedScope) continue;
if (!(role === OPERATOR_ROLE ? operatorScopeSatisfied(requestedScope, allowedSet) : requestedScope.startsWith(prefix) && allowedSet.has(requestedScope))) return scope;
}
return null;
}
/** Returns the first requested scope that does not belong to any requested role. */
function resolveScopeOutsideRequestedRoles(params) {
for (const scope of params.requestedScopes) if (!params.requestedRoles.some((role) => roleScopesAllow({
role,
requestedScopes: [scope],
allowedScopes: [scope]
}))) return scope;
return null;
}
//#endregion
export { resolveScopeOutsideRequestedRoles as n, roleScopesAllow as r, resolveMissingRequestedScope as t };