import { GetServerSideProps, NextPage } from "next"; import Head from "next/head"; import { useRouter } from "next/router"; import { usePlausible } from "next-plausible"; import React from "react"; import toast from "react-hot-toast"; import { useTimeoutFn } from "react-use"; import { decryptToken, mergeGuestsIntoUser, withSessionSsr } from "utils/auth"; import { nanoid } from "utils/nanoid"; import FullPageLoader from "@/components/full-page-loader"; import { prisma } from "../db"; const Page: NextPage<{ success: boolean; redirectTo: string }> = ({ success, redirectTo, }) => { const router = useRouter(); const pluasible = usePlausible(); if (!success) { toast.error("Login failed! Link is expired or invalid"); } useTimeoutFn(() => { if (success) { pluasible("Login completed"); } router.replace(redirectTo); }, 100); return ( <> Logging in… Logging in… ); }; export const getServerSideProps: GetServerSideProps = withSessionSsr( async ({ req, query }) => { const { code } = query; if (typeof code !== "string") { return { props: {}, redirect: { destination: "/new", }, }; } const { email, path = "/new", guestId, } = await decryptToken<{ email?: string; path?: string; guestId?: string; }>(code); if (!email) { return { props: { success: false, redirectTo: path, }, }; } const user = await prisma.user.upsert({ where: { email }, update: {}, create: { id: await nanoid(), name: email.substring(0, email.indexOf("@")), email, }, }); const guestIds: string[] = []; // guest id from existing sessions if (req.session.user?.isGuest) { guestIds.push(req.session.user.id); } // guest id from token if (guestId && guestId !== req.session.user?.id) { guestIds.push(guestId); } if (guestIds.length > 0) { await mergeGuestsIntoUser(user.id, guestIds); } req.session.user = { isGuest: false, name: user.name, email: user.email, id: user.id, }; await req.session.save(); return { props: { success: true, redirectTo: path, }, }; }, ); export default Page;