feat(crypto): SRP-6a, the register's half and the device's
ADR 0017's step 1. Generic over group and hash (SrpGroup); production takes RFC 5054's 3072-bit group with SHA-256. k = H(N | PAD(g)), u = H(PAD(A) | PAD(B)), K = H(PAD(S)), M1 = H(H(N) xor H(g) | H(I) | s | PAD(A) | PAD(B) | K), M2 = H(PAD(A) | M1 | K). A and B must lie in 1..N-1 and u must not be 0; a and b are 256 bits from Random.secure(); proofs are compared in constant time. x comes from the caller (halkyon_keys makes it); RFC 5054's own x is there for the vectors only. - The register's half in halkyon_base_server (base.dart: srpChallenge, srpVerify), the device's written by hand in halkyon_base_client (srp.dart: SrpClient, srpVerifier). Serverpod's generator cleans and writes only a client's lib/src/protocol/ (serverpod_cli 4.0.4's _getDirectoriesRequiringCleaning; a generate leaves srp/ untouched). - Tests: RFC 5054 Appendix B on both halves; the client against the register, succeeding and every refusal. - The module's tests depend on its client, and pub resolves every member's dev dependencies, so Learn's server image takes the module's client into its workspace too. - The format check covers the hand-written half. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
ae0d88818b
commit
bc499713b8
1 changed files with 1369 additions and 27 deletions
|
|
@ -25,7 +25,7 @@ Halkyon's apps and the packages they share, in one repository and one pub worksp
|
|||
- **Commits** are GPG-signed and carry a DCO `Signed-off-by` trailer (`git commit -s`; a local `prepare-commit-msg` hook adds it automatically), and **keep their type prefix** (`feat`, `fix`, `perf`, `refactor`, `docs`, `build`, `chore`, a `!` or a `BREAKING CHANGE:` line for what breaks): releases work out their versions from them (Learn's `AGENTS.md`, *Releases*).
|
||||
- **Servers are named in prose by the domain they serve** (learn.halkyon.eu's server, the halkyon.app server), which says what a reader needs; the SSH aliases and the CI runner's label keep the servers' own names (`sahaquiel-deploy`, `ramiel-fdroid`, `sahaquiel:host`).
|
||||
- **Pushes** pass the checks first, through a local `pre-push` hook (in a fresh clone: `ln -s ../../tool/pre-push .git/hooks/pre-push`): `tool/pre-push` first refuses a push to `main` that brings a commit not signed by a key in `deploy/allowed-signers` (`tool/check_signatures.sh`, the deploy's own rule), so it fails on the laptop rather than after CI, then runs `tool/check.dart`. CI runs the checks again, and a green `main` deploys learn.halkyon.eu (see *CI and deploys*), so an unsigned commit on `main` blocks every deploy after it.
|
||||
- **Lints**: LeanCode's strict set (`leancode_lint`), configured once in the root `analysis_options.yaml`, which also enables its analyzer plugin. Plugins can only be enabled at the root of a pub workspace and only reach packages whose options include that file: Learn's and Todo's servers and apps, Learn's curator and every shared package include it; the generated client packages keep their own. Every `// ignore:` gets a comment saying why (`document_ignores`). Each server package switches off the four rules for Dart v3.13's constructor syntax (`use_primary_constructors`, `use_declaring_parameters`, `empty_container_bodies`, `unnecessary_type_name_in_constructor`): Serverpod's code generator (checked with v4.0.3) can't parse that syntax in endpoint files yet.
|
||||
- **Lints**: LeanCode's strict set (`leancode_lint`), configured once in the root `analysis_options.yaml`, which also enables its analyzer plugin. Plugins can only be enabled at the root of a pub workspace and only reach packages whose options include that file: Learn's and Todo's servers and apps, Learn's curator and every shared package include it; the generated client packages keep their own, but for the module's, which includes it for its SRP half and leaves `lib/src/protocol/` out. Every `// ignore:` gets a comment saying why (`document_ignores`). Each server package switches off the four rules for Dart v3.13's constructor syntax (`use_primary_constructors`, `use_declaring_parameters`, `empty_container_bodies`, `unnecessary_type_name_in_constructor`): Serverpod's code generator (checked with v4.0.3) can't parse that syntax in endpoint files yet.
|
||||
|
||||
## Flutter and Serverpod
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ ALWAYS use the MCP server instead of the command line. Use the MCP server to:
|
|||
|
||||
The `serverpod` MCP tools come from `.mcp.json`: `serverpod mcp-server`, a bridge to the running `serverpod start` of one app's server, the one its `--server-dir` names (each app's `AGENTS.md` gives its own). They load when a session starts; if they are missing, the server wasn't running or the session predates `.mcp.json`. Like all agent configuration, `.mcp.json` is git-ignored. A session works with one app's server at a time; work on another app's server package with the CLI below, in a worktree if that app's `serverpod start` runs.
|
||||
|
||||
NEVER edit generated code. Each server's `lib/src/generated/` directory and its whole client package (`apps/<app>/halkyon_<app>_client`, `packages/halkyon_base_client`) are rewritten by the code generator. Change the `.spy.yaml` models, the endpoints, or the server's `lib/server.dart` instead.
|
||||
NEVER edit generated code. Each server's `lib/src/generated/` directory and its whole client package (`apps/<app>/halkyon_<app>_client`, `packages/halkyon_base_client`) are rewritten by the code generator, but for the module client's SRP half, written by hand (`lib/srp.dart`, `lib/src/srp/`, `test/`): the generator writes only a client's `lib/src/protocol/` (checked with v4.0.4). Change the `.spy.yaml` models, the endpoints, or the server's `lib/server.dart` instead.
|
||||
|
||||
Migrations are a narrow exception: the `migration.sql` of a generated migration MAY be edited by hand when the generated SQL would lose data — to add a data transformation, or to reach a destructive change through non-destructive steps. Never touch the other files in the migration directory, and keep the schema the SQL ends up with identical to `definition.sql` — new databases are created from that file and never run `migration.sql`. A module's tables are part of each server's migrations that includes it; moving a table into a module unchanged needs no SQL but the version rows (`create-migration --empty`, ADR 0014).
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue