mirror of
https://github.com/hanzo-apps/dataroom.git
synced 2026-11-02 22:04:20 +00:00
- Replace all Papermark branding with Hanzo Dataroom - Update metadata, titles, descriptions, OG tags - Update email templates footer and branding - Replace papermark.io/com URLs with dataroom.hanzo.ai - Update powered-by component - Update x-powered-by header - Update legal references to Hanzo AI, Inc. - Update social handles to @hanzoai - Update README, CLA, LICENSE, SECURITY docs
135 lines
3.1 KiB
TypeScript
135 lines
3.1 KiB
TypeScript
import { Metadata } from "next";
|
|
import { redirect } from "next/navigation";
|
|
|
|
import NotFound from "@/pages/404";
|
|
import { VerificationToken } from "@prisma/client";
|
|
import { waitUntil } from "@vercel/functions";
|
|
|
|
import { hashToken } from "@/lib/api/auth/token";
|
|
import prisma from "@/lib/prisma";
|
|
import { redis } from "@/lib/redis";
|
|
import { sendEmail, subscribe, unsubscribe } from "@/lib/resend";
|
|
import { CustomUser } from "@/lib/types";
|
|
|
|
import EmailUpdated from "@/components/emails/email-updated";
|
|
|
|
import ConfirmEmailChangePageClient from "./page-client";
|
|
import { getSession } from "./utils";
|
|
|
|
export const runtime = "nodejs";
|
|
|
|
const data = {
|
|
description: "Confirm email change",
|
|
title: "Confirm email change | Hanzo Dataroom",
|
|
url: "/auth/confirm-email-change",
|
|
};
|
|
|
|
export const metadata: Metadata = {
|
|
metadataBase: new URL("https://dataroom.hanzo.ai"),
|
|
title: data.title,
|
|
description: data.description,
|
|
openGraph: {
|
|
title: data.title,
|
|
description: data.description,
|
|
url: data.url,
|
|
siteName: "Hanzo Dataroom",
|
|
images: [
|
|
{
|
|
url: "/_static/meta-image.png",
|
|
width: 800,
|
|
height: 600,
|
|
},
|
|
],
|
|
locale: "en_US",
|
|
type: "website",
|
|
},
|
|
twitter: {
|
|
card: "summary_large_image",
|
|
title: data.title,
|
|
description: data.description,
|
|
creator: "@hanzoai",
|
|
images: ["/_static/meta-image.png"],
|
|
},
|
|
};
|
|
|
|
interface PageProps {
|
|
params: Promise<{ token: string }>;
|
|
}
|
|
|
|
export default async function ConfirmEmailChangePage(props: PageProps) {
|
|
return (
|
|
<div className="flex flex-col items-center justify-center gap-6 text-center">
|
|
<VerifyEmailChange {...props} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const VerifyEmailChange = async ({ params }: PageProps) => {
|
|
const { token } = await params;
|
|
const tokenFound = await prisma.verificationToken.findUnique({
|
|
where: {
|
|
token: hashToken(token),
|
|
},
|
|
});
|
|
|
|
if (!tokenFound || tokenFound.expires < new Date()) return <NotFound />;
|
|
|
|
const session = await getSession();
|
|
|
|
if (!session) {
|
|
redirect(`/login?next=/auth/confirm-email-change/${token}`);
|
|
}
|
|
|
|
const currentUserId = (session.user as CustomUser).id;
|
|
|
|
const data = await redis.get<{ email: string; newEmail: string }>(
|
|
`email-change-request:user:${currentUserId}`,
|
|
);
|
|
|
|
if (!data) return <NotFound />;
|
|
|
|
await unsubscribe(data.email);
|
|
|
|
await prisma.user.update({
|
|
where: {
|
|
id: currentUserId,
|
|
},
|
|
data: {
|
|
email: data.newEmail,
|
|
},
|
|
});
|
|
|
|
waitUntil(
|
|
Promise.all([
|
|
deleteRequest(tokenFound),
|
|
|
|
subscribe(data.newEmail),
|
|
|
|
sendEmail({
|
|
to: data.email,
|
|
subject: "Your email address has been changed",
|
|
system: true,
|
|
react: EmailUpdated({
|
|
oldEmail: data.email,
|
|
newEmail: data.newEmail,
|
|
}),
|
|
test: process.env.NODE_ENV === "development",
|
|
}),
|
|
]),
|
|
);
|
|
|
|
return <ConfirmEmailChangePageClient />;
|
|
};
|
|
|
|
const deleteRequest = async (tokenFound: VerificationToken) => {
|
|
await Promise.all([
|
|
prisma.verificationToken.delete({
|
|
where: {
|
|
token: tokenFound.token,
|
|
},
|
|
}),
|
|
|
|
redis.del(`email-change-request:user:${tokenFound.identifier}`),
|
|
]);
|
|
};
|