front
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import type { User, LoginCredentials, SignupCredentials, AuthResponse } from '@/types'
|
||||
import { useWhiteboardStore } from '@/stores/whiteboards'
|
||||
import { authService } from '@/services/authService'
|
||||
|
||||
const ACCESS_TOKEN = 'auth_token'
|
||||
@@ -14,7 +15,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
|
||||
const isAuthenticated = computed(() => !!user.value)
|
||||
|
||||
// single-flight promise for refresh to avoid concurrent refresh requests
|
||||
let refreshPromise: Promise<void> | null = null
|
||||
|
||||
function setTokens(access: string | null, refresh: string | null) {
|
||||
@@ -28,28 +28,23 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
if (refresh) {
|
||||
localStorage.setItem(REFRESH_TOKEN, refresh)
|
||||
} else if (refresh === null) {
|
||||
// explicit null means remove
|
||||
localStorage.removeItem(REFRESH_TOKEN)
|
||||
}
|
||||
}
|
||||
|
||||
async function tryRefresh(): Promise<void> {
|
||||
// if a refresh is already in progress, return that promise
|
||||
if (refreshPromise) return refreshPromise
|
||||
|
||||
const refreshToken = localStorage.getItem(REFRESH_TOKEN)
|
||||
if (!refreshToken) {
|
||||
// nothing to do
|
||||
throw new Error('No refresh token')
|
||||
}
|
||||
|
||||
refreshPromise = (async () => {
|
||||
try {
|
||||
const res = await authService.refreshLogin(refreshToken)
|
||||
// API expected to return { accessToken, refreshToken }
|
||||
setTokens(res.accessToken ?? null, res.refreshToken ?? null)
|
||||
} finally {
|
||||
// clear so subsequent calls can create a new promise
|
||||
refreshPromise = null
|
||||
}
|
||||
})()
|
||||
@@ -70,7 +65,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
isLoading.value = false
|
||||
return
|
||||
} catch (e) {
|
||||
// token might be expired; try refresh if we have refresh token
|
||||
if (savedRefresh) {
|
||||
try {
|
||||
await tryRefresh()
|
||||
@@ -78,14 +72,13 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
isLoading.value = false
|
||||
return
|
||||
} catch (err) {
|
||||
// refresh failed - fallthrough to clearing auth
|
||||
console.warn('Token refresh failed during initialize', err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not authenticated or refresh failed
|
||||
|
||||
setTokens(null, null)
|
||||
user.value = null
|
||||
isLoading.value = false
|
||||
@@ -96,14 +89,14 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
error.value = null
|
||||
try {
|
||||
const res: AuthResponse = await authService.login(credentials)
|
||||
// expect AuthResponse to have accessToken and refreshToken
|
||||
|
||||
setTokens(res.accessToken ?? null, res.refreshToken ?? null)
|
||||
|
||||
try {
|
||||
user.value = await authService.getMe()
|
||||
} catch (e) {
|
||||
console.error('Logged in but failed to fetch user profile', e)
|
||||
// keep tokens but clear user
|
||||
|
||||
user.value = null
|
||||
}
|
||||
} catch (e: any) {
|
||||
@@ -124,7 +117,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
try {
|
||||
user.value = await authService.getMe()
|
||||
} catch (e) {
|
||||
// keep tokens but no profile
|
||||
|
||||
user.value = null
|
||||
}
|
||||
} catch (e: any) {
|
||||
@@ -136,16 +129,17 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}
|
||||
|
||||
async function logout(allDevices = false) {
|
||||
const whiteboardStore = useWhiteboardStore()
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
try {
|
||||
if (allDevices) await authService.logoutAll()
|
||||
else await authService.logout(localStorage.getItem(REFRESH_TOKEN)!)
|
||||
} catch (e) {
|
||||
// ignore network errors on logout
|
||||
console.warn('Logout request failed', e)
|
||||
} finally {
|
||||
setTokens(null, null)
|
||||
whiteboardStore.clearWhiteboards()
|
||||
user.value = null
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user