253 lines
8.0 KiB
JavaScript
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;
|