-
Timm Fitschen authoredTimm Fitschen authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
[...nextauth].ts 3.45 KiB
import NextAuth from 'next-auth'
import KeycloakProvider from 'next-auth/providers/keycloak'
const secretSessionKey = process.env.SECRET_SESSION_KEY || 'UItTuD1HcGXIj8ZfHUswhYdNd40Lc325R8VlxQPUoR0='
const clientId = process.env.KEY_CLOAK_CLIENT_ID || 'gwdg-fdoman-test'
const clientSecret = process.env.KEY_CLOAK_CLIENT_SECRET || ''
const issuer = process.env.KEY_CLOAK_ISSUER || 'https://keycloak.sso.gwdg.de/auth/realms/academiccloud'
async function refreshAccessToken (token: any) {
try {
const url = issuer + '/protocol/openid-connect/token'
const params = new URLSearchParams({
client_id: clientId,
client_secret: clientSecret,
grant_type: 'refresh_token',
refresh_token: token.refreshToken
}).toString()
const response = await fetch(url, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
body: params
})
const refreshedTokens = await response.json()
if (!response.ok) {
throw refreshedTokens
}
console.log('### refreshToken', new Date().toISOString(), refreshedTokens, '### ### ###')
return {
...token,
accessToken: refreshedTokens.access_token,
accessTokenExpires: Date.now() + refreshedTokens.expires_in * 1000,
refreshToken: refreshedTokens.refresh_token ?? token.refreshToken // Fall back to old refresh token
}
} catch (error) {
console.log('### RefreshAccessTokenError', error, '### ### ###')
return {
...token,
error: 'RefreshAccessTokenError'
}
}
}
export const authOptions = {
// adapter: UnstorageAdapter(storage),
session: {
maxAge: 172800 // 48h
},
debug: true,
// Configure one or more authentication providers
providers: [
// !!! Should be stored in .env file.
KeycloakProvider({
clientId,
clientSecret,
issuer,
// authorization: { params: { scope: 'openid profile email' } },
profile (profile) {
console.log('### profile', profile, '### ### ###')
return {
id: profile.sub,
name: profile.name ?? profile.preferred_username
}
}
})
],
callbacks: {
async signIn ({ user, account, profile, email, credentials }: any) {
console.log('### signIn', user, account, profile, email, credentials, '### ### ###')
return true
},
async session ({ session, user, token }: any) {
console.log('### session', session, user, token, '### ### ###')
session.user = token.user
session.accessToken = token.accessToken
session.error = token.error
return session
},
async redirect ({ url, baseUrl }: any) {
console.log('### redirect', url, baseUrl, '### ### ###')
return Promise.resolve(url)
},
async jwt ({ token, user, account, profile, isNewUser }: any) {
console.log('### jwt', token, user, account, profile, isNewUser, '### ### ###')
// Initial sign in
if (account && user) {
return {
lastRefresh: Date.now(),
accessToken: account.access_token,
accessTokenExpires: account.expires_at,
refreshToken: account.refresh_token,
user
}
}
if (token.lastRefresh + 60000 > Date.now()) {
// return if last refresh is 10 seconds or younger
return token
}
// Access token has expired, try to update it
return refreshAccessToken(token)
}
},
secret: secretSessionKey
}
export default NextAuth(authOptions)