Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 6x 5x 5x 5x 1x 4x 4x 4x 1x 3x 3x 3x 1x 2x 2x 2x | import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { generateResetPasswordEmail } from "~web/email/utils";
import { unauthProcedure } from "~web/handlers/trpc";
import { MAX_INTENTIONS_AMOUNT, emailSchema } from "~web/handlers/validation";
import { getEmailClient } from "~web/providers/email";
export const procedure = unauthProcedure
.meta({
title: "Add reset password intention",
description:
"Sends a password reset email for a given email address, up to a daily limit of pending intentions.",
})
.input(
z.strictObject({
email: emailSchema,
}),
)
.mutation(async ({ input, ctx }) => {
const { database } = ctx;
const user = await database
.selectFrom("users")
.select("id")
.where("email", "=", input.email.lowercase)
.limit(1)
.executeTakeFirst();
if (!user) {
throw new TRPCError({
code: "NOT_FOUND",
message: `User "${input.email.original}" does not exist.`,
});
}
const uuid: string = ctx.getUuid();
const expirationDate = Temporal.Now.zonedDateTimeISO().add({
days: 1,
});
if (!ctx.emailOptions.getActive()) {
throw new TRPCError({
code: "FORBIDDEN",
message: `Currently password reset is not supported.`,
});
}
const currentIntentions = await database
.selectFrom("resetPasswordIntentions")
.where((eb) =>
eb("resetPasswordIntentions.userId", "=", user.id).and(
"expiresTimestamp",
">",
Temporal.Now.zonedDateTimeISO(),
),
)
.select("expiresTimestamp")
.execute();
if (currentIntentions.length >= MAX_INTENTIONS_AMOUNT) {
throw new TRPCError({
code: "FORBIDDEN",
message: `Maximum amount of intentions per day is ${MAX_INTENTIONS_AMOUNT}, please try later.`,
});
}
await database
.insertInto("resetPasswordIntentions")
.values({
userId: user.id,
expiresTimestamp: expirationDate,
token: uuid,
})
.executeTakeFirst();
const data = await generateResetPasswordEmail(uuid, ctx);
await getEmailClient(ctx).send({ address: input.email.lowercase, ...data });
});
|