Skip to content

Commit bbf5b35

Browse files
jd-solankionmax
andauthored
chore: fetch cached session from cookie to ensure latest user state (#314)
Co-authored-by: onmax <maximogarciamtnez@gmail.com>
1 parent 7e55667 commit bbf5b35

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

src/runtime/app/middleware/auth.global.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ export default defineNuxtRouteMiddleware(async (to) => {
4848
const config = useRuntimeConfig().public.auth as AuthRuntimeConfig | undefined
4949
const { fetchSession, user, loggedIn } = useUserSession()
5050

51-
// Always fetch session if not logged in - state may not have synced yet
52-
if (!loggedIn.value) {
51+
const mode: AuthMode = typeof auth === 'string' ? auth : auth?.only ?? 'user'
52+
const redirectTo = typeof auth === 'object' ? auth.redirectTo : undefined
53+
54+
if (!loggedIn.value || mode === 'guest') {
5355
const headers = import.meta.server ? useRequestHeaders(['cookie']) : undefined
5456
const isHydratedPrerenderPayload
5557
= (import.meta.client || !import.meta.server)
@@ -58,9 +60,6 @@ export default defineNuxtRouteMiddleware(async (to) => {
5860
await fetchSession({ headers, ...(isHydratedPrerenderPayload ? { force: true } : {}) })
5961
}
6062

61-
const mode: AuthMode = typeof auth === 'string' ? auth : auth?.only ?? 'user'
62-
const redirectTo = typeof auth === 'object' ? auth.redirectTo : undefined
63-
6463
if (mode === 'guest') {
6564
if (loggedIn.value)
6665
return navigateTo(redirectTo ?? config?.redirects?.guest ?? '/')

test/auth-global-middleware.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,25 @@ describe('auth.global middleware', () => {
9797
expect(navigateTo).toHaveBeenCalledWith('/app')
9898
})
9999

100+
it('does not redirect from guest routes when session refresh resolves as logged out', async () => {
101+
loggedIn.value = true
102+
getRouteRules.mockResolvedValueOnce({ auth: { only: 'guest' } })
103+
fetchSession.mockImplementationOnce(async () => {
104+
loggedIn.value = false
105+
user.value = null
106+
})
107+
108+
const middleware = await loadMiddleware()
109+
await middleware({
110+
path: '/login',
111+
fullPath: '/login',
112+
meta: {},
113+
})
114+
115+
expect(fetchSession).toHaveBeenCalledTimes(1)
116+
expect(navigateTo).not.toHaveBeenCalled()
117+
})
118+
100119
it('checks protected routes and attempts redirect when unauthenticated', async () => {
101120
getRouteRules.mockResolvedValueOnce({ auth: 'user' })
102121

@@ -107,6 +126,7 @@ describe('auth.global middleware', () => {
107126
meta: {},
108127
})
109128

129+
expect(fetchSession).toHaveBeenCalledTimes(1)
110130
expect(navigateTo).toHaveBeenCalledTimes(1)
111131
})
112132

@@ -122,6 +142,8 @@ describe('auth.global middleware', () => {
122142
meta: {},
123143
})
124144

145+
expect(fetchSession).toHaveBeenCalledTimes(1)
146+
expect(fetchSession).toHaveBeenCalledWith({ headers: undefined, force: true })
125147
expect(navigateTo).toHaveBeenCalledTimes(1)
126148
})
127149

0 commit comments

Comments
 (0)