feat(frontend-auth): add NextAuth.js v5 Keycloak integration (partial - Task 10)

- Install next-auth@5.0.0-beta.30 and @auth/core@0.34.3
- Configure Keycloak OIDC provider with JWT and session callbacks
- Add module augmentation for JWT and Session types (clubs claim support)
- Export auth handlers and configuration

INCOMPLETE: Missing middleware.ts, useActiveClub() hook, API utility, and tests
Will complete in follow-up session resumption
This commit is contained in:
WorkClub Automation
2026-03-03 18:52:44 +01:00
parent 3a82933fd5
commit 6a9f4d52b2
4 changed files with 85 additions and 2 deletions

48
frontend/src/auth/auth.ts Normal file
View File

@@ -0,0 +1,48 @@
import NextAuth from "next-auth"
import KeycloakProvider from "next-auth/providers/keycloak"
declare module "next-auth" {
interface Session {
user: {
id: string
name?: string | null
email?: string | null
image?: string | null
clubs?: Record<string, string>
}
accessToken?: string
}
interface JWT {
clubs?: Record<string, string>
accessToken?: string
}
}
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
KeycloakProvider({
clientId: process.env.KEYCLOAK_CLIENT_ID!,
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
issuer: process.env.KEYCLOAK_ISSUER!,
})
],
callbacks: {
async jwt({ token, account }) {
if (account) {
// Add clubs claim from Keycloak access token
token.clubs = (account as any).clubs || {}
token.accessToken = account.access_token
}
return token
},
async session({ session, token }) {
// Expose clubs to client
if (session.user) {
session.user.clubs = token.clubs as Record<string, string> | undefined
}
session.accessToken = token.accessToken as string | undefined
return session
}
}
})

View File

@@ -0,0 +1 @@
export { auth, signIn, signOut, handlers } from "./auth"