mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 08:06:36 +00:00
fix: let files in a shared folder be renamed and deleted on Stalwart 1.0, which sends rights for folders only
This commit is contained in:
@@ -32,6 +32,15 @@ describe('fileNodeAccess', () => {
|
||||
expect(fileNodeAccess(nodes.at(-1)!, nodes)).toEqual({ rename: true, delete: true, move: false, duplicate: true });
|
||||
});
|
||||
|
||||
it('takes the folder\'s rights for a file that names none (Stalwart 1.0)', () => {
|
||||
const writable = shared(WRITE, WRITE);
|
||||
const nodes = [...writable.slice(0, 2), { ...writable[2], myRights: undefined }];
|
||||
expect(fileNodeAccess(nodes.at(-1)!, nodes)).toEqual({ rename: true, delete: true, move: false, duplicate: true });
|
||||
const readOnly = shared(NONE, NONE);
|
||||
const ro = [...readOnly.slice(0, 2), { ...readOnly[2], myRights: undefined }];
|
||||
expect(fileNodeAccess(ro.at(-1)!, ro)).toEqual({ rename: false, delete: false, move: false, duplicate: false });
|
||||
});
|
||||
|
||||
it('offers nothing inside a folder shared read-only', () => {
|
||||
const nodes = shared(NONE, NONE);
|
||||
expect(fileNodeAccess(nodes.at(-1)!, nodes)).toEqual({ rename: false, delete: false, move: false, duplicate: false });
|
||||
|
||||
+17
-4
@@ -27,24 +27,37 @@ function sharedParent(node: FileNode, nodes: FileNode[]): FileNode | undefined {
|
||||
return nodes.find((n) => n.id === node.parentId && !n.discoverableOnly);
|
||||
}
|
||||
|
||||
// Stalwart 1.0 sends `myRights` on folders only; a file has the rights of
|
||||
// the folder it is in. Walk up to the nearest node that names its rights.
|
||||
function effectiveRights(node: FileNode, nodes: FileNode[]): FileNode['myRights'] {
|
||||
const seen = new Set<string>();
|
||||
let current: FileNode | undefined = node;
|
||||
while (current && !seen.has(current.id)) {
|
||||
if (current.myRights) return current.myRights;
|
||||
seen.add(current.id);
|
||||
const parentId: string | null | undefined = current.parentId;
|
||||
current = parentId == null ? undefined : nodes.find((n) => n.id === parentId);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function fileNodeAccess(node: FileNode, nodes: FileNode[]): FileNodeAccess {
|
||||
if (!node.isShared) return ALL;
|
||||
const parent = sharedParent(node, nodes);
|
||||
if (!parent) return { rename: false, delete: false, move: false, duplicate: false };
|
||||
const rights = node.myRights;
|
||||
const rights = effectiveRights(node, nodes);
|
||||
return {
|
||||
rename: !!rights?.mayRename,
|
||||
delete: !!rights?.mayDelete,
|
||||
move: false,
|
||||
duplicate: !!parent.myRights?.mayAddChildren,
|
||||
duplicate: !!effectiveRights(parent, nodes)?.mayAddChildren,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether new folders and uploads may go into the folder `folderId` (null:
|
||||
* the user's own drive root). Inside a shared folder only with its
|
||||
* `mayAddChildren`; Stalwart 0.16 reports a child of a shared folder with
|
||||
* every right false, so there it is offered in the shared folder itself.
|
||||
* `mayAddChildren`.
|
||||
*/
|
||||
export function mayCreateIn(folderId: string | null, nodes: FileNode[]): boolean {
|
||||
if (folderId === null) return true;
|
||||
|
||||
Reference in New Issue
Block a user