mirror of
https://github.com/BradNut/example-sveltekit-email-password-webauthn
synced 2025-09-08 17:40:27 +00:00
73 lines
1.7 KiB
TypeScript
73 lines
1.7 KiB
TypeScript
import { recoveryCodeBucket, resetUser2FAWithRecoveryCode } from "$lib/server/2fa";
|
|
import { fail, redirect } from "@sveltejs/kit";
|
|
|
|
import type { Actions, RequestEvent } from "./$types";
|
|
|
|
export const actions: Actions = {
|
|
default: action
|
|
};
|
|
|
|
export async function load(event: RequestEvent) {
|
|
if (event.locals.user === null || event.locals.session === null) {
|
|
return redirect(302, "/login");
|
|
}
|
|
if (!event.locals.user.emailVerified) {
|
|
return redirect(302, "/verify-email");
|
|
}
|
|
if (!event.locals.user.registered2FA) {
|
|
return redirect(302, "/2fa/setup");
|
|
}
|
|
if (event.locals.session.twoFactorVerified) {
|
|
return redirect(302, "/");
|
|
}
|
|
return {};
|
|
}
|
|
|
|
async function action(event: RequestEvent) {
|
|
if (event.locals.session === null || event.locals.user === null) {
|
|
return fail(401, {
|
|
message: "Not authenticated"
|
|
});
|
|
}
|
|
if (!event.locals.user.emailVerified) {
|
|
return fail(403, {
|
|
message: "Forbidden"
|
|
});
|
|
}
|
|
if (!event.locals.user.registered2FA) {
|
|
return fail(403, {
|
|
message: "Forbidden"
|
|
});
|
|
}
|
|
if (!recoveryCodeBucket.check(event.locals.user.id, 1)) {
|
|
return fail(429, {
|
|
message: "Too many requests"
|
|
});
|
|
}
|
|
|
|
const formData = await event.request.formData();
|
|
const code = formData.get("code");
|
|
if (typeof code !== "string") {
|
|
return fail(400, {
|
|
message: "Invalid or missing fields"
|
|
});
|
|
}
|
|
if (code === "") {
|
|
return fail(400, {
|
|
message: "Please enter your code"
|
|
});
|
|
}
|
|
if (!recoveryCodeBucket.consume(event.locals.user.id, 1)) {
|
|
return fail(429, {
|
|
message: "Too many requests"
|
|
});
|
|
}
|
|
const valid = resetUser2FAWithRecoveryCode(event.locals.user.id, code);
|
|
if (!valid) {
|
|
return fail(400, {
|
|
message: "Invalid recovery code"
|
|
});
|
|
}
|
|
recoveryCodeBucket.reset(event.locals.user.id);
|
|
return redirect(302, "/2fa/setup");
|
|
}
|