diff --git a/pages/api/auth/[...nextauth].js b/pages/api/auth/[...nextauth].js
index 6696436b..65fc0419 100644
--- a/pages/api/auth/[...nextauth].js
+++ b/pages/api/auth/[...nextauth].js
@@ -1,8 +1,84 @@
import NextAuth from "next-auth";
-import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter";
import EmailProvider from "next-auth/providers/email";
-import * as entities from "../../../lib/entities";
+import { PrismaAdapter } from "@next-auth/prisma-adapter";
+import { PrismaClient } from "@prisma/client";
+import nodemailer from "nodemailer";
+const prisma = new PrismaClient();
+
+// async function sendVerificationRequest({
+// identifier: email,
+// url,
+// provider: { server, from },
+// }) {
+// const { host } = new URL(url);
+// const transport = nodemailer.createTransport(server);
+// await transport.sendMail({
+// to: email,
+// from,
+// subject: `Sign in to ${host}`,
+// text: text({ url, host }),
+// html: html({ url, host, email }),
+// });
+// }
+// Email HTML body
+function html({ url, host, email }) {
+ // Insert invisible space into domains and email address to prevent both the
+ // email address and the domain from being turned into a hyperlink by email
+ // clients like Outlook and Apple mail, as this is confusing because it seems
+ // like they are supposed to click on their email address to sign in.
+ const escapedEmail = `${email.replace(/\./g, ".")}`;
+ const escapedHost = `${host.replace(/\./g, ".")}`;
+
+ // Some simple styling options
+ const backgroundColor = "#ffffff";
+ const textColor = "#444444";
+ const mainBackgroundColor = "#ffffff";
+ const buttonBackgroundColor = "#aa1111";
+ const buttonBorderColor = "#aa1111";
+ const buttonTextColor = "#ffffff";
+ const headerBackgroundColor = "#000000";
+
+ return `
+
+ If you did not request this email you can safely ignore it.
+
+
+
+
+ `;
+}
+
+// Email Text body (fallback for email clients that don't render HTML, e.g. feature phones)
+function text({ url, host }) {
+ return `Sign in to PEDW - Planning Casework\n${url}\n\n`;
+}
// For more information on each option (and a full list of options) go to
// https://next-auth.js.org/configuration/options
export default NextAuth({
@@ -19,19 +95,35 @@ export default NextAuth({
},
from: process.env.EMAIL_FROM,
maxAge: 10 * 60, // Magic links are valid for 10 min only
+ async sendVerificationRequest({
+ identifier: email,
+ url,
+ provider: { server, from },
+ }) {
+ const { host } = new URL(url);
+ const transport = nodemailer.createTransport(server);
+ await transport.sendMail({
+ to: email,
+ from,
+ subject: `Sign in to PEDW - Planning Casework`,
+ text: text({ url, host }),
+ html: html({ url, host, email }),
+ });
+ },
}),
],
- adapter: TypeORMLegacyAdapter({
- type: "mysql",
- database:
- "mysql://nextAuthAdmin:!Sky9fish1972@77.68.17.157:3306/nextauthDB?synchronise=true",
- synchronize: false,
- }),
- secret: "SuperSecret",
+ adapter: PrismaAdapter(prisma),
session: {
jwt: true,
pages: {},
theme: "dark",
debug: true,
},
+ pages: {
+ signIn: "/auth/signin",
+ //signOut: "/auth/signout",
+ error: "/auth/error", // Error code passed in query string as ?error=
+ verifyRequest: "/auth/verify-request", // (used for check email message)
+ // newUser: "/auth/new-user", // New users will be directed here on first sign in (leave the property out if not of interest)
+ },
});
diff --git a/pages/auth/error.js b/pages/auth/error.js
new file mode 100644
index 00000000..2d0113b0
--- /dev/null
+++ b/pages/auth/error.js
@@ -0,0 +1,80 @@
+import useTranslation from "next-translate/useTranslation";
+import Head from "next/head";
+import Link from "next/link";
+import CookieBanner from "../../components/cookieBanner";
+import Footer from "../../components/footer";
+import Header from "../../components/header";
+import Breadcrumbs from "../../components/breadcrumbs";
+import { useRouter } from "next/router";
+
+import { getCsrfToken } from "next-auth/react";
+
+const Error = (props) => {
+ let { t, lang } = useTranslation();
+ const { footerLinks, pages, csrfToken } = props;
+
+ const { error } = useRouter().query;
+
+ const errors = {
+ Signin: "Try signing with a different account.",
+ OAuthSignin: "Try signing with a different account.",
+ OAuthCallback: "Try signing with a different account.",
+ OAuthCreateAccount: "Try signing with a different account.",
+ EmailCreateAccount: "Try signing with a different account.",
+ Callback: "Try signing with a different account.",
+ OAuthAccountNotLinked:
+ "To confirm your identity, sign in with the same account you used originally.",
+ EmailSignin: "Check your email address.",
+ CredentialsSignin:
+ "Sign in failed. Check the details you provided are correct.",
+ Verification:
+ "Unable to sign in. The sign in link is no longer valid.It may have been used already or it may have expired. ",
+ default: "Unable to sign in.",
+ };
+
+ const errorMessage = error && (errors[error] ?? errors.default);
+
+ return (
+
+
+ Sign in Error - {t("common:service-name")}
+
+
+
+
+
+
+
+
+
+
+
There has been an error
+
+
+
+
+ {errorMessage}
+
+
+
+
+ {" "}
+ Return to Home
+
+
+
+
+
+
+
+ );
+};
+
+export async function getServerSideProps(context) {
+ const csrfToken = await getCsrfToken(context);
+ return {
+ props: { csrfToken },
+ };
+}
+
+export default Error;
diff --git a/pages/auth/signin.js b/pages/auth/signin.js
new file mode 100644
index 00000000..e389cf3b
--- /dev/null
+++ b/pages/auth/signin.js
@@ -0,0 +1,82 @@
+import useTranslation from "next-translate/useTranslation";
+import Head from "next/head";
+import Link from "next/link";
+import CookieBanner from "../../components/cookieBanner";
+import Footer from "../../components/footer";
+import Header from "../../components/header";
+import Breadcrumbs from "../../components/breadcrumbs";
+import { getCsrfToken } from "next-auth/react";
+
+const SignIn = (props) => {
+ let { t, lang } = useTranslation();
+ const { footerLinks, pages, csrfToken } = props;
+
+ return (
+
+
+ Sign in - {t("common:service-name")}
+
+
+
+
+
+
+
+
+
+
Sign in
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export async function getServerSideProps(context) {
+ const csrfToken = await getCsrfToken(context);
+ return {
+ props: { csrfToken },
+ };
+}
+
+export default SignIn;
diff --git a/pages/auth/verify-request.js b/pages/auth/verify-request.js
new file mode 100644
index 00000000..53708db1
--- /dev/null
+++ b/pages/auth/verify-request.js
@@ -0,0 +1,59 @@
+import useTranslation from "next-translate/useTranslation";
+import Head from "next/head";
+import Link from "next/link";
+import CookieBanner from "../../components/cookieBanner";
+import Footer from "../../components/footer";
+import Header from "../../components/header";
+import Breadcrumbs from "../../components/breadcrumbs";
+
+import { getCsrfToken } from "next-auth/react";
+
+const SignIn = (props) => {
+ let { t, lang } = useTranslation();
+ const { footerLinks, pages, csrfToken } = props;
+
+ return (
+
+
+ Sign in - {t("common:service-name")}
+
+
+
+
+
+
+
+
+
+
+
Check your email
+
+
+
+
+ A link has been sent to your email so you can
+ continue
+