Skip to content
Snippets Groups Projects

add refresh token logic

Merged Mohammad Torkashvand requested to merge feature/NAT-761-add-refresh-token-logic into develop
All threads resolved!
4 files
+ 82
13
Compare changes
  • Side-by-side
  • Inline
Files
4
@@ -5,25 +5,69 @@ import {
@@ -5,25 +5,69 @@ import {
import NextAuth, { AuthOptions } from 'next-auth';
import NextAuth, { AuthOptions } from 'next-auth';
import { JWT } from 'next-auth/jwt';
import { JWT } from 'next-auth/jwt';
import { OAuthConfig } from 'next-auth/providers';
import { OAuthConfig } from 'next-auth/providers';
 
import fetch from 'node-fetch';
const token_endpoint_auth_method = process.env.NEXTAUTH_CLIENT_SECRET
const token_endpoint_auth_method = process.env.NEXTAUTH_CLIENT_SECRET
? 'client_secret_basic'
? 'client_secret_basic'
: 'none';
: 'none';
const authActive = process.env.AUTH_ACTIVE?.toLowerCase() != 'false';
const authActive = process.env.AUTH_ACTIVE?.toLowerCase() !== 'false';
 
 
async function refreshAccessToken(token: JWT): Promise<JWT> {
 
try {
 
const raw = JSON.stringify({
 
client_id: process.env.NEXTAUTH_CLIENT_ID,
 
grant_type: 'refresh_token',
 
refresh_token: token.refreshToken as string,
 
});
 
 
const response = await fetch(process.env.NEXTAUTH_TOKEN_ENDPOINT!, {
 
method: 'POST',
 
headers: {
 
'Content-Type': 'application/json',
 
},
 
body: raw,
 
redirect: 'follow',
 
});
 
 
if (response.ok) {
 
const data: {
 
access_token: string;
 
expires_in: number;
 
refresh_token: string;
 
} = await response.json();
 
 
return {
 
...token,
 
accessToken: data.access_token,
 
accessTokenExpires:
 
Math.floor(Date.now() / 1000) + (data.expires_in - 300), // Store expiry as a Unix timestamp (in seconds)
 
refreshToken: data.refresh_token,
 
};
 
} else {
 
return {
 
...token,
 
error: `${response.statusText}`,
 
};
 
}
 
} catch (error) {
 
return {
 
...token,
 
error: `${error}`,
 
};
 
}
 
}
 
const wfoProvider: OAuthConfig<WfoUserProfile> = {
const wfoProvider: OAuthConfig<WfoUserProfile> = {
id: process.env.NEXTAUTH_ID || '',
id: process.env.NEXTAUTH_ID || '',
name: process.env.NEXTAUTH_ID || '',
name: 'GEANT Identity Provider',
type: 'oauth',
type: 'oauth',
clientId: process.env.NEXTAUTH_CLIENT_ID || '',
clientId: process.env.NEXTAUTH_CLIENT_ID,
clientSecret: process.env.NEXTAUTH_CLIENT_SECRET || undefined,
wellKnown: process.env.NEXTAUTH_WELL_KNOWN_OVERRIDE,
wellKnown:
process.env.NEXTAUTH_WELL_KNOWN_OVERRIDE ??
`${process.env.NEXTAUTH_ISSUER || ''}/.well-known/openid-configuration`,
authorization: {
authorization: {
params: {
params: {
scope:
scope: process.env.NEXTAUTH_AUTHORIZATION_SCOPE_OVERRIDE,
process.env.NEXTAUTH_AUTHORIZATION_SCOPE_OVERRIDE ?? 'openid profile',
prompt: 'consent',
},
},
},
},
idToken: true,
idToken: true,
@@ -35,7 +79,6 @@ const wfoProvider: OAuthConfig<WfoUserProfile> = {
@@ -35,7 +79,6 @@ const wfoProvider: OAuthConfig<WfoUserProfile> = {
if (!context.provider.wellKnown || !tokens.access_token) {
if (!context.provider.wellKnown || !tokens.access_token) {
return {};
return {};
}
}
return await client.userinfo(tokens.access_token);
return await client.userinfo(tokens.access_token);
},
},
},
},
@@ -55,13 +98,25 @@ const wfoProvider: OAuthConfig<WfoUserProfile> = {
@@ -55,13 +98,25 @@ const wfoProvider: OAuthConfig<WfoUserProfile> = {
export const authOptions: AuthOptions = {
export const authOptions: AuthOptions = {
providers: authActive ? [wfoProvider] : [],
providers: authActive ? [wfoProvider] : [],
callbacks: {
callbacks: {
async jwt({ token, account, profile }) {
async jwt({ token, account, profile }): Promise<JWT> {
// The "account" is only available right after signing in -- adding useful data to the token
// The "account" is only available right after signing in -- adding useful data to the token
if (account) {
if (account) {
token.accessToken = account.access_token;
token.accessToken = account.access_token;
token.profile = profile;
token.refreshToken = account.refresh_token;
 
token.accessTokenExpires = account.expires_at as number;
 
 
token.profile = profile as WfoUserProfile;
 
}
 
 
const now = Math.floor(Date.now() / 1000);
 
if (
 
typeof token.accessTokenExpires === 'number' &&
 
now < token.accessTokenExpires
 
) {
 
return token;
}
}
return token;
 
return await refreshAccessToken(token);
},
},
async session({ session, token }: { session: WfoSession; token: JWT }) {
async session({ session, token }: { session: WfoSession; token: JWT }) {
// Assign data to the session to be available in the client through the useSession hook
// Assign data to the session to be available in the client through the useSession hook
@@ -72,4 +127,5 @@ export const authOptions: AuthOptions = {
@@ -72,4 +127,5 @@ export const authOptions: AuthOptions = {
},
},
},
},
};
};
 
export default NextAuth(authOptions);
export default NextAuth(authOptions);
Loading