Files
wp-headless/wp-content/themes/moonshine/server/utils/auth.ts

77 lines
2.4 KiB
TypeScript

import type { H3Event } from "h3";
import { GraphQLClient } from "graphql-request";
import { jwtDecode } from "jwt-decode";
import type { User } from "#auth-utils";
import type { AuthUserFragment } from "#graphql/fragments";
import { AuthRefreshTokenDocument, type AuthLoginResult } from "#graphql/operations";
// Handle login result and store user session
export async function handleLogin(event: H3Event, loginData: AuthLoginResult) {
if (!loginData?.login) {
return;
}
const { user, authToken, refreshToken } = loginData.login;
if (!user || !authToken || !refreshToken) {
return;
}
await setUserSession(event, {
user: getAuthUser(user),
secure: {
authToken,
refreshToken,
},
loggedInAt: new Date().toISOString(),
});
}
// Handle user logout by clearing session
export async function handleLogout(event: H3Event) {
await clearUserSession(event);
}
// Convert AuthUserFragment to nuxt-auth-utils User
function getAuthUser(user: AuthUserFragment): User {
return {
id: Number(user.id),
email: user.email!,
roles: extractNodes(user.roles).map(({ name }) => name!) || [],
};
}
// Refresh auth token by calling remote GraphQL endpoint directly
export async function refreshAuthToken(refreshToken: string): Promise<string | undefined> {
const client = new GraphQLClient(`${process.env.NUXT_WP_URL || "https://wp-headless.ledevsimple.ca"}/graphql`);
const data = await client.request(AuthRefreshTokenDocument, { refreshToken });
return data.refreshToken?.authToken || undefined;
}
// Get auth token from user session (refresh if needed)
export async function getAuthToken(event: H3Event): Promise<string | undefined> {
// Retrieve user session, return if none
const session = await getUserSession(event);
if (!session.secure) {
return;
}
// Extract tokens and check expiration
const { authToken, refreshToken } = session.secure;
const decoded = jwtDecode<{ exp: number }>(authToken);
const isExpired = decoded.exp * 1000 < Date.now();
if (isExpired) {
try {
const newAuthToken = await refreshAuthToken(refreshToken);
if (!newAuthToken) {
throw new Error("Impossible de rafraîchir le jeton d'authentification.");
}
session.secure.authToken = newAuthToken;
await setUserSession(event, session);
}
catch {
await clearUserSession(event);
return;
}
}
return session.secure.authToken;
}