WP-01: authentication, user management and application shell
Argon2id password hashing, JWT access tokens with rotating HttpOnly refresh cookies and reuse detection, login rate limiting, auth audit log, bootstrap admin, admin-only user CRUD and password reset, OpenAPI spec. Vue login page, auth store with automatic token refresh, route guards, sidebar shell with toasts and placeholder pages, user management page. All tests green: 40 backend, 12 Vitest, 4 Playwright. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
43
frontend/src/stores/auth.ts
Normal file
43
frontend/src/stores/auth.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
import { api, ApiError } from '../api/client'
|
||||
import type { TokenResponse, User } from '../api/types'
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
const accessToken = ref<string | null>(null)
|
||||
const user = ref<User | null>(null)
|
||||
const isAuthenticated = computed(() => user.value !== null)
|
||||
const isAdmin = computed(() => user.value?.role === 'admin')
|
||||
|
||||
function setSession(data: TokenResponse) {
|
||||
accessToken.value = data.access_token
|
||||
user.value = data.user
|
||||
}
|
||||
|
||||
function clear() {
|
||||
accessToken.value = null
|
||||
user.value = null
|
||||
}
|
||||
|
||||
async function login(email: string, password: string) {
|
||||
const res = await fetch('/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify({ email, password }),
|
||||
})
|
||||
const body = await res.json().catch(() => ({}))
|
||||
if (!res.ok) throw new ApiError(res.status, body.error ?? 'unknown', body.message ?? '')
|
||||
setSession(body as TokenResponse)
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
await api.post('/api/auth/logout')
|
||||
} finally {
|
||||
clear()
|
||||
}
|
||||
}
|
||||
|
||||
return { accessToken, user, isAuthenticated, isAdmin, setSession, clear, login, logout }
|
||||
})
|
||||
Reference in New Issue
Block a user