feat: implement auth middleware, user sync, and token state persistence

- Define useAuth composable logic with syncUser, handleLoginSuccess, and logout methods
- Add auth.ts and guest.ts route middlewares to guard routes based on authentication and user roles
- Add auth.client.ts plugin to boot-sync logged in user details
- Declare custom PageMeta type definitions to support role-based authorization rules
This commit is contained in:
2026-06-12 19:04:19 +02:00 Unverified
parent 834fdade2b
commit 7499ca60f6
5 changed files with 138 additions and 0 deletions
+58
View File
@@ -8,6 +8,55 @@ import type {
} from "~/types/api";
export const useAuth = () => {
const token = useCookie('auth_token', {
maxAge: 60 * 60 * 12,
sameSite: 'lax',
watch: true
})
const tokenState = useState<string | null>('auth_token_state', () => token.value ?? null)
type UserContext = CurrentUserResponse['user']
const user = useState<UserContext | null>('auth_user', () => null)
const isSyncingUser = useState<boolean>('auth_syncing', () => false)
const isAuthenticated = computed(() => !!(tokenState.value || token.value))
watch(() => token.value, (newVal) => {
tokenState.value = newVal || null
})
const syncUser = async () => {
const tokenVal = tokenState.value || token.value
if (!tokenVal || isSyncingUser.value) return
isSyncingUser.value = true
try {
const res = await fetchCurrentUser()
if (res.ok) {
console.log('[Auth] User synced successfully')
user.value = res.user
}
} catch (error) {
console.error('[Auth] Sync failed, logging out:', error)
logout()
} finally {
isSyncingUser.value = false
}
}
const handleLoginSuccess = async (jwtToken: string) => {
token.value = jwtToken
tokenState.value = jwtToken
await syncUser()
}
const logout = () => {
token.value = null
tokenState.value = null
user.value = null
navigateTo('/auth/login')
}
const register = (body: RegisterCitizenRequest) =>
useApiFetch<RegisterCitizenResponse>('/api/v1/auth/register', { method: 'POST', body })
@@ -36,6 +85,15 @@ export const useAuth = () => {
useApiFetch<OkResponse>(`/api/v1/notifications/${id}/read`, { method: 'PATCH' })
return {
user,
token,
tokenState,
isSyncingUser,
isAuthenticated,
handleLoginSuccess,
syncUser,
logout,
register,
requestOtp,
verifyOtp,