Skip to content

feat(identity): sms login implementation#2

Draft
agniev-a-hub wants to merge 2 commits into
devfrom
feat/73--mobile-sms-login
Draft

feat(identity): sms login implementation#2
agniev-a-hub wants to merge 2 commits into
devfrom
feat/73--mobile-sms-login

Conversation

@agniev-a-hub

Copy link
Copy Markdown
Collaborator

Summary

Changes

New files:

  • packages/core/src/contracts/adapters/sms.ts — SmsAdapter port + SMS_ADAPTER token
  • packages/core/src/pam/identity/adapters/mock/mock-sms-adapter.ts — dev/stage mock (logs OTP to
    stdout)
  • packages/core/src/pam/identity/service/phone-login.service.ts — full OTP flow: request
    (anti-enumeration, 60s cooldown, SHA-256 hashed code, 5-min TTL) + verify (5-attempt cancellation,
    TOTP bypass, direct session insert, RG block check)
  • packages/core/src/pam/identity/tests/phone-login.service.test.ts — 11 unit tests covering all AC
    scenarios

Modified files:

  • Schema: added phoneNumber, phoneVerified, phoneVerifiedAt, lockoutCount, lastLockoutAt to user; new
    smsOtpSession table + migration generated
  • Contracts: E164PhoneSchema, PhoneLoginRequestInputSchema, PhoneLoginRequestOutputSchema,
    PhoneLoginVerifyInputSchema added; UserSchema extended with phone fields; 3 new domain events
  • Identity contract/router/plugin: 2 new routes wired end-to-end; SMS_ADAPTER bound with
    MockSmsAdapter as default
  • Audit plugin: subscribed to identity.user.phone_login and identity.phone_otp.cancelled (the security
    event when max attempts exhausted)
  • Identity service: progressive lockout tiers (1 min / 5 min / 15 min within 24h rolling window);
    attemptsRemaining in failed-login event

Acceptance criteria

[ ] - Player can select "Log in with phone number" as an alternative on the login page
[ ] - Player enters their registered phone number and receives an SMS OTP
[ ] - OTP is valid for 5 minutes and single-use
[ ] - Valid OTP creates a session identical to email login
[ ] - Invalid/expired OTP shows an error - player can resend after 60 seconds
[ ] - Previous OTP is invalidated when a new one is requested
[ ] - After 5 failed OTP attempts, login attempt is cancelled and player is returned to login page
[ ] - Login method (phone) is recorded in the audit log
[ ] - "Remember me" option available same as email login

Phone number must be verified on the account before this method is available

TOTP 2FA is not applied on top of phone login

Checklist

  • pnpm verify is green (typecheck + lint + boundaries + module-shape + tests)
  • pnpm verify:drift is green (catalog / OpenAPI not stale) - run pnpm regen if not
  • New cross-module talk goes through events / command ports / contracts / the /schema subpath (no direct module imports)
  • New data tables carry tenantId and are RLS-covered (pnpm regen runs gen:rls)
  • No secrets, real player data, or internal/customer names added
  • Docs / AGENTS.md updated if behavior or extension points changed

@agniev-a-hub agniev-a-hub self-assigned this Jul 9, 2026
@agniev-a-hub agniev-a-hub requested a review from zaxovaiko as a code owner July 9, 2026 17:49
@agniev-a-hub agniev-a-hub marked this pull request as draft July 9, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant