From 3c9b400db482c332b70202d571db52d50642c12a Mon Sep 17 00:00:00 2001 From: cproudlock Date: Thu, 27 Aug 2026 09:25:54 -0400 Subject: [PATCH] Granting somebody a permission now takes effect without a re-login fetchUser() existed and was called from nowhere. The signed-in user - including the permission list every v-if in the app reads - was written once at login and cached in localStorage, and nothing ever refreshed it. So an admin granted somebody guides.create, the person was told they had it, and the New guide button stayed hidden until they happened to log out and back in. Nothing on screen explained why, and the natural conclusion is that the permission system is broken. Called on app boot, so a permission change lands on the next page load. Reproduced before and after: button hidden, permission granted mid-session, plain reload, button there. Only a 401 logs out now. The old handler logged out on ANY failure, so an API restart or a network blip would have thrown people out of sessions they still held - a cached user is stale, not invalid. --- frontend/src/stores/auth.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/src/stores/auth.js b/frontend/src/stores/auth.js index 2f0a96dd..9d8faaf5 100644 --- a/frontend/src/stores/auth.js +++ b/frontend/src/stores/auth.js @@ -75,13 +75,25 @@ export const useAuthStore = defineStore('auth', { } }, + // Re-read the signed-in user from the server, permissions included. + // + // The login response is the ONLY thing that used to populate this, and it + // is cached in localStorage - so granting somebody a permission did nothing + // visible until they happened to log out and back in. They were told they + // had rights, the button stayed hidden, and nothing explained why. Called + // on app boot so a permission change lands on the next page load. + // + // Only a 401 logs out. A transient failure - API restarting, network blip - + // must not throw somebody out of a session they still hold; the cached user + // is stale, not invalid. async fetchUser() { try { const response = await authApi.me() this.user = response.data.data await this.enrichFromDirectory() + localStorage.setItem('user', JSON.stringify(this.user)) } catch (error) { - this.logout() + if (error.response?.status === 401) this.logout() } },