UNPKG

aegis-auth

Version:

A credentials-based auth solution for Next.js (and other Node projects) with IP rate-limiting, account lockouts, and sessions in DB.

97 lines 3.65 kB
import { VerificationType } from "@prisma/client"; import { sendVerificationEmail } from "../emails"; import { ErrorCodes, } from "../types"; import { limitIpAttempts } from "../utils"; import { initiateEmailChangeSchema } from "../validations"; import { createVerification } from "./createVerification"; export async function initiateEmailChange(context, input) { var _a; const { prisma, config, limiters, parsedRequest } = context; const { ipAddress } = parsedRequest !== null && parsedRequest !== void 0 ? parsedRequest : {}; try { const validatedInput = initiateEmailChangeSchema.safeParse(input); if (!validatedInput.success) { config.logger.securityEvent("INVALID_INPUT", { route: "initiateEmailChange", ipAddress, }); return { success: false, status: 400, message: "Invalid input provided", code: ErrorCodes.INVALID_INPUT, }; } const { userId, newEmail } = validatedInput.data; if (config.rateLimiting.initiateEmailChange.enabled && ipAddress) { const limiter = limiters.initiateEmailChange; const limit = await limitIpAttempts({ ipAddress, limiter }); if (!limit.success) { config.logger.securityEvent("RATE_LIMIT_EXCEEDED", { route: "initiateEmailChange", ipAddress, }); return { success: false, status: 429, message: "Too many attempts. Try again later.", code: ErrorCodes.RATE_LIMIT_EXCEEDED, }; } } const existingUser = (await prisma.user.findFirst({ where: { OR: [{ email: newEmail }, { pendingEmail: newEmail }], }, })); if (existingUser) { return { success: false, status: 400, message: "Email is already in use", code: ErrorCodes.EMAIL_IN_USE, }; } await prisma.user.update({ where: { id: userId }, data: { pendingEmail: newEmail }, }); const verification = await createVerification(context, { userId, type: VerificationType.EMAIL_CHANGE, }); if (!verification.success || !((_a = verification.data) === null || _a === void 0 ? void 0 : _a.verification)) { return { success: false, status: 500, message: "Failed to create email change verification.", code: ErrorCodes.INTERNAL_SERVER_ERROR, }; } const { token } = verification.data.verification; await sendVerificationEmail({ toEmail: newEmail, token, config: context.config, }); return { success: true, status: 200, message: "Verification email sent to your new email address.", }; } catch (error) { config.logger.error("Error initiating email change", { error, email: input.newEmail, ipAddress: parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.ipAddress, }); return { success: false, status: 500, message: "An unexpected error occurred.", code: ErrorCodes.INTERNAL_SERVER_ERROR, }; } } //# sourceMappingURL=initiateEmailChange.js.map