Passwordless logins
Mailbox challenges also work well for passwordless login flows.
Generate and email the challenge
Section titled “Generate and email the challenge”import { Passlock, isChallengeRateLimitedError } from "@passlock/server";
const passlock = new Passlock({ ... });
// cpatured in a login formconst email = "...";
const user = await findUserByEmail(email);if (!user) { throw new Error("Account not found");}
const result = await passlock.createMailboxChallenge({ email, userId: user.id, purpose: "login", // any pending "login" challenges for this userId will be nuked invalidateOthers: true,});
if (result.success) { const { challengeId, secret, message } = result.value.challenge;
// save this in the user's session or a secure HTTP only cookie await savePendingChallenge({ purpose: "login" challengeId, secret, });
await emailCodeToUser({ email, message });} else if (isChallengeRateLimitedError(result.error)) { return showRateLimit(result.error.retryAfterSeconds);} else { throw new Error(result.error.message);}Verify the code and create a session
Section titled “Verify the code and create a session”import { Passlock } from "@passlock/server";
const passlock = new Passlock({... });
// fetch from the user's session or secure cookieconst pendingChallenge = await loadPendingChallenge({ purpose: "login" });
const result = await passlock.verifyMailboxChallenge({ challengeId: pendingChallenge.challengeId, secret: pendingChallenge.secret, code: form.code, // the user submitted this});
if (result.success) { const { challenge } = result.value; await createLoginSession(challenge.userId);} else { return throw new Error(result.error.message);}