fix: guard apiFetch with Keycloak ready + auth check #162

Merged
forgejo_admin merged 1 commit from 153-fix-auth-guard-race into main 2026-03-28 22:51:18 +00:00

Summary

Protected pages fire API calls in onMount before Keycloak init completes, causing 401 console errors on unauthenticated access. This fix makes apiFetch and apiUpload auth-aware by awaiting the Keycloak ready promise and returning null early if not authenticated.

Changes

  • src/lib/api.js — Import ready and isAuthenticated from keycloak.js. Add await ready; if (!isAuthenticated()) return null; guard at the top of both apiFetch and apiUpload.

Test Plan

  • Visit any protected page (e.g. /my-players, /admin, /coach) while unauthenticated
  • Open browser console — confirm no 401 errors appear
  • Auth guard redirect to /signin should still work as before
  • Sign in and verify all protected pages load data normally
  • Verify apiUpload flows (e.g. photo upload) still work when authenticated

Review Checklist

  • npm run check passes (0 errors, 7 pre-existing warnings)
  • Single file changed: src/lib/api.js
  • Callers handle null returns (try/catch in all protected pages)
  • No new dependencies added

N/A — no pal-e-docs notes affected.

## Summary Protected pages fire API calls in `onMount` before Keycloak init completes, causing 401 console errors on unauthenticated access. This fix makes `apiFetch` and `apiUpload` auth-aware by awaiting the Keycloak `ready` promise and returning `null` early if not authenticated. ## Changes - `src/lib/api.js` — Import `ready` and `isAuthenticated` from `keycloak.js`. Add `await ready; if (!isAuthenticated()) return null;` guard at the top of both `apiFetch` and `apiUpload`. ## Test Plan - Visit any protected page (e.g. `/my-players`, `/admin`, `/coach`) while unauthenticated - Open browser console — confirm no 401 errors appear - Auth guard redirect to `/signin` should still work as before - Sign in and verify all protected pages load data normally - Verify `apiUpload` flows (e.g. photo upload) still work when authenticated ## Review Checklist - [x] `npm run check` passes (0 errors, 7 pre-existing warnings) - [x] Single file changed: `src/lib/api.js` - [x] Callers handle null returns (try/catch in all protected pages) - [x] No new dependencies added ## Related - Forgejo issue: #153 - Closes #153 ## Related Notes N/A — no pal-e-docs notes affected.
fix: guard apiFetch with Keycloak ready + auth check
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
86b7976c9f
Protected pages fired API calls before Keycloak init completed,
causing 401 console errors on unauthenticated access. Now apiFetch
awaits the ready promise and returns null if not authenticated.
Fixes all 8 protected pages without touching any of them.

Closes #153

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

QA Review -- PR #162

Diff Summary

Single file changed: src/lib/api.js (+7, -1). Adds auth guards to apiFetch and apiUpload.

Findings

Correctness

  • ready is a module-level Promise exported from keycloak.js (line 34). Awaiting it guarantees Keycloak init has completed before any API call proceeds. Correct.
  • isAuthenticated() checks keycloak?.authenticated ?? false (line 121). Returns false before init and when unauthenticated. Correct.
  • Returning null early is safe. All 8 protected page callers wrap apiFetch in try/catch. A null return does not throw, so it falls through to the finally block (sets loading = false). The auth guard $effect in (app)/+layout.svelte then redirects to /signin.

No regressions

  • Authenticated users: await ready resolves immediately (already resolved), isAuthenticated() returns true, execution continues to getToken() as before. No behavior change.
  • apiUpload gets the same treatment. Symmetric fix.

SOP compliance

  • Branch naming: 153-fix-auth-guard-race -- matches {issue}-{kebab} convention.
  • svelte-check passes: 0 errors (7 pre-existing a11y warnings, unrelated).
  • PR body has Closes #153, test plan, review checklist. Complete.

Nits

  • None.

VERDICT: APPROVED

## QA Review -- PR #162 ### Diff Summary Single file changed: `src/lib/api.js` (+7, -1). Adds auth guards to `apiFetch` and `apiUpload`. ### Findings **Correctness** - `ready` is a module-level `Promise` exported from `keycloak.js` (line 34). Awaiting it guarantees Keycloak init has completed before any API call proceeds. Correct. - `isAuthenticated()` checks `keycloak?.authenticated ?? false` (line 121). Returns `false` before init and when unauthenticated. Correct. - Returning `null` early is safe. All 8 protected page callers wrap `apiFetch` in try/catch. A `null` return does not throw, so it falls through to the `finally` block (sets `loading = false`). The auth guard `$effect` in `(app)/+layout.svelte` then redirects to `/signin`. **No regressions** - Authenticated users: `await ready` resolves immediately (already resolved), `isAuthenticated()` returns `true`, execution continues to `getToken()` as before. No behavior change. - `apiUpload` gets the same treatment. Symmetric fix. **SOP compliance** - Branch naming: `153-fix-auth-guard-race` -- matches `{issue}-{kebab}` convention. - `svelte-check` passes: 0 errors (7 pre-existing a11y warnings, unrelated). - PR body has `Closes #153`, test plan, review checklist. Complete. **Nits** - None. ### VERDICT: APPROVED
forgejo_admin deleted branch 153-fix-auth-guard-race 2026-03-28 22:51:18 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/westside-landing!162
No description provided.