107 lines
2.7 KiB
TypeScript
107 lines
2.7 KiB
TypeScript
import axios from "axios";
|
|
import moment from "moment";
|
|
import { AuthOptions, Session } from "next-auth";
|
|
import { JWT } from "next-auth/jwt";
|
|
|
|
moment.locale("fr");
|
|
|
|
export const authOptions: AuthOptions = {
|
|
providers: [
|
|
{
|
|
id: "oauth",
|
|
name: process.env.OAUTH_PROVIDER_NAME,
|
|
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",
|
|
response_type: "code",
|
|
},
|
|
},
|
|
checks: ["pkce", "state"],
|
|
idToken: true,
|
|
token: process.env.OAUTH_TOKEN_URL,
|
|
userinfo: process.env.OAUTH_USERINFO_URL,
|
|
issuer: process.env.OAUTH_ISSUER,
|
|
jwks_endpoint: process.env.OAUTH_JWKS_ENDPOINT,
|
|
profile(profile: Session["user"]) {
|
|
return {
|
|
id: profile.sub || profile.id,
|
|
name:
|
|
profile.name ||
|
|
profile.preferred_username ||
|
|
`${profile.given_name} ${profile.family_name}`,
|
|
};
|
|
},
|
|
},
|
|
],
|
|
callbacks: {
|
|
async jwt({ token, account, user }) {
|
|
if (account && user) {
|
|
token.accessToken = account.access_token;
|
|
token.accessTokenExpires = moment(account.expires_at * 1000).subtract(5, "s");
|
|
token.refreshToken = account.refresh_token;
|
|
token.user = user;
|
|
return token;
|
|
}
|
|
|
|
if (moment().isBefore(moment(token.accessTokenExpires))) {
|
|
return token;
|
|
}
|
|
|
|
return refreshAccessToken(token);
|
|
},
|
|
async session({ session, token }) {
|
|
if (token) {
|
|
session.user = token.user;
|
|
session.accessToken = token.accessToken;
|
|
session.accessTokenExpires = token.accessTokenExpires;
|
|
session.error = token.error;
|
|
}
|
|
|
|
return session;
|
|
},
|
|
},
|
|
pages: {
|
|
signIn: "/auth/login",
|
|
signOut: "/auth/logout",
|
|
}
|
|
};
|
|
|
|
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,
|
|
};
|
|
};
|