import { NextApiRequest, NextApiResponse } from "next"; import NextAuth from "next-auth"; import Google from "next-auth/providers/google"; import GitHub from "next-auth/providers/github"; import GitLab from "next-auth/providers/gitlab"; import Cognito from "next-auth/providers/cognito"; import { loadConfig, IAppConfig } from "@digiresilience/metamigo-config"; import { MetamigoAdapter } from "../../../lib/nextauth-adapter"; import { CloudflareAccessProvider } from "../../../lib/cloudflare"; const nextAuthOptions = (config: IAppConfig, req: NextApiRequest) => { const { nextAuth, cfaccess } = config; const adapter = MetamigoAdapter(config); const providers = []; const { audience, domain } = cfaccess; const cloudflareAccessEnabled = audience && domain; if (cloudflareAccessEnabled) providers.push(CloudflareAccessProvider(audience, domain, adapter, req)); else { if (nextAuth.google?.id) providers.push( Google({ clientId: nextAuth.google.id, clientSecret: nextAuth.google.secret, }) ); if (nextAuth.github?.id) providers.push( GitHub({ clientId: nextAuth.github.id, clientSecret: nextAuth.github.secret, }) ); if (nextAuth.gitlab?.id) providers.push( GitLab({ clientId: nextAuth.gitlab.id, clientSecret: nextAuth.gitlab.secret, }) ); if (nextAuth.cognito?.id) providers.push( Cognito({ clientId: nextAuth.cognito.id, clientSecret: nextAuth.cognito.secret, // domain: nextAuth.cognito.domain, }) ); } if (providers.length === 0) throw new Error( "No next-auth providers configured. See Metamigo configuration docs." ); return { secret: nextAuth.secret, session: { jwt: true, maxAge: 8 * 60 * 60, // 8 hours }, jwt: { secret: nextAuth.secret, encryption: false, signingKey: nextAuth.signingKey, encryptionKey: nextAuth.encryptionKey, }, providers, adapter, callbacks: { async session(session: any, token: any) { // make the user id available in the react client session.user.id = token.userId; return session; }, async jwt(token: any, user: any) { const isSignIn = Boolean(user); // Add auth_time to token on signin in if (isSignIn) { // not sure what this does // if (!token.aud) token.aud; token.aud = nextAuth.audience; token.picture = user.avatar; token.userId = user.id; token.role = user.userRole ? `app_${user.userRole}` : "app_anonymous"; } return token; }, }, }; }; const nextAuth = async ( req: NextApiRequest, res: NextApiResponse ): Promise => // @ts-expect-error: Type mismatch NextAuth(req, res, nextAuthOptions(await loadConfig(), req)); export default nextAuth;