halkyon/packages/halkyon_base_server/migrations/migration_registry.txt

15 lines
570 B
Text
Raw Normal View History

### AUTOMATICALLY GENERATED DO NOT MODIFY
###
### This file is generated by Serverpod when creating a migration, do not modify it
### manually. If a collision is detected in this file when doing a code merge, resolve
### the conflict by removing and recreating the conflicting migration.
20261019115750898
20261019200558685
20261019202835333-deletion-notices
feat(auth): a password with TOTP on the register, and resets The register's side of signing in with an address, a password that never leaves the device (SRP-6a) and a code from an authenticator (ADR 0017), with members forwarding every step through AccountRegister: - password.set: salt, Argon2id's costs, SRP's verifier, the public keys and the private keys wrapped twice, all made on the device; with the address a mailed code proves, an anonymous person becomes identified under their ID. It signs in once an authenticator is confirmed. - passwordSignIn.begin and complete: SRP's two steps with a TOTP or recovery code. An address nobody has is answered from a decoy key as an account would be; every wrong credential is refused alike. - authenticator: secrets sealed under totpKey (XChaCha20-Poly1305, bound to their row), each code accepted once, ten recovery codes with the first, the last one kept. - accountRecovery: a lost authenticator reset 72 hours after the password and a mailed code or the recovery phrase ask, a lost password set anew with the phrase's signature, or the account reset with new keys 72 hours after a mailed code asks; a mail at each start, a sign-in calling it off. - An account with a password no longer signs in by a mailed code or GitHub; no new GitHub account is linked where passwords are offered, and from GITHUB_SIGN_IN_ENDS GitHub signs nobody in and its IDs go. Five tables, added by the module's migration; deletePerson deletes their rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-20 13:32:12 +02:00
20261020111123780-passwords
20261020124836165-sessions-ended
20261020185619505-recovery-proof-key
fix(auth): codes wait after ten wrong in a row, and the owner is told Whoever knew the password could guess codes at 10 an hour forever, unnoticed, each guess checked against every authenticator (the second reading's M4). Every code an account's second factor refuses after a right password (sign-in, a phrase's reset, a change) or from a signed-in device (removing an authenticator, new recovery codes, the code from one confirmed before) now counts, per account, from every network; after every tenth in a row no code is taken (codesWait, saying until when), an hour, then twice as long each time, a day at the most (longestCodeWait, second_factor_waits.dart): at a day, ten guesses a day still have about a 1 % chance a year against one authenticator, so the first wait mails the owner that someone knows their password. The instance keeps no address, so sign-in and the phrase's reset now send the address the device typed (and its language), used only for that mail after its hash is checked against the account's. A code accepted clears it all. Migration (module, Learn's and Todo's servers, Learn's device schema): CREATE TABLE "second_factor_failures" ("id" bigserial PRIMARY KEY, "authUserId" uuid NOT NULL, "failures" bigint NOT NULL, "waits" bigint NOT NULL, "waitUntil" timestamp, "updatedAt" timestamp NOT NULL) with a unique index on "authUserId": a new table, nothing touched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-20 21:47:38 +02:00
20261020194005842-second-factor-waits
fix(auth): a session's wrong codes end the session, not the account's codes Wrong codes for removing an authenticator, new recovery codes or confirming one counted toward the account's waits (the re-review's third finding): a stolen session alone, without the password, could keep the owner's codes waiting for up to a day at a time, renewed without end, holding them out of signing in and of changing the password, the way to end that session, and nobody was mailed. Those codes now count per session, where the session is (the register's own, or a member's, which forwards the code): each try counted before its code is checked (one statement, so tries sent at once count each), a code accepted clearing the count, and the tenth wrong in a row ending the session (sessionEnded; the device says it was signed out). A try that checked no code (a refusal of something else) is taken back. The account's waits now count only codes after a right password, and the per-account ten tries an hour, which a session could fill as well, go. Migration (module, Learn's and Todo's servers, Learn's device schema): CREATE TABLE "session_code_failures" ("id" bigserial PRIMARY KEY, "sessionId" uuid NOT NULL, "authUserId" uuid NOT NULL, "failures" bigint NOT NULL, "updatedAt" timestamp NOT NULL) with a unique index on "sessionId": a new table, nothing touched. Its rows go with a code accepted, with the person, and hourly once their session is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-20 22:53:20 +02:00
20261020204618337-session-code-tries
20261020211224310-email-code-purpose