Separate second-factor policy, enrolled destinations, challenge delivery, verification and one-use authorization proofs from signup/authentication. Auth creates sessions only after consuming a matching second-factor proof.
Approach
Reused the Sendico-derived verification issuance/consumption engine already retained at the pinned source revision. Implemented product/twofactor with shared Mongo wrappers, verified user preferences and a channel delivery interface. Signup email activation remains in auth/flow; notifications only deliver messages. Auth owns password/client validation and session creation through the service's atomic completion callback. Updated the shared Flutter adapter.
Acceptance criteria
Auth no longer generates, delivers or directly consumes OTP verification records.
The 2FA service binds challenges/proofs to customer, purpose and operation; enforces expiry, attempts, cooldowns and one-use consumption.
Channel selection uses persisted, verified user preferences; enrollment and preference changes require verification and unsupported channels fail closed.
Login consumes a matching proof before session creation; signup activation remains separate.
Sendico reuse and exclusions, contracts, configuration and recovery limitations are documented.
Required review, tests and lint pass; contribution committed/pushed and a PR opened.
Notes
Delivered in PR #41: #41, branch twofactor-40 against main. Follow-up to merged #38 / PR #39. Primary module: twofactor; secondary modules: auth, verification purpose definitions, notification templates and Flutter auth.
Source: S_I/sendico at 8bb20dcd622dd8eb92d289b6b34411e7eccab083. Reused local verification/store; coupled verification/session/private-messaging handlers were inspected but not copied. Details in docs/architecture/two-factor.md and backend/PROVENANCE.md.
Validation passed: make test (Go race tests and all frontend suites), make lint-backend, flutter analyze in frontend/packages/sxchnge_auth, and Dart format checks for all four changed Dart files. Mongo tests cover invalid attempts committed through outer transactions, callback rollback, concurrent completion, isolation, expiry, inactive accounts, proof replay, enrollment and preference invalidation. No live email or optional security scan was run.
Roll out backend and client together, load twofactor.code revision 1 and restart old pending logins. A failed session write leaves the code retryable; a lost response after commit still requires recovery. Email is the installed channel. Settings UI wiring, SMS/push/TOTP/passkeys, recovery/removal and payout integration are outside this change. This is a domain service in the product executable, not a separate deployment. The PR remains open; no merge performed.
### Goal
Separate second-factor policy, enrolled destinations, challenge delivery, verification and one-use authorization proofs from signup/authentication. Auth creates sessions only after consuming a matching second-factor proof.
### Approach
Reused the Sendico-derived verification issuance/consumption engine already retained at the pinned source revision. Implemented product/twofactor with shared Mongo wrappers, verified user preferences and a channel delivery interface. Signup email activation remains in auth/flow; notifications only deliver messages. Auth owns password/client validation and session creation through the service's atomic completion callback. Updated the shared Flutter adapter.
### Acceptance criteria
- [x] Auth no longer generates, delivers or directly consumes OTP verification records.
- [x] The 2FA service binds challenges/proofs to customer, purpose and operation; enforces expiry, attempts, cooldowns and one-use consumption.
- [x] Channel selection uses persisted, verified user preferences; enrollment and preference changes require verification and unsupported channels fail closed.
- [x] Login consumes a matching proof before session creation; signup activation remains separate.
- [x] Sendico reuse and exclusions, contracts, configuration and recovery limitations are documented.
- [x] Required review, tests and lint pass; contribution committed/pushed and a PR opened.
### Notes
Delivered in PR #41: https://git.sendico.io/tech/sxchnge/pulls/41, branch twofactor-40 against main. Follow-up to merged #38 / PR #39. Primary module: twofactor; secondary modules: auth, verification purpose definitions, notification templates and Flutter auth.
Source: S_I/sendico at 8bb20dcd622dd8eb92d289b6b34411e7eccab083. Reused local verification/store; coupled verification/session/private-messaging handlers were inspected but not copied. Details in docs/architecture/two-factor.md and backend/PROVENANCE.md.
Validation passed: make test (Go race tests and all frontend suites), make lint-backend, flutter analyze in frontend/packages/sxchnge_auth, and Dart format checks for all four changed Dart files. Mongo tests cover invalid attempts committed through outer transactions, callback rollback, concurrent completion, isolation, expiry, inactive accounts, proof replay, enrollment and preference invalidation. No live email or optional security scan was run.
Roll out backend and client together, load twofactor.code revision 1 and restart old pending logins. A failed session write leaves the code retryable; a lost response after commit still requires recovery. Email is the installed channel. Settings UI wiring, SMS/push/TOTP/passkeys, recovery/removal and payout integration are outside this change. This is a domain service in the product executable, not a separate deployment. The PR remains open; no merge performed.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Separate second-factor policy, enrolled destinations, challenge delivery, verification and one-use authorization proofs from signup/authentication. Auth creates sessions only after consuming a matching second-factor proof.
Approach
Reused the Sendico-derived verification issuance/consumption engine already retained at the pinned source revision. Implemented product/twofactor with shared Mongo wrappers, verified user preferences and a channel delivery interface. Signup email activation remains in auth/flow; notifications only deliver messages. Auth owns password/client validation and session creation through the service's atomic completion callback. Updated the shared Flutter adapter.
Acceptance criteria
Notes
Delivered in PR #41: #41, branch twofactor-40 against main. Follow-up to merged #38 / PR #39. Primary module: twofactor; secondary modules: auth, verification purpose definitions, notification templates and Flutter auth.
Source: S_I/sendico at 8bb20dcd622dd8eb92d289b6b34411e7eccab083. Reused local verification/store; coupled verification/session/private-messaging handlers were inspected but not copied. Details in docs/architecture/two-factor.md and backend/PROVENANCE.md.
Validation passed: make test (Go race tests and all frontend suites), make lint-backend, flutter analyze in frontend/packages/sxchnge_auth, and Dart format checks for all four changed Dart files. Mongo tests cover invalid attempts committed through outer transactions, callback rollback, concurrent completion, isolation, expiry, inactive accounts, proof replay, enrollment and preference invalidation. No live email or optional security scan was run.
Roll out backend and client together, load twofactor.code revision 1 and restart old pending logins. A failed session write leaves the code retryable; a lost response after commit still requires recovery. Email is the installed channel. Settings UI wiring, SMS/push/TOTP/passkeys, recovery/removal and payout integration are outside this change. This is a domain service in the product executable, not a separate deployment. The PR remains open; no merge performed.
twofactor-40to twofactor-40