Granting somebody a permission now takes effect without a re-login
Some checks failed
CI / naming (push) Successful in 2m32s
CI / frontend (push) Successful in 4m14s
CI / migrations-mysql (push) Failing after 10m46s
CI / backend (push) Has been cancelled

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.
This commit is contained in:
cproudlock
2026-08-27 09:25:54 -04:00
parent 37a82c2650
commit 3c9b400db4

View File

@@ -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() { async fetchUser() {
try { try {
const response = await authApi.me() const response = await authApi.me()
this.user = response.data.data this.user = response.data.data
await this.enrichFromDirectory() await this.enrichFromDirectory()
localStorage.setItem('user', JSON.stringify(this.user))
} catch (error) { } catch (error) {
this.logout() if (error.response?.status === 401) this.logout()
} }
}, },