database integration
Deploy photobooth / deploy (push) Has been cancelled

This commit is contained in:
2026-05-26 09:07:16 +07:00
parent a90b3a85a2
commit 100e5c3a87
18 changed files with 1068 additions and 108 deletions
+151
View File
@@ -0,0 +1,151 @@
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
import { apiRequest, clearAccessToken, setAccessToken, setRefreshHandler } from '../api'
export const useAuthStore = defineStore('auth', () => {
const user = ref(null)
const accessToken = ref('')
const status = ref('idle')
const isAuthenticated = computed(() => Boolean(accessToken.value))
function applyAccessToken(token) {
accessToken.value = token || ''
setAccessToken(accessToken.value)
}
function clearSession() {
user.value = null
accessToken.value = ''
clearAccessToken()
}
async function refresh() {
status.value = 'loading'
try {
const data = await apiRequest('/auth/refresh', {
method: 'POST',
skipAuth: true,
skipRefresh: true,
})
const token = data?.accessToken || ''
if (!token) {
clearSession()
status.value = 'idle'
return false
}
applyAccessToken(token)
status.value = 'idle'
return true
} catch {
clearSession()
status.value = 'idle'
return false
}
}
async function fetchMe() {
try {
const data = await apiRequest('/me', { method: 'GET' })
user.value = data?.user || data || null
return user.value
} catch {
user.value = null
return null
}
}
async function bootstrap() {
// Try to restore session using refresh cookie.
const ok = await refresh()
if (ok) {
await fetchMe()
}
}
async function login({ email, password }) {
status.value = 'loading'
try {
const data = await apiRequest('/auth/login', {
method: 'POST',
skipAuth: true,
body: { email, password },
})
applyAccessToken(data?.accessToken || '')
user.value = data?.user || null
status.value = 'idle'
return true
} catch (err) {
clearSession()
status.value = 'error'
throw err
}
}
async function signup({ email, password, name }) {
status.value = 'loading'
try {
const data = await apiRequest('/auth/signup', {
method: 'POST',
skipAuth: true,
body: { email, password, name },
})
applyAccessToken(data?.accessToken || '')
user.value = data?.user || null
status.value = 'idle'
return true
} catch (err) {
clearSession()
status.value = 'error'
throw err
}
}
async function logout() {
status.value = 'loading'
try {
await apiRequest('/auth/logout', { method: 'POST', skipRefresh: true })
} finally {
clearSession()
status.value = 'idle'
}
}
// Allow apiRequest() to refresh tokens automatically on 401.
setRefreshHandler(async () => {
const data = await apiRequest('/auth/refresh', {
method: 'POST',
skipAuth: true,
skipRefresh: true,
})
const token = data?.accessToken || ''
applyAccessToken(token)
return token
})
// Keep api module token in sync if a token was already set.
setAccessToken(accessToken.value)
return {
user,
accessToken,
status,
isAuthenticated,
bootstrap,
fetchMe,
refresh,
login,
signup,
logout,
clearSession,
}
})