Webapp/src/authOptions.ts

107 lines
2.7 KiB
TypeScript
Raw Normal View History

import axios from "axios";
import moment from "moment";
2024-12-11 17:51:23 +00:00
import { AuthOptions, Session } from "next-auth";
import { JWT } from "next-auth/jwt";
moment.locale("fr");
export const authOptions: AuthOptions = {
providers: [
2024-12-10 23:41:55 +00:00
{
id: "oauth",
name: process.env.OAUTH_PROVIDER_NAME,
2024-12-10 23:41:55 +00:00
type: "oauth",
clientId: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
authorization: {
url: process.env.OAUTH_AUTHORIZATION_URL,
params: {
scope: "openid profile offline_access",
2024-12-10 23:41:55 +00:00
response_type: "code",
},
},
2024-12-11 17:51:23 +00:00
checks: ["pkce", "state"],
idToken: true,
2024-12-10 23:41:55 +00:00
token: process.env.OAUTH_TOKEN_URL,
userinfo: process.env.OAUTH_USERINFO_URL,
issuer: process.env.OAUTH_ISSUER,
jwks_endpoint: process.env.OAUTH_JWKS_ENDPOINT,
2024-12-11 17:51:23 +00:00
profile(profile: Session["user"]) {
2024-12-10 23:41:55 +00:00
return {
id: profile.sub || profile.id,
name:
profile.name ||
profile.preferred_username ||
`${profile.given_name} ${profile.family_name}`,
2024-12-10 23:41:55 +00:00
};
},
},
],
callbacks: {
async jwt({ token, account, user }) {
if (account && user) {
2024-12-10 23:41:55 +00:00
token.accessToken = account.access_token;
token.accessTokenExpires = moment(account.expires_at * 1000).subtract(5, "s");
2024-12-10 23:41:55 +00:00
token.refreshToken = account.refresh_token;
token.user = user;
return token;
2024-12-10 23:41:55 +00:00
}
if (moment().isBefore(moment(token.accessTokenExpires))) {
return token;
}
2024-12-10 23:41:55 +00:00
return refreshAccessToken(token);
},
async session({ session, token }) {
2024-12-10 23:41:55 +00:00
if (token) {
session.user = token.user;
2024-12-10 23:41:55 +00:00
session.accessToken = token.accessToken;
session.accessTokenExpires = token.accessTokenExpires;
session.error = token.error;
2024-12-10 23:41:55 +00:00
}
return session;
},
},
pages: {
signIn: "/auth/login",
signOut: "/auth/logout",
}
2024-12-10 23:41:55 +00:00
};
const refreshAccessToken = async (token: JWT): Promise<JWT> => {
const response = await axios.post<{
access_token: string;
expires_in: number;
refresh_token: string;
error_description?: string;
}>(
process.env.OAUTH_TOKEN_URL,
{
grant_type: "refresh_token",
refresh_token: token.refreshToken,
client_id: process.env.OAUTH_CLIENT_ID,
client_secret: process.env.OAUTH_CLIENT_SECRET,
},
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
if (response.status != 200) {
throw new Error(
response.data.error_description || "Failed to refresh access token"
);
}
return {
...token,
accessToken: response.data.access_token,
accessTokenExpires: moment().add(response.data.expires_in, "seconds").subtract(5, "s"),
refreshToken: response.data.refresh_token,
};
};