diff --git a/src/lib/permissions.spec.ts b/src/lib/permissions.spec.ts index 1a18846..5934db0 100644 --- a/src/lib/permissions.spec.ts +++ b/src/lib/permissions.spec.ts @@ -51,12 +51,14 @@ describe("permissions helpers", () => { }); }); - it("defaults requested permissions to false on API error", async () => { + it("defaults requested permissions to true on API error and marks __checkFailed", async () => { mockCheckPermissions.mockRejectedValueOnce(new Error("request failed")); const result = await checkPermissions("token", ["a", "b"]); - expect(result).toEqual({ a: false, b: false }); + expect(result.a).toBe(true); + expect(result.b).toBe(true); + expect(result.__checkFailed).toBe(true); }); it("hasPermission returns true only for explicit true values", () => { diff --git a/src/lib/permissions.ts b/src/lib/permissions.ts index 29ed7bb..d49ab9e 100644 --- a/src/lib/permissions.ts +++ b/src/lib/permissions.ts @@ -1,6 +1,9 @@ import { optima } from "$lib"; -export type PermissionMap = Record; +export type PermissionMap = Record & { + /** Set to `true` when the permission check itself failed (API error, timeout, etc.) */ + __checkFailed?: boolean; +}; /** * Check multiple permissions for the current user and return a map of @@ -34,11 +37,15 @@ export async function checkPermissions( }, {}); } catch (err) { console.error("Permission check failed:", err); - // Default every requested permission to false on failure - return permissions.reduce((map, p) => { - map[p] = false; - return map; - }, {}); + // Default every requested permission to true on failure so the UI + // doesn't hide features that the user may actually be allowed to use. + // The API will still enforce access if the user truly lacks permission. + const map = permissions.reduce((m, p) => { + m[p] = true; + return m; + }, {} as PermissionMap); + map.__checkFailed = true; + return map; } } diff --git a/src/routes/(auth)/login/+page.svelte b/src/routes/(auth)/login/+page.svelte index 19ccea1..b2e9583 100644 --- a/src/routes/(auth)/login/+page.svelte +++ b/src/routes/(auth)/login/+page.svelte @@ -85,14 +85,19 @@ -
{ - // Called when the form action response comes back from the server - return async ({ update }) => { - formActionDone = true; - $loading = false; - await update(); - }; - }}> + { + // Called when the form action response comes back from the server + return async ({ update }) => { + formActionDone = true; + $loading = false; + await update(); + }; + }} + >