acl ole :)
This commit is contained in:
parent
fa3304fe0b
commit
e1c1d182e4
2
packages/acl/dist-in/index.d.ts
vendored
2
packages/acl/dist-in/index.d.ts
vendored
@ -11,4 +11,4 @@ export { DecoratedVfsClient } from './vfs/DecoratedVfsClient.js';
|
||||
export { loadVfsSettings, vfsResource, resourceChain } from './vfs/vfs-acl.js';
|
||||
export type { VfsSettings, VfsAclEntry, VfsGroup } from './vfs/vfs-acl.js';
|
||||
export { DefaultSanitizers } from './vfs/sanitizers.js';
|
||||
export { assertNonEmpty, cleanPath, pathSegments, normalisePath, cleanPermission, cleanPermissions, isUuid, cleanUuid, cleanId, cleanGroupName, sanitizeSubpath, sanitizeWritePath, sanitizeFilename, } from './vfs/sanitizers.js';
|
||||
export { assertNonEmpty, cleanPath, pathSegments, normalisePath, cleanPermission, cleanPermissions, isUuid, cleanUuid, cleanId, cleanGroupName, sanitizeSubpath, sanitizeWritePath, sanitizeFilename, ANONYMOUS_USER_ID, AUTHENTICATED_USER_ID, } from './vfs/sanitizers.js';
|
||||
|
||||
@ -10,5 +10,5 @@ export { AclVfsClient } from './vfs/AclVfsClient.js';
|
||||
export { DecoratedVfsClient } from './vfs/DecoratedVfsClient.js';
|
||||
export { loadVfsSettings, vfsResource, resourceChain } from './vfs/vfs-acl.js';
|
||||
export { DefaultSanitizers } from './vfs/sanitizers.js';
|
||||
export { assertNonEmpty, cleanPath, pathSegments, normalisePath, cleanPermission, cleanPermissions, isUuid, cleanUuid, cleanId, cleanGroupName, sanitizeSubpath, sanitizeWritePath, sanitizeFilename, } from './vfs/sanitizers.js';
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFnQnBELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxELE1BQU07QUFDTixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFL0UsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDeEQsT0FBTyxFQUNILGNBQWMsRUFDZCxTQUFTLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFDdEMsZUFBZSxFQUFFLGdCQUFnQixFQUNqQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQzFDLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsR0FDdkQsTUFBTSxxQkFBcUIsQ0FBQyJ9
|
||||
export { assertNonEmpty, cleanPath, pathSegments, normalisePath, cleanPermission, cleanPermissions, isUuid, cleanUuid, cleanId, cleanGroupName, sanitizeSubpath, sanitizeWritePath, sanitizeFilename, ANONYMOUS_USER_ID, AUTHENTICATED_USER_ID, } from './vfs/sanitizers.js';
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFnQnBELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxELE1BQU07QUFDTixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFL0UsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDeEQsT0FBTyxFQUNILGNBQWMsRUFDZCxTQUFTLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFDdEMsZUFBZSxFQUFFLGdCQUFnQixFQUNqQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQzFDLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFDcEQsaUJBQWlCLEVBQ2pCLHFCQUFxQixHQUN4QixNQUFNLHFCQUFxQixDQUFDIn0=
|
||||
2
packages/acl/dist-in/vfs/AclVfsClient.d.ts
vendored
2
packages/acl/dist-in/vfs/AclVfsClient.d.ts
vendored
@ -25,7 +25,7 @@ export declare class AclVfsClient {
|
||||
/**
|
||||
* @param acl Populated Acl instance (call `loadVfsSettings` first)
|
||||
* @param ownerId UUID of the folder owner
|
||||
* @param callerId UUID of the user performing the operation
|
||||
* @param callerId UUID of the user performing the operation, or 'anonymous'
|
||||
* @param fsOpts LocalVFS options (must include `root`)
|
||||
*/
|
||||
constructor(acl: Acl, ownerId: string, callerId: string, fsOpts: IDefaultParameters);
|
||||
|
||||
@ -12,12 +12,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
||||
var _AclVfsClient_instances, _AclVfsClient_acl, _AclVfsClient_local, _AclVfsClient_ownerId, _AclVfsClient_callerId, _AclVfsClient_guard;
|
||||
import { LocalVFS } from './fs/Local.js';
|
||||
import { resourceChain } from './vfs-acl.js';
|
||||
import { cleanUuid, sanitizeSubpath } from './sanitizers.js';
|
||||
import { cleanUuid, cleanId, sanitizeSubpath, ANONYMOUS_USER_ID, AUTHENTICATED_USER_ID } from './sanitizers.js';
|
||||
export class AclVfsClient {
|
||||
/**
|
||||
* @param acl Populated Acl instance (call `loadVfsSettings` first)
|
||||
* @param ownerId UUID of the folder owner
|
||||
* @param callerId UUID of the user performing the operation
|
||||
* @param callerId UUID of the user performing the operation, or 'anonymous'
|
||||
* @param fsOpts LocalVFS options (must include `root`)
|
||||
*/
|
||||
constructor(acl, ownerId, callerId, fsOpts) {
|
||||
@ -29,7 +29,7 @@ export class AclVfsClient {
|
||||
__classPrivateFieldSet(this, _AclVfsClient_acl, acl, "f");
|
||||
__classPrivateFieldSet(this, _AclVfsClient_local, new LocalVFS(fsOpts), "f");
|
||||
__classPrivateFieldSet(this, _AclVfsClient_ownerId, cleanUuid(ownerId), "f");
|
||||
__classPrivateFieldSet(this, _AclVfsClient_callerId, cleanUuid(callerId), "f");
|
||||
__classPrivateFieldSet(this, _AclVfsClient_callerId, cleanId(callerId), "f");
|
||||
}
|
||||
// ── Read operations ─────────────────────────────────────────────
|
||||
async stat(path) {
|
||||
@ -86,17 +86,30 @@ _AclVfsClient_acl = new WeakMap(), _AclVfsClient_local = new WeakMap(), _AclVfsC
|
||||
* Walk the resource chain from most-specific path to root.
|
||||
* If ANY level grants the permission, access is allowed.
|
||||
* This means a grant on `/` covers the entire tree.
|
||||
*
|
||||
* For non-anonymous callers, also checks grants given to the
|
||||
* `'authenticated'` sentinel, so a single grant can cover all
|
||||
* logged-in users.
|
||||
*/
|
||||
async function _AclVfsClient_guard(permission, path) {
|
||||
const safePath = sanitizeSubpath(path);
|
||||
const chain = resourceChain(__classPrivateFieldGet(this, _AclVfsClient_ownerId, "f"), safePath);
|
||||
// 1. Check caller-specific grants
|
||||
for (const resource of chain) {
|
||||
const result = await __classPrivateFieldGet(this, _AclVfsClient_acl, "f").isAllowed(__classPrivateFieldGet(this, _AclVfsClient_callerId, "f"), resource, permission);
|
||||
if (result.ok && result.data)
|
||||
return;
|
||||
}
|
||||
// 2. For non-anonymous callers, check 'authenticated' group grants
|
||||
if (__classPrivateFieldGet(this, _AclVfsClient_callerId, "f") !== ANONYMOUS_USER_ID) {
|
||||
for (const resource of chain) {
|
||||
const result = await __classPrivateFieldGet(this, _AclVfsClient_acl, "f").isAllowed(AUTHENTICATED_USER_ID, resource, permission);
|
||||
if (result.ok && result.data)
|
||||
return;
|
||||
}
|
||||
}
|
||||
const err = new Error(`EACCES: user '${__classPrivateFieldGet(this, _AclVfsClient_callerId, "f")}' lacks '${permission}' on path '${path}'`);
|
||||
err.code = 'EACCES';
|
||||
throw err;
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWNsVmZzQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Zmcy9BY2xWZnNDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBcUJBLE9BQU8sRUFBRSxRQUFRLEVBQTJCLE1BQU0sZUFBZSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUU3RCxNQUFNLE9BQU8sWUFBWTtJQU1yQjs7Ozs7T0FLRztJQUNILFlBQVksR0FBUSxFQUFFLE9BQWUsRUFBRSxRQUFnQixFQUFFLE1BQTBCOztRQVgxRSxvQ0FBVTtRQUNWLHNDQUFpQjtRQUNqQix3Q0FBaUI7UUFDakIseUNBQWtCO1FBU3ZCLHVCQUFBLElBQUkscUJBQVEsR0FBRyxNQUFBLENBQUM7UUFDaEIsdUJBQUEsSUFBSSx1QkFBVSxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBQSxDQUFDO1FBQ25DLHVCQUFBLElBQUkseUJBQVksU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFBLENBQUM7UUFDbkMsdUJBQUEsSUFBSSwwQkFBYSxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQUEsQ0FBQztJQUN6QyxDQUFDO0lBeUJELG1FQUFtRTtJQUVuRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQVk7UUFDbkIsTUFBTSx1QkFBQSxJQUFJLG9EQUFPLE1BQVgsSUFBSSxFQUFRLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNoQyxPQUFPLHVCQUFBLElBQUksMkJBQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBWTtRQUN0QixNQUFNLHVCQUFBLElBQUksb0RBQU8sTUFBWCxJQUFJLEVBQVEsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hD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
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWNsVmZzQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Zmcy9BY2xWZnNDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBcUJBLE9BQU8sRUFBRSxRQUFRLEVBQTJCLE1BQU0sZUFBZSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLHFCQUFxQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFaEgsTUFBTSxPQUFPLFlBQVk7SUFNckI7Ozs7O09BS0c7SUFDSCxZQUFZLEdBQVEsRUFBRSxPQUFlLEVBQUUsUUFBZ0IsRUFBRSxNQUEwQjs7UUFYMUUsb0NBQVU7UUFDVixzQ0FBaUI7UUFDakIsd0NBQWlCO1FBQ2pCLHlDQUFrQjtRQVN2Qix1QkFBQSxJQUFJLHFCQUFRLEdBQUcsTUFBQSxDQUFDO1FBQ2hCLHVCQUFBLElBQUksdUJBQVUsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQUEsQ0FBQztRQUNuQyx1QkFBQSxJQUFJLHlCQUFZLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBQSxDQUFDO1FBQ25DLHVCQUFBLElBQUksMEJBQWEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFBLENBQUM7SUFDdkMsQ0FBQztJQXNDRCxtRUFBbUU7SUFFbkUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFZO1FBQ25CLE1BQU0sdUJBQUEsSUFBSSxvREFBTyxNQUFYLElBQUksRUFBUSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEMsT0FBTyx1QkFBQSxJQUFJLDJCQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTyxDQUFDLElBQVk7UUFDdEIsTUFBTSx1QkFBQSxJQUFJLG9EQUFPLE1BQVgsSUFBSSxF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
|
||||
11
packages/acl/dist-in/vfs/sanitizers.d.ts
vendored
11
packages/acl/dist-in/vfs/sanitizers.d.ts
vendored
@ -50,6 +50,10 @@ export declare function cleanPermission(raw: string): string;
|
||||
* Validate and normalise permission arrays.
|
||||
*/
|
||||
export declare function cleanPermissions(raw: string[]): string[];
|
||||
/** Sentinel userId for unauthenticated/anonymous access. */
|
||||
export declare const ANONYMOUS_USER_ID = "anonymous";
|
||||
/** Sentinel userId for any authenticated user. */
|
||||
export declare const AUTHENTICATED_USER_ID = "authenticated";
|
||||
/**
|
||||
* Test whether a string is a valid UUID.
|
||||
*
|
||||
@ -64,9 +68,10 @@ export declare function isUuid(value: string): boolean;
|
||||
*/
|
||||
export declare function cleanUuid(raw: string): string;
|
||||
/**
|
||||
* Validate a user/owner identifier — must be a valid UUID.
|
||||
* Validate a user/owner identifier — must be a valid UUID or the
|
||||
* well-known `'anonymous'` sentinel.
|
||||
*
|
||||
* @throws Error if the identifier is not a valid UUID.
|
||||
* @throws Error if the identifier is not a valid UUID or 'anonymous'.
|
||||
*/
|
||||
export declare function cleanId(raw: string): string;
|
||||
/**
|
||||
@ -102,4 +107,6 @@ export declare const DefaultSanitizers: {
|
||||
readonly sanitizeSubpath: typeof sanitizeSubpath;
|
||||
readonly sanitizeWritePath: typeof sanitizeWritePath;
|
||||
readonly sanitizeFilename: typeof sanitizeFilename;
|
||||
readonly ANONYMOUS_USER_ID: "anonymous";
|
||||
readonly AUTHENTICATED_USER_ID: "authenticated";
|
||||
};
|
||||
|
||||
@ -70,6 +70,13 @@ export function cleanPermissions(raw) {
|
||||
return raw.map(cleanPermission);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Well-known sentinel IDs
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Sentinel userId for unauthenticated/anonymous access. */
|
||||
export const ANONYMOUS_USER_ID = 'anonymous';
|
||||
/** Sentinel userId for any authenticated user. */
|
||||
export const AUTHENTICATED_USER_ID = 'authenticated';
|
||||
// ---------------------------------------------------------------------------
|
||||
// UUID validation
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Standard UUID v1–v5 pattern (case-insensitive, lowercased on output). */
|
||||
@ -96,11 +103,17 @@ export function cleanUuid(raw) {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Validate a user/owner identifier — must be a valid UUID.
|
||||
* Validate a user/owner identifier — must be a valid UUID or the
|
||||
* well-known `'anonymous'` sentinel.
|
||||
*
|
||||
* @throws Error if the identifier is not a valid UUID.
|
||||
* @throws Error if the identifier is not a valid UUID or 'anonymous'.
|
||||
*/
|
||||
export function cleanId(raw) {
|
||||
const trimmed = raw.trim().toLowerCase();
|
||||
if (trimmed === ANONYMOUS_USER_ID)
|
||||
return ANONYMOUS_USER_ID;
|
||||
if (trimmed === AUTHENTICATED_USER_ID)
|
||||
return AUTHENTICATED_USER_ID;
|
||||
return cleanUuid(raw);
|
||||
}
|
||||
/**
|
||||
@ -159,5 +172,7 @@ export const DefaultSanitizers = {
|
||||
sanitizeSubpath,
|
||||
sanitizeWritePath,
|
||||
sanitizeFilename,
|
||||
ANONYMOUS_USER_ID,
|
||||
AUTHENTICATED_USER_ID,
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FuaXRpemVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZnMvc2FuaXRpemVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBRUg7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsR0FBVztJQUNqQyxPQUFPLEdBQUc7U0FDTCxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQztTQUNuQixPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQztTQUNwQixPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztTQUNuQixPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsR0FBVztJQUNwQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUN6QyxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxHQUFXO0lBQ3JDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ3JDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsR0FBVztJQUN2QyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbkMsSUFBSSxDQUFDLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7SUFDM0QsT0FB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
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FuaXRpemVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZnMvc2FuaXRpemVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBRUg7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsR0FBVztJQUNqQyxPQUFPLEdBQUc7U0FDTCxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQztTQUNuQixPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQztTQUNwQixPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztTQUNuQixPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsR0FBVztJQUNwQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUN6QyxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxHQUFXO0lBQ3JDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ3JDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsR0FBVztJQUN2QyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbkMsSUFBSSxDQUFDLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7SUFDM0QsT0FB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
|
||||
@ -106,4 +106,4 @@ export async function loadVfsSettings(acl, userDir) {
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmZzLWFjbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZnMvdmZzLWFjbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsT0FBTyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVqQyxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUEyQnpHLDhFQUE4RTtBQUM5RSxVQUFVO0FBQ1YsOEVBQThFO0FBRTlFOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxPQUFlLEVBQUUsWUFBWSxHQUFHLEdBQUc7SUFDM0QsT0FBTyxPQUFPLE9BQU8sSUFBSSxhQUFhLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztBQUMzRCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQUMsT0FBZSxFQUFFLE9BQWU7SUFDMUQsTUFBTSxRQUFRLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXZDLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUUzQiw2Q0FBNkM7SUFDN0MsS0FBSyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN2QyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVELHNCQUFzQjtJQUN0QixLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcs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
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmZzLWFjbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZnMvdmZzLWFjbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsT0FBTyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVqQyxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFxQixNQUFNLGlCQUFpQixDQUFDO0FBMkI1SCw4RUFBOEU7QUFDOUUsVUFBVTtBQUNWLDhFQUE4RTtBQUU5RTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsT0FBZSxFQUFFLFlBQVksR0FBRyxHQUFHO0lBQzNELE9BQU8sT0FBTyxPQUFPLElBQUksYUFBYSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7QUFDM0QsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLE9BQWUsRUFBRSxPQUFlO0lBQzFELE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUV2QyxNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7SUFFM0IsNkNBQTZDO0lBQzdDLEtBQUssSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDdkMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLEdBQUcsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFRCxzQkFBc0I7SUFDdEIsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFX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
|
||||
@ -33,4 +33,6 @@ export {
|
||||
cleanPermission, cleanPermissions,
|
||||
isUuid, cleanUuid, cleanId, cleanGroupName,
|
||||
sanitizeSubpath, sanitizeWritePath, sanitizeFilename,
|
||||
ANONYMOUS_USER_ID,
|
||||
AUTHENTICATED_USER_ID,
|
||||
} from './vfs/sanitizers.js';
|
||||
|
||||
@ -21,7 +21,7 @@ import type { Acl } from '../Acl.js';
|
||||
import type { INode } from './fs/VFS.js';
|
||||
import { LocalVFS, type IDefaultParameters } from './fs/Local.js';
|
||||
import { resourceChain } from './vfs-acl.js';
|
||||
import { cleanUuid, sanitizeSubpath } from './sanitizers.js';
|
||||
import { cleanUuid, cleanId, sanitizeSubpath, ANONYMOUS_USER_ID, AUTHENTICATED_USER_ID } from './sanitizers.js';
|
||||
|
||||
export class AclVfsClient {
|
||||
readonly #acl: Acl;
|
||||
@ -32,14 +32,14 @@ export class AclVfsClient {
|
||||
/**
|
||||
* @param acl Populated Acl instance (call `loadVfsSettings` first)
|
||||
* @param ownerId UUID of the folder owner
|
||||
* @param callerId UUID of the user performing the operation
|
||||
* @param callerId UUID of the user performing the operation, or 'anonymous'
|
||||
* @param fsOpts LocalVFS options (must include `root`)
|
||||
*/
|
||||
constructor(acl: Acl, ownerId: string, callerId: string, fsOpts: IDefaultParameters) {
|
||||
this.#acl = acl;
|
||||
this.#local = new LocalVFS(fsOpts);
|
||||
this.#ownerId = cleanUuid(ownerId);
|
||||
this.#callerId = cleanUuid(callerId);
|
||||
this.#callerId = cleanId(callerId);
|
||||
}
|
||||
|
||||
// ── Guards ──────────────────────────────────────────────────────
|
||||
@ -48,16 +48,29 @@ export class AclVfsClient {
|
||||
* Walk the resource chain from most-specific path to root.
|
||||
* If ANY level grants the permission, access is allowed.
|
||||
* This means a grant on `/` covers the entire tree.
|
||||
*
|
||||
* For non-anonymous callers, also checks grants given to the
|
||||
* `'authenticated'` sentinel, so a single grant can cover all
|
||||
* logged-in users.
|
||||
*/
|
||||
async #guard(permission: string, path: string): Promise<void> {
|
||||
const safePath = sanitizeSubpath(path);
|
||||
const chain = resourceChain(this.#ownerId, safePath);
|
||||
|
||||
// 1. Check caller-specific grants
|
||||
for (const resource of chain) {
|
||||
const result = await this.#acl.isAllowed(this.#callerId, resource, permission);
|
||||
if (result.ok && result.data) return;
|
||||
}
|
||||
|
||||
// 2. For non-anonymous callers, check 'authenticated' group grants
|
||||
if (this.#callerId !== ANONYMOUS_USER_ID) {
|
||||
for (const resource of chain) {
|
||||
const result = await this.#acl.isAllowed(AUTHENTICATED_USER_ID, resource, permission);
|
||||
if (result.ok && result.data) return;
|
||||
}
|
||||
}
|
||||
|
||||
const err = new Error(
|
||||
`EACCES: user '${this.#callerId}' lacks '${permission}' on path '${path}'`,
|
||||
);
|
||||
|
||||
@ -74,6 +74,16 @@ export function cleanPermissions(raw: string[]): string[] {
|
||||
return raw.map(cleanPermission);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Well-known sentinel IDs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Sentinel userId for unauthenticated/anonymous access. */
|
||||
export const ANONYMOUS_USER_ID = 'anonymous';
|
||||
|
||||
/** Sentinel userId for any authenticated user. */
|
||||
export const AUTHENTICATED_USER_ID = 'authenticated';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// UUID validation
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -105,11 +115,15 @@ export function cleanUuid(raw: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user/owner identifier — must be a valid UUID.
|
||||
* Validate a user/owner identifier — must be a valid UUID or the
|
||||
* well-known `'anonymous'` sentinel.
|
||||
*
|
||||
* @throws Error if the identifier is not a valid UUID.
|
||||
* @throws Error if the identifier is not a valid UUID or 'anonymous'.
|
||||
*/
|
||||
export function cleanId(raw: string): string {
|
||||
const trimmed = raw.trim().toLowerCase();
|
||||
if (trimmed === ANONYMOUS_USER_ID) return ANONYMOUS_USER_ID;
|
||||
if (trimmed === AUTHENTICATED_USER_ID) return AUTHENTICATED_USER_ID;
|
||||
return cleanUuid(raw);
|
||||
}
|
||||
|
||||
@ -173,4 +187,6 @@ export const DefaultSanitizers = {
|
||||
sanitizeSubpath,
|
||||
sanitizeWritePath,
|
||||
sanitizeFilename,
|
||||
ANONYMOUS_USER_ID,
|
||||
AUTHENTICATED_USER_ID,
|
||||
} as const;
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
import { readFileSync, existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import type { Acl } from '../Acl.js';
|
||||
import { pathSegments, normalisePath, cleanGroupName, cleanId, cleanPermissions } from './sanitizers.js';
|
||||
import { pathSegments, normalisePath, cleanGroupName, cleanId, cleanPermissions, ANONYMOUS_USER_ID } from './sanitizers.js';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
78
packages/acl/tests/vfs-acl-anonymous.e2e.test.ts
Normal file
78
packages/acl/tests/vfs-acl-anonymous.e2e.test.ts
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* VFS ACL — Anonymous user e2e test
|
||||
*
|
||||
* Verifies that the well-known 'anonymous' userId works through the
|
||||
* ACL pipeline: loadVfsSettings populates grants, and isAllowed checks
|
||||
* pass/fail correctly for anonymous callers.
|
||||
*/
|
||||
import { describe, it, expect, beforeAll } from 'vitest';
|
||||
import { resolve } from 'node:path';
|
||||
import { Acl } from '../src/Acl.js';
|
||||
import { MemoryBackend } from '../src/data/MemoryBackend.js';
|
||||
import { loadVfsSettings, vfsResource } from '../src/vfs/vfs-acl.js';
|
||||
import { ANONYMOUS_USER_ID } from '../src/vfs/sanitizers.js';
|
||||
import type { AclResult } from '../src/interfaces.js';
|
||||
|
||||
/** Unwrap AclResult — asserts ok and returns data. */
|
||||
function d<T>(result: AclResult<T>): T {
|
||||
if (!result.ok) throw new Error(`Expected ok, got ${result.code}: ${result.message}`);
|
||||
return result.data;
|
||||
}
|
||||
|
||||
const OWNER_ID = '3bb4cfbf-318b-44d3-a9d3-35680e738421';
|
||||
const READ_ONLY_USER = 'aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb';
|
||||
const STRANGER_USER = '99999999-0000-0000-0000-ffffffffffff';
|
||||
|
||||
const ROOT = vfsResource(OWNER_ID, '/');
|
||||
const SHARED = vfsResource(OWNER_ID, '/shared');
|
||||
|
||||
const USER_DIR = resolve(import.meta.dirname!, 'vfs/root/anon-test');
|
||||
|
||||
describe('VFS ACL — anonymous user', () => {
|
||||
let acl: Acl;
|
||||
|
||||
beforeAll(async () => {
|
||||
acl = new Acl(new MemoryBackend());
|
||||
const settings = await loadVfsSettings(acl, USER_DIR);
|
||||
expect(settings).not.toBeNull();
|
||||
expect(settings!.owner).toBe(OWNER_ID);
|
||||
});
|
||||
|
||||
// Anonymous gets read+list on /
|
||||
it('anonymous can read on /', async () => {
|
||||
expect(d(await acl.isAllowed(ANONYMOUS_USER_ID, ROOT, 'read'))).toBe(true);
|
||||
});
|
||||
|
||||
it('anonymous can list on /', async () => {
|
||||
expect(d(await acl.isAllowed(ANONYMOUS_USER_ID, ROOT, 'list'))).toBe(true);
|
||||
});
|
||||
|
||||
// Direct isAllowed on /shared returns false — the grant is on "/" only.
|
||||
// AclVfsClient.#guard walks the resource chain, but raw acl.isAllowed does not.
|
||||
it('anonymous direct check on /shared returns false (grant is on /)', async () => {
|
||||
expect(d(await acl.isAllowed(ANONYMOUS_USER_ID, SHARED, 'read'))).toBe(false);
|
||||
});
|
||||
|
||||
// Anonymous CANNOT write
|
||||
it('anonymous CANNOT write on /', async () => {
|
||||
expect(d(await acl.isAllowed(ANONYMOUS_USER_ID, ROOT, 'write'))).toBe(false);
|
||||
});
|
||||
|
||||
it('anonymous CANNOT delete on /', async () => {
|
||||
expect(d(await acl.isAllowed(ANONYMOUS_USER_ID, ROOT, 'delete'))).toBe(false);
|
||||
});
|
||||
|
||||
it('anonymous CANNOT mkdir on /', async () => {
|
||||
expect(d(await acl.isAllowed(ANONYMOUS_USER_ID, ROOT, 'mkdir'))).toBe(false);
|
||||
});
|
||||
|
||||
// Other users still work alongside anonymous
|
||||
it('read-only user can still read on /', async () => {
|
||||
expect(d(await acl.isAllowed(READ_ONLY_USER, ROOT, 'read'))).toBe(true);
|
||||
});
|
||||
|
||||
// Stranger (no grant) is still denied
|
||||
it('stranger CANNOT read on /', async () => {
|
||||
expect(d(await acl.isAllowed(STRANGER_USER, ROOT, 'read'))).toBe(false);
|
||||
});
|
||||
});
|
||||
21
packages/acl/tests/vfs/root/anon-test/vfs-settings.json
Normal file
21
packages/acl/tests/vfs/root/anon-test/vfs-settings.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"owner": "3bb4cfbf-318b-44d3-a9d3-35680e738421",
|
||||
"acl": [
|
||||
{
|
||||
"userId": "anonymous",
|
||||
"path": "/",
|
||||
"permissions": [
|
||||
"read",
|
||||
"list"
|
||||
]
|
||||
},
|
||||
{
|
||||
"userId": "aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
|
||||
"path": "/",
|
||||
"permissions": [
|
||||
"read",
|
||||
"list"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user