feat: hide write UI from read-only users (no WRITE_ALL permission) #17

Closed
opened 2026-03-19 20:32:04 +01:00 by marcel · 0 comments
Owner

Problem

Users without WRITE_ALL permission (read-only users) currently see all edit buttons, "New Document" links, "New Person" links, edit forms, and merge sections. The backend correctly blocks the actual mutations via @RequirePermission(Permission.WRITE_ALL), but the UI gives no indication that those actions are unavailable — users click a button, get a 403, and are confused.

Reference pattern: The admin nav link is already conditionally hidden using isAdmin derived from page.data.user.groups. The same approach should be applied to all write UI.


Approach

1. Expose canWrite centrally in the layout load

Add canWrite to +layout.server.ts so it is available as page.data.canWrite on every page — no per-page boilerplate needed.

// src/routes/+layout.server.ts
return {
    user: locals.user,
    canWrite: locals.user?.groups?.some(g => g.permissions.includes('WRITE_ALL')) ?? false
};

2. Hide write UI in components

Use {#if page.data.canWrite} to wrap write-only elements (same pattern as the admin nav link):

File Elements to hide
src/routes/+page.svelte "Neues Dokument" link
src/routes/documents/[id]/+page.svelte "Bearbeiten" button
src/routes/persons/+page.svelte "Neue Person" link
src/routes/persons/[id]/+page.svelte Edit button, inline edit form, merge section

3. Server-side route guards on write-only routes

Add a WRITE_ALL check in the load function of each write-only route — same pattern as the admin page. Throws 403 if a read-only user navigates there directly via the URL bar.

  • src/routes/documents/new/+page.server.ts
  • src/routes/documents/[id]/edit/+page.server.ts
  • src/routes/persons/new/+page.server.ts

Acceptance Criteria

  • A user with only read permissions sees no edit buttons, no "New Document" / "New Person" links, no merge section
  • Direct URL navigation to /documents/new, /documents/:id/edit, /persons/new returns 403 for read-only users
  • Users with WRITE_ALL see and can use all write UI as before
  • ADMIN users are unaffected (admin implies separate permissions, not write access per se — check existing group setup)
## Problem Users without `WRITE_ALL` permission (read-only users) currently see all edit buttons, "New Document" links, "New Person" links, edit forms, and merge sections. The backend correctly blocks the actual mutations via `@RequirePermission(Permission.WRITE_ALL)`, but the UI gives no indication that those actions are unavailable — users click a button, get a 403, and are confused. **Reference pattern:** The admin nav link is already conditionally hidden using `isAdmin` derived from `page.data.user.groups`. The same approach should be applied to all write UI. --- ## Approach ### 1. Expose `canWrite` centrally in the layout load Add `canWrite` to `+layout.server.ts` so it is available as `page.data.canWrite` on every page — no per-page boilerplate needed. ```typescript // src/routes/+layout.server.ts return { user: locals.user, canWrite: locals.user?.groups?.some(g => g.permissions.includes('WRITE_ALL')) ?? false }; ``` ### 2. Hide write UI in components Use `{#if page.data.canWrite}` to wrap write-only elements (same pattern as the admin nav link): | File | Elements to hide | |---|---| | `src/routes/+page.svelte` | "Neues Dokument" link | | `src/routes/documents/[id]/+page.svelte` | "Bearbeiten" button | | `src/routes/persons/+page.svelte` | "Neue Person" link | | `src/routes/persons/[id]/+page.svelte` | Edit button, inline edit form, merge section | ### 3. Server-side route guards on write-only routes Add a `WRITE_ALL` check in the `load` function of each write-only route — same pattern as the admin page. Throws 403 if a read-only user navigates there directly via the URL bar. - `src/routes/documents/new/+page.server.ts` - `src/routes/documents/[id]/edit/+page.server.ts` - `src/routes/persons/new/+page.server.ts` --- ## Acceptance Criteria - [ ] A user with only read permissions sees no edit buttons, no "New Document" / "New Person" links, no merge section - [ ] Direct URL navigation to `/documents/new`, `/documents/:id/edit`, `/persons/new` returns 403 for read-only users - [ ] Users with `WRITE_ALL` see and can use all write UI as before - [ ] `ADMIN` users are unaffected (admin implies separate permissions, not write access per se — check existing group setup)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#17