Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions apps/web/src/server/api/routers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { z } from "zod";
import { createTRPCRouter, protectedProcedure, publicProcedure } from "~/server/api/trpc";
import { db } from "~/server/db";
import { TRPCError } from "@trpc/server";
import { sendEmailChangeVerificationEmail } from "~/server/mailer";
import { sendEmailChangeVerificationEmail, sendBackupEmailVerificationEmail } from "~/server/mailer";
import {
generateTwoFactorSecret,
verifyTwoFactorToken,
Expand Down Expand Up @@ -692,10 +692,8 @@ export const userRouter = createTRPCRouter({
},
});

// Store the hashed password in session (client will pass it back on verification)
// This is done client-side to avoid storing plaintext passwords in DB temporarily
// TODO: Send verification email to backup email address
// await sendBackupEmailVerificationEmail(backupEmail, code);
// Send verification email to backup email address
await sendBackupEmailVerificationEmail(backupEmail, code);

return {
step: "verify" as const,
Expand Down
23 changes: 23 additions & 0 deletions apps/web/src/server/mailer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,29 @@ export async function sendEmailChangeVerificationEmail(
await sendMail(email, finalSubject, text, html);
}

export async function sendBackupEmailVerificationEmail(
email: string,
token: string
) {
if (env.NODE_ENV === "development") {
logger.info({ email, token }, "Sending backup email verification code");
return;
}

const subject = "Verify your backup email address";
const text = `Hey,\n\nUse this verification code to confirm your backup email address:\n\n${token}\n\nThis code expires in 15 minutes.\n\nIf you did not request this, you can ignore this email.\n\nThanks,\nByteSend Team`;
const html = [
"<p>Hey,</p>",
"<p>Use this verification code to confirm your backup email address:</p>",
`<p style=\"font-size:24px;font-weight:700;letter-spacing:0.08em;\">${token}</p>`,
"<p>This code expires in 15 minutes.</p>",
"<p>If you did not request this, you can ignore this email.</p>",
"<p>Thanks,<br/>ByteSend Team</p>",
].join("");

await sendMail(email, subject, text, html);
}

export async function sendMail(
email: string,
subject: string,
Expand Down
Loading