major: Migration from better-auth to keycloak

This commit is contained in:
2025-10-28 10:40:38 +01:00
parent e5e063bbde
commit 36364a7977
77 changed files with 1444 additions and 2930 deletions

View File

@@ -0,0 +1,56 @@
import { jwtDecode } from 'jwt-decode'
import type { KeycloakTokenPayload, Organization } from '~/types/keycloak'
export default defineOAuthKeycloakEventHandler({
async onSuccess(event, { user, tokens }) {
const rawAccessToken = tokens?.access_token
let decodedJwt: KeycloakTokenPayload | null = null
try {
decodedJwt = jwtDecode<KeycloakTokenPayload>(rawAccessToken!)
} catch (err) {
console.warn('[auth] Failed to decode access token:', err)
}
const organizations = decodedJwt ? extractOrganizations(decodedJwt) : []
await setUserSession(event, {
user: {
keycloakId: user.sub,
name: user.preferred_username,
organizations
},
jwt: {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in
},
loggedInAt: Date.now()
})
return sendRedirect(event, '/')
},
onError(event) {
console.log('error during keycloak authentication', event)
return sendRedirect(event, '/login')
}
})
function extractOrganizations(decoded: KeycloakTokenPayload): Organization[] {
const organizations: Organization[] = []
const orgClaim = decoded?.organization ?? null
if (orgClaim && typeof orgClaim === 'object') {
Object.entries(orgClaim).forEach(([name, meta]) => {
if (!name || !meta?.id) return
organizations.push({
name: name,
id: meta.id
})
})
}
return organizations
}

View File

@@ -0,0 +1,12 @@
export default defineEventHandler(async (event) => {
try {
const cleared = await clearUserSession(event)
if (!cleared) {
console.warn('Failed to clear user session')
}
} catch (error) {
console.error('Error clearing user session:', error)
}
return sendRedirect(event, '/login', 200)
})