@zeushq/nextjs-zidentity
Version:
Next.js SDK for signin in with Zeus Identity
90 lines (75 loc) • 2.53 kB
text/typescript
import { NextApiResponse, NextApiRequest } from 'next';
import { ClientFactory } from '../zsession';
import { SessionCache, Session, fromJson, GetAccessToken } from '../session';
import { assertReqRes } from '../utils/assert';
import { HandlerError } from '../utils/errors';
export type AfterRefetch = (req: NextApiRequest, res: NextApiResponse, session: Session) => Promise<Session> | Session;
/**
* Custom options for {@link HandleProfile}
*
* @category Server
*/
export type ProfileOptions = {
/**
* If set to `true` this will refetch the user profile information from `/userinfo` and save it to the session.
*/
refetch?: boolean;
/**
* Like {@AfterCallback} when a session is created, you can use this function to validate or add/remove claims
* after the session is updated. Will only run if {@link ProfileOptions.refetch} is `true`
*/
afterRefetch?: AfterRefetch;
};
/**
* The handler for the `/api/auth/me` route.
*
* @category Server
*/
export type HandleProfile = (req: NextApiRequest, res: NextApiResponse, options?: ProfileOptions) => Promise<void>;
/**
* @ignore
*/
export default function profileHandler(
getClient: ClientFactory,
getAccessToken: GetAccessToken,
sessionCache: SessionCache
): HandleProfile {
return async (req, res, options): Promise<void> => {
try {
assertReqRes(req, res);
if (!sessionCache.isAuthenticated(req, res)) {
res.status(401).json({
error: 'not_authenticated',
description: 'The user does not have an active session or is not authenticated'
});
return;
}
const session = sessionCache.get(req, res) as Session;
res.setHeader('Cache-Control', 'no-store');
if (options?.refetch) {
const { accessToken } = await getAccessToken(req, res);
if (!accessToken) {
throw new Error('No access token available to refetch the profile');
}
const client = await getClient();
const userInfo = await client.userinfo(accessToken);
let newSession = fromJson({
...session,
user: {
...session.user,
...userInfo
}
}) as Session;
if (options.afterRefetch) {
newSession = await options.afterRefetch(req, res, newSession);
}
sessionCache.set(req, res, newSession);
res.json(newSession.user);
return;
}
res.json(session.user);
} catch (e: any) {
throw new HandlerError(e);
}
};
}