67 lines
3.1 KiB
Markdown
67 lines
3.1 KiB
Markdown
# TASK METADATA
|
|
|
|
- **Target Files:**
|
|
- `server/routes/auth_forward.ts`
|
|
- `ui/db_queries.ts`
|
|
- `ui/mod.ts`
|
|
- `server/routes/events.ts`
|
|
- `server/tests/forward_auth.test.ts`
|
|
- `server/tests/events.test.ts`
|
|
- **Core Objective:** Implement Phase 1 of the Event Delegation & Ingress Overhaul:
|
|
enable Traefik ForwardAuth guest ingress for scoped event attendees, bridge
|
|
session custom scopes to the Launchpad UI, and wire audit logging on seat claims.
|
|
- **Dependencies:** None.
|
|
- **Additional Important Notes:**
|
|
- Strictly 100% pure Hono SSR JSX.
|
|
- Zero-Trust Ingress Rule: `account_status: 'guest'` must ONLY be permitted if
|
|
the session holds the specific `app:<appName>` custom scope for the target host.
|
|
- Must pass all quality gates (`deno fmt`, `deno task lint`, `deno task check`,
|
|
and `deno test --allow-all`).
|
|
|
|
---
|
|
|
|
## Architectural Considerations & Risks
|
|
|
|
### Risks
|
|
1. **Scope Leakage:** If ForwardAuth allows any guest account through without
|
|
validating the specific `app:<appName>` scope, a guest for Event A could
|
|
access Event B's workload.
|
|
- *Mitigation:* In `server/routes/auth_forward.ts`, explicitly require that
|
|
either `grantRole` exists in PostgreSQL or `auth.customScopes` includes
|
|
`app:${appRecord.name}`.
|
|
2. **Launchpad Scope Resolution:** Guests do not have rows in the `grants` table.
|
|
- *Mitigation:* Update `getDashboardApps` in `ui/db_queries.ts` to accept
|
|
optional `customScopes?: string[]` from `auth` and query matching apps
|
|
with role `'Guest (Viewer)'`.
|
|
|
|
---
|
|
|
|
## Proposed Implementation
|
|
|
|
### 1. ForwardAuth Guest Ingress (`server/routes/auth_forward.ts`)
|
|
- Update the user account status validation (around line 120):
|
|
- Permit `user.account_status === "active" || user.account_status === "guest"`.
|
|
- Update the grant resolution check (around line 128):
|
|
- Check if `auth.customScopes` contains `app:${appRecord.name}`.
|
|
- If matched, set `grantRole = "viewer"` (or the role defined in scopes) and
|
|
allow ingress with injected `X-Forwarded-*` headers.
|
|
|
|
### 2. Launchpad Guest Scopes (`ui/db_queries.ts` & `ui/mod.ts`)
|
|
- Update `getDashboardApps(userId: string, isAdmin: boolean, customScopes?: string[])`:
|
|
- If `customScopes` contains items formatted as `app:<appName>`, query the `apps`
|
|
table for those app names.
|
|
- Return the app records with `role: "Guest (Viewer)"`.
|
|
- In `ui/mod.ts` under `/dashboard`: Pass `auth.customScopes` to `getDashboardApps`.
|
|
|
|
### 3. Join Audit Logging (`server/routes/events.ts`)
|
|
- In `POST /api/join` (around line 265):
|
|
- Call `auditWrapper.auditLog(guestUuid, "event_seat_claimed", event.id, { eventName: event.name, slug: event.slug, seatNumber: event.seats_claimed }, getClientIp(c))`
|
|
- Ensures all guest claims are captured in the Merkle audit ledger.
|
|
|
|
### 4. Unit & Integration Tests
|
|
- In `server/tests/forward_auth.test.ts`:
|
|
- Add test: `Tier 1 & 2: GET /api/forward-auth - Guest session with app scope allowed`.
|
|
- Add test: `Tier 1 & 2: GET /api/forward-auth - Guest session without app scope rejected (403)`.
|
|
- In `server/tests/events.test.ts`:
|
|
- Verify that `POST /api/join` triggers `event_seat_claimed` audit event.
|