wip: Phase 3 UAT in progress — 2/10 tests pass, upload XHR bug open

Fixes applied this session:
- frontend/src/api/client.js: noRefreshPaths exclusion prevents auth 401s
  from triggering session-expired error on login/register/refresh
- frontend/src/router/index.js: async beforeEach with silent refresh()
  restores session from httpOnly cookie on page reload

UAT state: 2 pass (cold-start, admin block), 1 open (XHR upload network error),
7 pending. MinIO PUT fails in browser — needs console output to diagnose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curo1305
2026-05-24 21:26:50 +02:00
parent a5994d9ff4
commit b5dde2aad9
6 changed files with 299 additions and 5 deletions
+4 -1
View File
@@ -21,7 +21,10 @@ async function request(path, options = {}) {
const res = await fetch(path, { ...options, headers, credentials: 'include' })
// 401 → attempt refresh → retry once
if (res.status === 401 && !options._retry) {
// Skip refresh for auth endpoints: login/register return 401 for bad credentials (not expired tokens),
// and refresh itself must not retry to avoid an infinite loop.
const noRefreshPaths = ['/api/auth/login', '/api/auth/register', '/api/auth/refresh']
if (res.status === 401 && !options._retry && !noRefreshPaths.includes(path)) {
try {
await authStore.refresh()
return request(path, { ...options, _retry: true })
+8 -3
View File
@@ -46,11 +46,16 @@ const router = createRouter({
})
// Navigation guard (D-10): redirect unauthenticated users to /login.
// Preserves the intended destination via ?redirect= query param.
router.beforeEach((to) => {
// On page reload the access token is gone (memory-only per CLAUDE.md), so we attempt
// a silent refresh via the httpOnly cookie before concluding the session is gone.
router.beforeEach(async (to) => {
const authStore = useAuthStore()
if (!to.meta.public && !authStore.accessToken) {
return { path: '/login', query: { redirect: to.fullPath } }
try {
await authStore.refresh()
} catch {
return { path: '/login', query: { redirect: to.fullPath } }
}
}
})