fix: Phase 2 QA — all 25 remaining HIGH/MEDIUM/LOW issues
HIGH fixes (7): - H1: VNCdirectory admin i18n — 30+ translation keys added - H2: handleSave try/catch with error toast - H3: Free/busy accountId scoping - H4: cancelEventBookings filter by eventId - H5: Resource picker static apiFetch import - H6: Sharing-store toast messages via lastMessage state - H7: roleLabel for all resource types MEDIUM fixes (11): - M1: identitySignatureMap cleanup on delete - M2: Now-line relative positioning - M3: Radial menu disabled item keyboard nav - M4: Radial menu stable event listener via refs - M5: cancelBooking error on missing booking - M6: PasswordRow isMasked state flag - M7: Extract shared rights into lib/sharing-rights.ts - M8: VNCtalk client server-side guard - M9: Collabora configManager instead of process.env - M10: CONFIG_ENV_MAP VNCdirectory fields - M11: SENSITIVE_CONFIG_KEYS field name unification LOW fixes (7): - L1-L3: Unused imports removed - L4: aria-labels on close, clear, search, spinner - L5-L7: Comments for intentional patterns, null guard
This commit is contained in:
+2
-169
@@ -1,4 +1,5 @@
|
||||
import type { NextRequest } from "next/server";
|
||||
import { resolveRights, type SharedResourceKind } from "@/lib/sharing-rights";
|
||||
|
||||
type JmapMethodCall = [string, Record<string, unknown>, string];
|
||||
|
||||
@@ -142,7 +143,7 @@ export async function POST(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
const patchValue = role === null ? null : buildRights(kind as string, role as string);
|
||||
const patchValue = role === null ? null : resolveRights(kind as SharedResourceKind, role as string);
|
||||
|
||||
const methodCalls: JmapMethodCall[] = [
|
||||
[
|
||||
@@ -190,172 +191,4 @@ export async function POST(request: NextRequest) {
|
||||
return Response.json({ ok: true });
|
||||
}
|
||||
|
||||
function buildRights(
|
||||
kind: string,
|
||||
role: string,
|
||||
): Record<string, boolean> | null {
|
||||
if (role === null) return null;
|
||||
|
||||
switch (kind) {
|
||||
case "mailbox":
|
||||
return mailboxRights(role);
|
||||
case "calendar":
|
||||
return calendarRights(role);
|
||||
case "addressBook":
|
||||
return addressBookRights(role);
|
||||
case "file":
|
||||
return fileRights(role);
|
||||
default:
|
||||
return readRights();
|
||||
}
|
||||
}
|
||||
|
||||
function mailboxRights(role: string): Record<string, boolean> {
|
||||
switch (role) {
|
||||
case "read":
|
||||
return {
|
||||
mayReadItems: true,
|
||||
mayAddItems: false,
|
||||
mayRemoveItems: false,
|
||||
maySetSeen: false,
|
||||
maySetKeywords: false,
|
||||
mayCreateChild: false,
|
||||
mayRename: false,
|
||||
mayDelete: false,
|
||||
maySubmit: false,
|
||||
};
|
||||
case "readWrite":
|
||||
return {
|
||||
mayReadItems: true,
|
||||
mayAddItems: true,
|
||||
mayRemoveItems: false,
|
||||
maySetSeen: true,
|
||||
maySetKeywords: true,
|
||||
mayCreateChild: false,
|
||||
mayRename: false,
|
||||
mayDelete: false,
|
||||
maySubmit: true,
|
||||
};
|
||||
case "manager":
|
||||
return {
|
||||
mayReadItems: true,
|
||||
mayAddItems: true,
|
||||
mayRemoveItems: true,
|
||||
maySetSeen: true,
|
||||
maySetKeywords: true,
|
||||
mayCreateChild: true,
|
||||
mayRename: true,
|
||||
mayDelete: true,
|
||||
maySubmit: true,
|
||||
mayShare: true,
|
||||
};
|
||||
default:
|
||||
return mailboxRights("read");
|
||||
}
|
||||
}
|
||||
|
||||
function calendarRights(role: string): Record<string, boolean> {
|
||||
switch (role) {
|
||||
case "read":
|
||||
return {
|
||||
mayReadFreeBusy: true,
|
||||
mayReadItems: true,
|
||||
mayWriteAll: false,
|
||||
mayWriteOwn: false,
|
||||
mayUpdatePrivate: false,
|
||||
mayRSVP: false,
|
||||
mayShare: false,
|
||||
mayDelete: false,
|
||||
};
|
||||
case "readWrite":
|
||||
return {
|
||||
mayReadFreeBusy: true,
|
||||
mayReadItems: true,
|
||||
mayWriteAll: true,
|
||||
mayWriteOwn: true,
|
||||
mayUpdatePrivate: true,
|
||||
mayRSVP: true,
|
||||
mayShare: false,
|
||||
mayDelete: false,
|
||||
};
|
||||
case "manager":
|
||||
return {
|
||||
mayReadFreeBusy: true,
|
||||
mayReadItems: true,
|
||||
mayWriteAll: true,
|
||||
mayWriteOwn: true,
|
||||
mayUpdatePrivate: true,
|
||||
mayRSVP: true,
|
||||
mayShare: true,
|
||||
mayDelete: true,
|
||||
};
|
||||
default:
|
||||
return calendarRights("read");
|
||||
}
|
||||
}
|
||||
|
||||
function addressBookRights(role: string): Record<string, boolean> {
|
||||
switch (role) {
|
||||
case "read":
|
||||
return {
|
||||
mayRead: true,
|
||||
mayWrite: false,
|
||||
mayShare: false,
|
||||
mayDelete: false,
|
||||
};
|
||||
case "readWrite":
|
||||
return {
|
||||
mayRead: true,
|
||||
mayWrite: true,
|
||||
mayShare: false,
|
||||
mayDelete: false,
|
||||
};
|
||||
case "manager":
|
||||
return {
|
||||
mayRead: true,
|
||||
mayWrite: true,
|
||||
mayShare: true,
|
||||
mayDelete: true,
|
||||
};
|
||||
default:
|
||||
return addressBookRights("read");
|
||||
}
|
||||
}
|
||||
|
||||
function fileRights(role: string): Record<string, boolean> {
|
||||
switch (role) {
|
||||
case "read":
|
||||
return {
|
||||
mayRead: true,
|
||||
mayAddChildren: false,
|
||||
mayRename: false,
|
||||
mayDelete: false,
|
||||
mayModifyContent: false,
|
||||
mayShare: false,
|
||||
};
|
||||
case "readWrite":
|
||||
return {
|
||||
mayRead: true,
|
||||
mayAddChildren: true,
|
||||
mayRename: true,
|
||||
mayDelete: true,
|
||||
mayModifyContent: true,
|
||||
mayShare: false,
|
||||
};
|
||||
case "manager":
|
||||
return {
|
||||
mayRead: true,
|
||||
mayAddChildren: true,
|
||||
mayRename: true,
|
||||
mayDelete: true,
|
||||
mayModifyContent: true,
|
||||
mayShare: true,
|
||||
};
|
||||
default:
|
||||
return fileRights("read");
|
||||
}
|
||||
}
|
||||
|
||||
function readRights(): Record<string, boolean> {
|
||||
return { mayRead: true };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user