diff options
| author | Joe Carstairs <me@joeac.net> | 2025-12-18 11:03:32 +0000 |
|---|---|---|
| committer | Joe Carstairs <me@joeac.net> | 2025-12-18 11:03:32 +0000 |
| commit | 40d6c7f248c3fe506690ee3ccb3894f952e164ed (patch) | |
| tree | fe135c14cb58385d109a3bfcadde46dc5ffcafba /website/src/actions/otp/send-otp.ts | |
| parent | a81d1de1e58ee2c314dbbea941dcb4e4a776ed84 (diff) | |
otp actions
Diffstat (limited to 'website/src/actions/otp/send-otp.ts')
| -rw-r--r-- | website/src/actions/otp/send-otp.ts | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/website/src/actions/otp/send-otp.ts b/website/src/actions/otp/send-otp.ts new file mode 100644 index 0000000..b349feb --- /dev/null +++ b/website/src/actions/otp/send-otp.ts @@ -0,0 +1,51 @@ +import crypto from "node:crypto"; +import { SENDMAIL_BIN } from "astro:env/server"; +import nodemailer from "nodemailer"; +import { z } from "astro/zod"; +import { defineAction } from "astro:actions"; +import { db, Otp } from "astro:db"; + +export default defineAction({ + input: z.object({ + email: z.string().email(), + name: z.string().optional(), + type: z.enum(["email"]), + }), + handler: sendOtp, +}); + +type OtpParams = { + email: string; + name?: string; + type: "email"; +}; + +async function sendOtp({ email, name }: OtpParams) { + const otp = crypto.randomBytes(3).toString("hex").toLocaleUpperCase(); + const otpPretty = `${otp.slice(0, 3)}-${otp.slice(3)}`; + + const info = await transporter.sendMail({ + from: `"Joe Carstairs" <me@joeac.net>`, + to: `${name ? `"${name}" ` : ""}<${email}>`, + subject: `joeac.net: your OTP is ${otpPretty}`, + text: ` +Someone tried to use this email address on joeac.net. If this was you, +your one-time passcode is ${otpPretty}. If this wasn't you, you don't need +to do anything.`, + }); + console.log( + `Sent OTP (${otpPretty}) to ${email}. Message ID: ${info.messageId}`, + ); + + await db.insert(Otp).values({ + userId: email, + value: otp, + createdAt: Date.now(), + validUntil: Date.now() + 1000 * 60 * 5, + }); +} + +const transporter = nodemailer.createTransport({ + sendmail: true, + path: SENDMAIL_BIN, +}); |
