fix: improve logout to clear all cookies and storage, fix subscription tier case
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
This commit is contained in:
@ -55,10 +55,27 @@ def set_auth_cookie(response: Response, token: str, max_age_seconds: int) -> Non
|
|||||||
|
|
||||||
|
|
||||||
def clear_auth_cookie(response: Response) -> None:
|
def clear_auth_cookie(response: Response) -> None:
|
||||||
|
"""Clear auth cookie with explicit expiry to ensure removal."""
|
||||||
|
# Delete with same settings used when setting (required for proper removal)
|
||||||
response.delete_cookie(
|
response.delete_cookie(
|
||||||
key=AUTH_COOKIE_NAME,
|
key=AUTH_COOKIE_NAME,
|
||||||
path="/",
|
path="/",
|
||||||
domain=cookie_domain(),
|
domain=cookie_domain(),
|
||||||
|
secure=True,
|
||||||
|
httponly=True,
|
||||||
|
samesite="lax",
|
||||||
|
)
|
||||||
|
# Also set with max_age=0 as fallback (some browsers need this)
|
||||||
|
response.set_cookie(
|
||||||
|
key=AUTH_COOKIE_NAME,
|
||||||
|
value="",
|
||||||
|
max_age=0,
|
||||||
|
expires=0,
|
||||||
|
path="/",
|
||||||
|
domain=cookie_domain(),
|
||||||
|
secure=True,
|
||||||
|
httponly=True,
|
||||||
|
samesite="lax",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -106,17 +106,46 @@ export const useStore = create<AppState>((set, get) => ({
|
|||||||
// They can then log in manually via the login page
|
// They can then log in manually via the login page
|
||||||
},
|
},
|
||||||
|
|
||||||
logout: () => {
|
logout: async () => {
|
||||||
api.logout()
|
try {
|
||||||
|
// Call backend to clear HttpOnly cookie
|
||||||
|
await api.logout()
|
||||||
|
} catch {
|
||||||
|
// Continue with client-side cleanup even if backend call fails
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all client-side state
|
||||||
set({
|
set({
|
||||||
user: null,
|
user: null,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
domains: [],
|
domains: [],
|
||||||
subscription: null,
|
subscription: null,
|
||||||
|
isLoading: false,
|
||||||
})
|
})
|
||||||
// Redirect to landing page
|
|
||||||
|
// Clear ALL client-side storage
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.location.href = '/'
|
// Clear localStorage
|
||||||
|
try {
|
||||||
|
localStorage.clear()
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
|
||||||
|
// Clear sessionStorage
|
||||||
|
try {
|
||||||
|
sessionStorage.clear()
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
|
||||||
|
// Clear any cookies we can access from JS (non-HttpOnly)
|
||||||
|
document.cookie.split(';').forEach(cookie => {
|
||||||
|
const name = cookie.split('=')[0].trim()
|
||||||
|
if (name) {
|
||||||
|
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`
|
||||||
|
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.pounce.ch`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Force redirect to landing page with cache-busting
|
||||||
|
window.location.href = '/?logout=' + Date.now()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user