72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
interface User {
|
|
id: string
|
|
email: string
|
|
username: string
|
|
name: string
|
|
}
|
|
|
|
interface AuthState {
|
|
user: User | null
|
|
authenticated: boolean
|
|
}
|
|
|
|
export const useCustomAuth = () => {
|
|
const user = ref<User | null>(null)
|
|
const authenticated = ref(false)
|
|
const loading = ref(true)
|
|
|
|
// Check authentication status
|
|
const checkAuth = async () => {
|
|
try {
|
|
loading.value = true
|
|
const data = await $fetch<AuthState>('/api/auth/session')
|
|
user.value = data.user
|
|
authenticated.value = data.authenticated
|
|
} catch (error) {
|
|
console.error('[AUTH] Session check failed:', error)
|
|
user.value = null
|
|
authenticated.value = false
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// Login with Keycloak
|
|
const login = () => {
|
|
const authUrl = 'https://auth.portnimara.dev/realms/client-portal/protocol/openid-connect/auth?' +
|
|
new URLSearchParams({
|
|
client_id: 'client-portal',
|
|
redirect_uri: 'https://client.portnimara.dev/auth/keycloak/callback',
|
|
response_type: 'code',
|
|
scope: 'openid profile email',
|
|
state: Math.random().toString(36).substring(2)
|
|
}).toString()
|
|
|
|
console.log('[AUTH] Redirecting to Keycloak login')
|
|
navigateTo(authUrl, { external: true })
|
|
}
|
|
|
|
// Logout
|
|
const logout = async () => {
|
|
try {
|
|
await navigateTo('/api/auth/logout', { external: true })
|
|
} catch (error) {
|
|
console.error('[AUTH] Logout failed:', error)
|
|
}
|
|
}
|
|
|
|
// Initialize auth state on composable creation
|
|
onMounted(() => {
|
|
checkAuth()
|
|
})
|
|
|
|
return {
|
|
user: readonly(user),
|
|
authenticated: readonly(authenticated),
|
|
loading: readonly(loading),
|
|
login,
|
|
logout,
|
|
checkAuth
|
|
}
|
|
}
|