135 lines
3.5 KiB
JavaScript
135 lines
3.5 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import { useAPIStore } from './api'
|
|
|
|
export const useAuthStore = defineStore('auth', () => {
|
|
|
|
const DEFAULT_TIMEOUT = 5 * 60 * 1000
|
|
const REMEMBER_ME_TIMEOUT = 365 * 24 * 60 * 60 * 1000
|
|
|
|
const currentUser = ref(undefined)
|
|
const token = ref(localStorage.getItem('token') || null)
|
|
const tokenExpiry = ref(localStorage.getItem('tokenExpiry') ? parseInt(localStorage.getItem('tokenExpiry')) : null)
|
|
const rememberMe = ref(false)
|
|
|
|
const isLoggedIn = computed(() => {
|
|
return currentUser.value !== undefined && token.value !== null && !isTokenAlmostExpired()
|
|
})
|
|
|
|
const currentUserID = computed(() => {
|
|
return currentUser.value?.id
|
|
})
|
|
|
|
const isTokenAlmostExpired = () => {
|
|
if (!tokenExpiry.value) return false;
|
|
return Date.now() > (tokenExpiry.value - 60 * 1000);
|
|
};
|
|
|
|
const resetTokenExpiry = () => {
|
|
const timeout = rememberMe.value ? REMEMBER_ME_TIMEOUT : DEFAULT_TIMEOUT
|
|
tokenExpiry.value = Date.now() + timeout
|
|
localStorage.setItem('tokenExpiry', tokenExpiry.value.toString())
|
|
}
|
|
|
|
const setToken = (jwtToken, shouldRememberMe = false) => {
|
|
token.value = jwtToken
|
|
rememberMe.value = shouldRememberMe
|
|
|
|
if (jwtToken) {
|
|
localStorage.setItem('token', jwtToken)
|
|
resetTokenExpiry()
|
|
} else {
|
|
localStorage.removeItem('token')
|
|
localStorage.removeItem('tokenExpiry')
|
|
tokenExpiry.value = null
|
|
}
|
|
}
|
|
|
|
const getToken = () => {
|
|
return token.value
|
|
}
|
|
|
|
const login = async (credentials) => {
|
|
const apiStore = useAPIStore()
|
|
const loginResp = await apiStore.postLogin(credentials)
|
|
const userResp = await apiStore.getAuthUser()
|
|
|
|
const jwtToken = loginResp.data.token
|
|
setToken(jwtToken, credentials.rememberMe)
|
|
currentUser.value = userResp.data
|
|
|
|
localStorage.setItem('currentUser', JSON.stringify(userResp.data))
|
|
return userResp.data
|
|
}
|
|
|
|
const logout = async () => {
|
|
const apiStore = useAPIStore()
|
|
await apiStore.postLogout()
|
|
currentUser.value = undefined
|
|
setToken(null)
|
|
localStorage.removeItem('currentUser')
|
|
}
|
|
|
|
const checkTokenExpiry = () => {
|
|
if (isTokenAlmostExpired()) {
|
|
logout()
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
const restoreSession = async () => {
|
|
const storedToken = localStorage.getItem('token')
|
|
const storedUser = localStorage.getItem('currentUser')
|
|
const storedTokenExpiry = localStorage.getItem('tokenExpiry')
|
|
|
|
if (!storedToken || !storedTokenExpiry) {
|
|
return false
|
|
}
|
|
if (Date.now() > parseInt(storedTokenExpiry)) {
|
|
localStorage.removeItem('token')
|
|
localStorage.removeItem('tokenExpiry')
|
|
localStorage.removeItem('currentUser')
|
|
return false
|
|
}
|
|
|
|
token.value = storedToken
|
|
tokenExpiry.value = parseInt(storedTokenExpiry)
|
|
|
|
if (storedUser) {
|
|
try {
|
|
currentUser.value = JSON.parse(storedUser)
|
|
} catch (e) {
|
|
// If stored user data is corrupted, fetch fresh data from API
|
|
try {
|
|
const userResp = await apiStore.getAuthUser()
|
|
currentUser.value = userResp.data
|
|
localStorage.setItem('currentUser', JSON.stringify(userResp.data))
|
|
} catch (apiError) {
|
|
// API call failed, likely token is invalid
|
|
logout()
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
return {
|
|
currentUser,
|
|
isLoggedIn,
|
|
currentUserID,
|
|
token,
|
|
rememberMe,
|
|
setToken,
|
|
getToken,
|
|
login,
|
|
logout,
|
|
resetTokenExpiry,
|
|
isTokenAlmostExpired,
|
|
checkTokenExpiry,
|
|
restoreSession,
|
|
}
|
|
})
|