103 lines
3.1 KiB
JavaScript
103 lines
3.1 KiB
JavaScript
|
|
// app/composables/useAuth.js
|
|||
|
|
import { useApi, useAuthToken } from './useApi'
|
|||
|
|
|
|||
|
|
export function useAuth() {
|
|||
|
|
const api = useApi()
|
|||
|
|
const { token, setToken } = useAuthToken()
|
|||
|
|
|
|||
|
|
const user = useState('auth:user', () => null)
|
|||
|
|
const loading = useState('auth:loading', () => false)
|
|||
|
|
|
|||
|
|
const pickToken = (res) => res?.user?.token || res?.token || null
|
|||
|
|
const setUserFromResponse = (res) => {
|
|||
|
|
const u = res?.user || {}
|
|||
|
|
user.value = {
|
|||
|
|
id: u.id ?? u._id ?? u.user_id ?? null,
|
|||
|
|
username: u.username ?? null,
|
|||
|
|
email: u.email ?? null,
|
|||
|
|
bio: u.bio ?? null,
|
|||
|
|
image: u.image ?? null,
|
|||
|
|
phone: u.phone ?? null,
|
|||
|
|
userType: u.userType ?? u.user_type ?? null,
|
|||
|
|
companyName: u.companyName ?? u.company_name ?? null,
|
|||
|
|
emailVerified: !!u.email_verified,
|
|||
|
|
roles: Array.isArray(u.roles) ? [...u.roles] : [],
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function login(payload) {
|
|||
|
|
loading.value = true
|
|||
|
|
console.log('[useAuth] login payload:', { ...payload, password: '***' })
|
|||
|
|
try {
|
|||
|
|
const res = await api.post('/auth/login', {
|
|||
|
|
user: { email: payload.email, password: payload.password },
|
|||
|
|
})
|
|||
|
|
console.log('[useAuth] login response:', res)
|
|||
|
|
|
|||
|
|
// 冗余写入(useApi 已做了,但这里再做一遍以防万一)
|
|||
|
|
const newToken = pickToken(res)
|
|||
|
|
if (newToken) setToken(newToken)
|
|||
|
|
|
|||
|
|
setUserFromResponse(res)
|
|||
|
|
console.log('[useAuth] user after login:', user.value)
|
|||
|
|
return res.user
|
|||
|
|
} finally {
|
|||
|
|
loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function register(payload) {
|
|||
|
|
if (payload.password !== payload.confirmPassword) {
|
|||
|
|
throw createError({ statusCode: 400, statusMessage: '两次输入的密码不一致' })
|
|||
|
|
}
|
|||
|
|
loading.value = true
|
|||
|
|
console.log('[useAuth] register payload:', { ...payload, password: '***', confirmPassword: '***' })
|
|||
|
|
try {
|
|||
|
|
const res = await api.post('/auth', {
|
|||
|
|
user: {
|
|||
|
|
email: payload.email,
|
|||
|
|
password: payload.password,
|
|||
|
|
confirm_password: payload.confirmPassword,
|
|||
|
|
code: payload.code,
|
|||
|
|
},
|
|||
|
|
})
|
|||
|
|
console.log('[useAuth] register response:', res)
|
|||
|
|
|
|||
|
|
const newToken = pickToken(res)
|
|||
|
|
if (newToken) setToken(newToken)
|
|||
|
|
|
|||
|
|
setUserFromResponse(res)
|
|||
|
|
console.log('[useAuth] user after register:', user.value)
|
|||
|
|
return res.user
|
|||
|
|
} finally {
|
|||
|
|
loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function fetchMe() {
|
|||
|
|
if (!token.value) {
|
|||
|
|
console.log('[useAuth] fetchMe skipped: no token')
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
const res = await api.get('/user')
|
|||
|
|
console.log('[useAuth] fetchMe response:', res)
|
|||
|
|
setUserFromResponse(res)
|
|||
|
|
return res.user
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function logout() {
|
|||
|
|
console.log('[useAuth] logout begin, token =', token.value)
|
|||
|
|
try {
|
|||
|
|
await $fetch('/api/auth/logout', { method: 'POST', credentials: 'include' })
|
|||
|
|
console.log('[useAuth] server logout OK')
|
|||
|
|
} catch (e) {
|
|||
|
|
console.warn('[useAuth] server logout error:', e)
|
|||
|
|
}
|
|||
|
|
setToken(null)
|
|||
|
|
user.value = null
|
|||
|
|
console.log('[useAuth] logout done, token =', token.value, 'user =', user.value)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { token, user, loading, login, register, fetchMe, logout }
|
|||
|
|
}
|