Skip to content

feat: Email-Only User Registration #260

@islandbitcoin

Description

@islandbitcoin

Overview

Implement email-only authentication flow for new user registration, allowing users to sign up with just an email address (no phone required).

PR: #212
Branch: feat/email-registration
Status: Ready for review

Feature Description

User Flow

  1. Client calls newUserEmailRegistrationInitiate with email address
  2. Backend creates Kratos identity, sends OTP via recovery flow
  3. Client calls newUserEmailRegistrationValidate with flowId + code
  4. Backend validates code, creates account if new, returns auth token

Key Components

  • GraphQL Mutations:
    • newUserEmailRegistrationInitiate - Start email registration
    • newUserEmailRegistrationValidate - Complete with OTP code
  • Kratos Integration: New schema email_no_password_v0
  • Account Upgrade: Device accounts can upgrade to email accounts
  • Schema Upgrade Paths:
    • Device → Email (replaces traits)
    • Phone → Phone+Email (adds email trait)

Files Changed (43 files, +855/-216)

  • src/graphql/public/root/mutation/new-user-email-registration-*.ts
  • src/app/authentication/email.ts
  • src/services/kratos/auth-email-no-password.ts
  • src/app/accounts/create-account.ts
  • src/app/accounts/upgrade-device-account.ts
  • src/domain/authentication/registration-payload-validator.ts
  • dev/ory/kratos.yml

Known Issues / Follow-up Work

🔴 HIGH PRIORITY (Security)

  • Account Enumeration Vulnerability

    • Location: src/services/kratos/auth-email-no-password.ts lines 73-78
    • Issue: createIdentityForEmailRegistration() reveals whether email is already registered
    • Mitigation: Return consistent response regardless of email existence
  • Missing TOTP Flow Completion

    • Location: newUserEmailRegistrationValidate returns totpRequired but no follow-up
    • Issue: If TOTP is required, no mutation exists to complete the flow
    • Action: Document expected client behavior or implement TOTP verification step
  • Race Condition in Account Creation

    • Location: new-user-email-registration-validate.ts lines 63-78
    • Issue: Concurrent code validations could create duplicate accounts
    • Mitigation: Add distributed lock or database constraint

🟡 MEDIUM PRIORITY (Tech Debt)

  • Inconsistent Error Handling - "dead branch" error message (line 162-163)
  • Hardcoded Schema ID - Should use SchemaIdType.EmailNoPasswordV0 enum
  • Known Account Enumeration TODO - FIXME at lines 415-419 not addressed
  • Missing Transaction Handling - Multi-step operations in upgrade-device-account.ts

🟢 LOW PRIORITY

  • Unused import pattern in validate mutation
  • Undocumented GraphQL complexity value (120)
  • Direct Kratos DB access (documented workaround for issue #3163)

Testing Status

  • TypeScript compiles (yarn tsc --noEmit - 0 errors)
  • Integration tests (pre-existing failures unrelated to this PR)

Dependencies

  • Ory Kratos configuration update required
  • No external feature dependencies

Related Issues/PRs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions