Files
pedwfrontend/pages/api/auth/[...nextauth].js
T
Robert Bond 15c35d201e Merged PR 2244: added condition to fix log in journey in welsh if no account in crm
added condition to fix log in journey in welsh if no account in crm

Related work items: #22081, #22303
2026-04-13 15:54:51 +00:00

254 lines
8.0 KiB
JavaScript

/**
* @swagger
* /api/auth/[...nextauth]:
* get:
* summary: Phase 2
* tags: [Login]
* description: NextAuth
* responses:
* 200:
* description: Success
*/
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";
import NextAuth from "next-auth";
import EmailProvider from "next-auth/providers/email";
import { consoleLogger } from "../../../actions/core/logger";
import { getPortalLogin } from "../../../actions/services/accountService";
const prisma = new PrismaClient();
const WELSH_LANGUAGE_CODE = 846040000;
const appendParamsAndPathToNewUrl = (fromUrl, toUrl) => {
const fromUrlObj = new URL(fromUrl);
const params = fromUrlObj.searchParams;
const toUrlObj = new URL(toUrl);
toUrlObj.pathname = fromUrlObj.pathname;
params.forEach((value, key) => {
if (!toUrlObj.searchParams.has(key)) {
toUrlObj.searchParams.append(key, value);
}
});
return toUrlObj.toString();
};
const resolveRequestLocale = (req) => {
const locale =
req?.body?.locale || req?.query?.locale || req?.cookies?.pedw_locale;
return locale === "cy" ? "cy" : "en";
};
const resolveCrmLocale = async (email) => {
if (!email) return null;
try {
const portalUserObj = await getPortalLogin(email);
const preferredLanguage =
portalUserObj?.value?.[0]?.pinswg_preferredlanguage;
if (preferredLanguage === WELSH_LANGUAGE_CODE) {
return "cy";
}
if (preferredLanguage != null) {
return "en";
}
return null;
} catch (error) {
consoleLogger(error);
return null;
}
};
const resolveEffectiveLocale = async (req, email) => {
const crmLocale = await resolveCrmLocale(email);
if (crmLocale) return crmLocale;
return resolveRequestLocale(req);
};
const buildLocalizedVerificationUrl = ({ url, email, effectiveLocale }) => {
const { host, protocol, searchParams } = new URL(url);
const baseDomain = `${protocol}//${host}`;
const newURL =
effectiveLocale === "cy"
? baseDomain +
"/api/auth/callback/email?callbackUrl=" +
encodeURIComponent(baseDomain + "/cy") +
"&token=" +
searchParams.get("token") +
"&email=" +
encodeURIComponent(email) +
"&locale=" +
effectiveLocale
: url;
return appendParamsAndPathToNewUrl(url, newURL);
};
const authOptions = (req, res) => {
const requestLocale = resolveRequestLocale(req);
return {
providers: [
{
id: "emailAPI",
name: "emailAPI",
type: "email",
async sendVerificationRequest({ identifier: email, url }) {
const effectiveLocale = await resolveEffectiveLocale(
req,
email
);
console.log(
"============================================================\n",
"verification url API: " + url + "\n",
"============================================================\n"
);
const formURL = buildLocalizedVerificationUrl({
url,
email,
effectiveLocale
});
console.log(
"============================================================\n",
"new verification url----: " + formURL + "\n",
"============================================================\n"
);
return res
.writeHead(200, { "Content-Type": "application/json" })
.json({ url: formURL });
}
},
EmailProvider({
maxAge: 2 * 60 * 60,
async sendVerificationRequest({ identifier: email, url }) {
const templateId = "b1b5704b-9bb8-4deb-a75c-d887ca902661";
const templateIdcy = "0614ce53-cd5f-421f-a1a5-8c8486a9113a";
const effectiveLocale = await resolveEffectiveLocale(
req,
email
);
console.log(
"============================================================\n",
"verification url----: " + url + "\n",
"============================================================\n"
);
const formURL = buildLocalizedVerificationUrl({
url,
email,
effectiveLocale
});
console.log(
"============================================================\n",
"new verification url----: " + formURL + "\n",
"============================================================\n"
);
const personalisation = {
emailAddress: email,
signInLink: formURL,
linkExpiry: 2 * 60 * 60
};
const reference = "PEDW-SIGNIN";
var NotifyClient =
require("notifications-node-client").NotifyClient;
const notifyClient = new NotifyClient(
process.env.NOTIFY_API_KEY
);
try {
await notifyClient.sendEmail(
effectiveLocale === "cy"
? templateIdcy
: templateId,
email,
{
personalisation,
reference
}
);
} catch (error) {
consoleLogger(error);
}
}
})
],
adapter: PrismaAdapter(prisma),
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: "database",
jwt: true,
pages: {},
theme: "dark",
debug: true,
maxAge: 30 * 60,
updateAge: 5 * 60
},
cookies: {
callbackUrl: {
name: `__Secure-next-auth.callback-url`,
options: {
sameSite: "lax",
path: "/",
secure: true
}
}
},
pages: {
signIn: (requestLocale === "cy" ? "/cy" : "") + "/auth/signin",
error: (requestLocale === "cy" ? "/cy" : "") + "/auth/error",
verifyRequest:
(requestLocale === "cy" ? "/cy" : "") + "/auth/verify-request",
newUser: (requestLocale === "cy" ? "/cy" : "") + "/account/register"
},
callbacks: {
session: async (session, user) => {
console.log("callback in auth", session, user);
return Promise.resolve(session);
},
redirect({ url, baseUrl }) {
console.log("baseurl:", url, baseUrl);
if (url.startsWith("/")) return `${baseUrl}${url}`;
if (new URL(url).origin === baseUrl) return url;
const newUrl =
requestLocale === "cy"
? process.env.CY_API_ROOT
: process.env.NEXTAUTH_URL;
const updatedUrl = appendParamsAndPathToNewUrl(url, newUrl);
console.log(updatedUrl);
return updatedUrl;
}
}
};
};
const NextAuthPEDW = (req, res) => {
return NextAuth(req, res, authOptions(req, res));
};
export default NextAuthPEDW;