41 lines
1.3 KiB
JavaScript
41 lines
1.3 KiB
JavaScript
// server/api/auth/login.post.js
|
|
import { getRequestIP } from "h3";
|
|
import { connectDB } from "../../utils/mongoose.js";
|
|
import { validateBody } from "../../utils/validateBody.js";
|
|
import { emailSchema } from "../../utils/schemas.js";
|
|
import { sendMagicLink } from "../../utils/magicLink.js";
|
|
import { rateLimit } from "../../utils/rateLimit.js";
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const ip = getRequestIP(event, { xForwardedFor: true }) || "unknown";
|
|
if (!rateLimit(`auth:login:ip:${ip}`, { max: 5, windowMs: 3600_000 })) {
|
|
throw createError({ statusCode: 429, statusMessage: "Too many login attempts" });
|
|
}
|
|
|
|
await connectDB();
|
|
|
|
const body = await validateBody(event, emailSchema);
|
|
|
|
if (!rateLimit(`auth:login:email:${body.email}`, { max: 3, windowMs: 3600_000 })) {
|
|
throw createError({
|
|
statusCode: 429,
|
|
statusMessage: "Too many login attempts for this email",
|
|
});
|
|
}
|
|
|
|
const GENERIC_MESSAGE = "If this email is registered, we've sent a login link.";
|
|
|
|
try {
|
|
await sendMagicLink(body.email);
|
|
return {
|
|
success: true,
|
|
message: GENERIC_MESSAGE,
|
|
};
|
|
} catch (error) {
|
|
console.error("Failed to send email:", error);
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage: "Failed to send login email. Please try again.",
|
|
});
|
|
}
|
|
});
|