Files
pedwfrontend/pages/api/auth/[...nextauth].js
T

253 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) =>
req?.query?.locale ||
req?.body?.locale ||
req?.cookies?.pedw_locale ||
"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;