feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma binaryTargets for openssl 3.0 - nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal cron, http->https redirect - prisma: add origin_goods.delisted migration, sync missing schema (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz - api: CORS wildcard reflection, helmet CORP cross-origin, price backfill in persistProductDetail, categoryIcon ancestor fallback, mediaByColor per-color gallery in public goods detail - admin: /admin base path (vite + router) - import-data.mjs: udt_name casting, serial sequence advance fix
This commit is contained in:
@@ -1,67 +1,67 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import type { LoginRequest, User } from '@/types'
|
||||
import { authApi } from '@/api/auth'
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
// The session lives in HttpOnly cookies set by the API; nothing
|
||||
// security-relevant is stored client-side. `user` is just UI state,
|
||||
// restored from the server via /auth/me on app start.
|
||||
const user = ref<User | null>(null)
|
||||
const sessionChecked = ref(false)
|
||||
|
||||
// Tokens moved to HttpOnly cookies; clean up any stale values from the
|
||||
// previous localStorage-based session.
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('user')
|
||||
|
||||
const isLoggedIn = computed(() => !!user.value)
|
||||
|
||||
// Restore the session once per app start. The router guard awaits this
|
||||
// so a page refresh on a protected route does not bounce to /login.
|
||||
async function ensureSessionChecked() {
|
||||
if (sessionChecked.value) return
|
||||
sessionChecked.value = true
|
||||
try {
|
||||
user.value = await authApi.getCurrentUser()
|
||||
} catch {
|
||||
user.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function setUser(newUser: User | null) {
|
||||
user.value = newUser
|
||||
}
|
||||
|
||||
async function login(payload: LoginRequest) {
|
||||
const res = await authApi.login(payload) as any
|
||||
const userData: User | null = res.user ?? res.data?.user ?? null
|
||||
sessionChecked.value = true
|
||||
setUser(userData)
|
||||
return res
|
||||
}
|
||||
|
||||
async function fetchCurrentUser() {
|
||||
const current = await authApi.getCurrentUser()
|
||||
setUser(current)
|
||||
return current
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
await authApi.logout()
|
||||
} catch {
|
||||
// Ignore network errors during logout
|
||||
}
|
||||
setUser(null)
|
||||
}
|
||||
|
||||
return {
|
||||
user,
|
||||
isLoggedIn,
|
||||
ensureSessionChecked,
|
||||
login,
|
||||
fetchCurrentUser,
|
||||
logout,
|
||||
}
|
||||
})
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import type { LoginRequest, User } from '@/types'
|
||||
import { authApi } from '@/api/auth'
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
// The session lives in HttpOnly cookies set by the API; nothing
|
||||
// security-relevant is stored client-side. `user` is just UI state,
|
||||
// restored from the server via /auth/me on app start.
|
||||
const user = ref<User | null>(null)
|
||||
const sessionChecked = ref(false)
|
||||
|
||||
// Tokens moved to HttpOnly cookies; clean up any stale values from the
|
||||
// previous localStorage-based session.
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('user')
|
||||
|
||||
const isLoggedIn = computed(() => !!user.value)
|
||||
|
||||
// Restore the session once per app start. The router guard awaits this
|
||||
// so a page refresh on a protected route does not bounce to /login.
|
||||
async function ensureSessionChecked() {
|
||||
if (sessionChecked.value) return
|
||||
sessionChecked.value = true
|
||||
try {
|
||||
user.value = await authApi.getCurrentUser()
|
||||
} catch {
|
||||
user.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function setUser(newUser: User | null) {
|
||||
user.value = newUser
|
||||
}
|
||||
|
||||
async function login(payload: LoginRequest) {
|
||||
const res = await authApi.login(payload) as any
|
||||
const userData: User | null = res.user ?? res.data?.user ?? null
|
||||
sessionChecked.value = true
|
||||
setUser(userData)
|
||||
return res
|
||||
}
|
||||
|
||||
async function fetchCurrentUser() {
|
||||
const current = await authApi.getCurrentUser()
|
||||
setUser(current)
|
||||
return current
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
await authApi.logout()
|
||||
} catch {
|
||||
// Ignore network errors during logout
|
||||
}
|
||||
setUser(null)
|
||||
}
|
||||
|
||||
return {
|
||||
user,
|
||||
isLoggedIn,
|
||||
ensureSessionChecked,
|
||||
login,
|
||||
fetchCurrentUser,
|
||||
logout,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user