Aller au contenu
Krizaka TypeScript
Krizaka TypeScript

@krizaka/email-verification

La preuve d’une adresse courriel pour les formulaires publics : un code à 6 chiffres valable 15 minutes, à usage unique, cinq essais, gardé sous forme de hachage salé ; le message n’est libéré qu’après le code.

Installer

bashTerminal
npm install @krizaka/email-verification

Aussi publié en sous-chemins : @krizaka/email-verification/testkit.

Le README ci-dessous est celui du paquet sur npm, en anglais.

Proof that a person controls an e-mail address, for every Krizaka public form (rule email-verification of the org registry: public e-mail forms verify the address). The message is held and delivered only after the code is confirmed (verify first): a bot that types someone else's address costs that person one e-mail and the team nothing.

  • a 6-digit code (crypto.randomInt), valid 15 minutes, single use, 5 tries (then the challenge is destroyed);
  • the store keeps only a salted HMAC of id + address + code and the held payload — never the code, never the address in the clear;
  • the proof binds the address: the right code with another address is refused;
  • mail texts EN and FR (verificationMail); the module never sends: the product queues the mail (@krizaka/mail, Mailgun, …);
  • no environment variable, no wall clock (now is injected), no vendor; the secret comes in as a parameter (≥ 32 characters).
import { createEmailVerification, memoryCodeStore, verificationMail } from "@krizaka/email-verification";

const verification = createEmailVerification({ store: memoryCodeStore(), secret, now: () => new Date() });

// 1. the form is posted (after its CAPTCHA and rate limit): hold the message, mail the code
const { challengeId, code, ttlMinutes } = await verification.issue({ address, payload: message });
await send({ to: address, ...verificationMail({ locale, code, ttlMinutes }) });
// answer { challengeId } — the browser asks for the code

// 2. the visitor returns the code
const result = await verification.confirm<Message>({ challengeId, address, code });
if (result.ok) await deliver(result.payload);          // released once
else /* result.reason: invalid (attemptsLeft) | expired | locked | unknown */;

memoryCodeStore is right for one instance and for tests (a visitor who lands on another instance, or after a restart, is asked for a new code). A product with several instances implements CodeStore (5 methods) and runs codeStoreContract from @krizaka/email-verification/testkit.

Callers still own the rate limit of issue (@krizaka/rate-limit: per address and per IP, so the code mail cannot be used to flood a mailbox) and the CAPTCHA (@krizaka/rate-limit/turnstile).

Exports

Les 19 noms que le paquet exporte, lus dans ses types.

NomNatureCe que c’est
ChallengetypeOne pending proof, as the store keeps it.
CodeStoretypeWhere challenges live.
createEmailVerificationfonctionThe verification of an address: issue holds an action (the payload) and produces the code to mail; confirm releases the action only for the right code, a…
DEFAULT_MAX_CHALLENGESconstanteThe memory bound of the in-process store, not a business parameter.
DEFAULT_SETTINGSconstante
EmailVerificationtype
EmailVerificationOptionstype
IssuedtypeWhat issue returns: mail code to the address; hand challengeId back to the browser (it is not secret, it is useless without the code).
memoryCodeStorefonctionChallenges kept in this process: right for one instance and for tests.
MIN_SECRET_LENGTHconstanteThe shortest secret accepted: it salts every proof, so a leaked store alone cannot be brute-forced offline.
VERIFICATION_CODEconstante
VerificationErrorclasse
VerificationLocaletypeThe mail that carries the code, in the visitor's language.
verificationMailfonctionSubject, text and HTML of the code mail.
VerificationMailtype
VerificationSettingstypeWhat a product tunes.
VERIFY_FAILUREconstanteWhy a confirmation was refused.
VerifyFailuretype
VerifyResulttype

@krizaka/email-verification/testkit

NomNatureCe que c’est
codeStoreContractfonctionWhat every CodeStore adapter must do: the same behaviour behind the same port.

Paquet

Version sur npm0.1.1 (npm)
LicenceApache-2.0
Node.js>=22
Dépendances@krizaka/time workspace:^
Dépendances à fournirvitest >=4
Code sourceemail-verification

Journal des versions

0.1.1

Patch changes

0.1.0

Minor changes

  • New package: proof of an e-mail address for public forms (createEmailVerification): a 6-digit code valid 15 minutes, single use, 5 tries, kept as a salted hash; the action is held and released only after the code is confirmed. memoryCodeStore, codeStoreContract (/testkit), EN/FR verificationMail. Org rule email-verification (krizaka/.github#464).

Sur cette page