mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 07:21:32 +02:00
The prior fixes closed the common cases with pre-checks; this closes the residual races by consuming the single-use gate token(s) AND creating the user AND persisting keys in ONE transaction, so a failure never burns a token without an account. - New Database::create_user_consuming_gates: claims the invite + consumes the payment invoice + inserts the user + upserts keys inside a tx; rolls the whole thing back on a username collision (mapped to 409) or a raced/already-spent token. - New plan_gate_consume: resolves which tokens to spend WITHOUT consuming (the payment settled-check stays non-consuming), so `all`-mode verifies the payment is settled before anything is spent, then both tokens are consumed atomically at creation. - extension_register + nostr_register route NEW users through the atomic path (returning users keep the ordinary backfill path); the npub F2 fail-closed check runs before the tx. Removed the now-dead enforce_method_gates / enforce_invite / enforce_payment. - tests/registration_atomicity.rs proves the rollback: a username collision keeps the invite; an already-spent payment keeps the invite. Validated against Postgres: full suite 286 passed / 0 failed.