@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
npm install @krizaka/email-verificationAussi 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 + codeand 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 (
nowis 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.
| Nom | Nature | Ce que c’est |
|---|---|---|
Challenge | type | One pending proof, as the store keeps it. |
CodeStore | type | Where challenges live. |
createEmailVerification | fonction | The 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_CHALLENGES | constante | The memory bound of the in-process store, not a business parameter. |
DEFAULT_SETTINGS | constante | |
EmailVerification | type | |
EmailVerificationOptions | type | |
Issued | type | What issue returns: mail code to the address; hand challengeId back to the browser (it is not secret, it is useless without the code). |
memoryCodeStore | fonction | Challenges kept in this process: right for one instance and for tests. |
MIN_SECRET_LENGTH | constante | The shortest secret accepted: it salts every proof, so a leaked store alone cannot be brute-forced offline. |
VERIFICATION_CODE | constante | |
VerificationError | classe | |
VerificationLocale | type | The mail that carries the code, in the visitor's language. |
verificationMail | fonction | Subject, text and HTML of the code mail. |
VerificationMail | type | |
VerificationSettings | type | What a product tunes. |
VERIFY_FAILURE | constante | Why a confirmation was refused. |
VerifyFailure | type | |
VerifyResult | type |
@krizaka/email-verification/testkit
| Nom | Nature | Ce que c’est |
|---|---|---|
codeStoreContract | fonction | What every CodeStore adapter must do: the same behaviour behind the same port. |
Paquet
| Version sur npm | 0.1.1 (npm) |
| Licence | Apache-2.0 |
| Node.js | >=22 |
| Dépendances | @krizaka/time workspace:^ |
| Dépendances à fournir | vitest >=4 |
| Code source | email-verification |
Journal des versions
0.1.1
Patch changes
- Updated dependencies [2a7898c]
- @krizaka/[email protected]
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/FRverificationMail. Org ruleemail-verification(krizaka/.github#464).