Skip to content

feat(identity): sms login implementation#2

Merged
agniev-a-hub merged 20 commits into
devfrom
feat/73--mobile-sms-login
Jul 15, 2026
Merged

feat(identity): sms login implementation#2
agniev-a-hub merged 20 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
@agniev-a-hub agniev-a-hub marked this pull request as ready for review July 13, 2026 13:18
Comment thread .husky/pre-commit

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements SMS-based OTP login as an alternative authentication method in the identity module, including new schema/migrations, contract routes, service logic, auditing, and demo seed support.

Changes:

  • Added SMS adapter contract + default mock implementation, wired via identity plugin.
  • Introduced phone OTP request/verify flow with rate limits, cooldown, OTP session storage, and RG-block enforcement.
  • Extended lockout logic with progressive tiers and added related schema fields + migrations.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/testing/src/seed-demo-data.ts Seeds demo users with E.164 phone numbers + verified flags.
packages/core/src/pam/identity/service/rg-guard.service.ts Extracts RG block predicate into shared helper.
packages/core/src/pam/identity/service/phone-login.service.ts Implements OTP request/verify + direct session minting.
packages/core/src/pam/identity/service/identity.service.ts Adds progressive lockout tiers + emits attemptsRemaining.
packages/core/src/pam/identity/schema/index.ts Adds phone fields + lockout tier fields + sms_otp_session table.
packages/core/src/pam/identity/router/index.ts Wires new phone login routes and forwards IP/UA.
packages/core/src/pam/identity/plugin.ts Binds SMS_ADAPTER and constructs PhoneLoginService.
packages/core/src/pam/identity/drizzle/migrations/meta/0002_snapshot.json Drizzle snapshot for latest schema state.
packages/core/src/pam/identity/drizzle/migrations/meta/0001_snapshot.json Drizzle snapshot for initial migration state.
packages/core/src/pam/identity/drizzle/migrations/meta/_journal.json Records new migration entries.
packages/core/src/pam/identity/drizzle/migrations/0002_outstanding_patriot.sql Adds UNIQUE constraint for sms_otp_session.user_id.
packages/core/src/pam/identity/drizzle/migrations/0001_rainy_peter_quill.sql Creates sms_otp_session + adds new user columns.
packages/core/src/pam/identity/contract/index.ts Adds /identity/phone-login/request and /verify routes.
packages/core/src/pam/identity/AGENTS.md Documents progressive lockout + phone login behavior/events.
packages/core/src/pam/identity/adapters/mock/mock-sms-adapter.ts Default SMS adapter that logs OTP to stdout.
packages/core/src/pam/identity/tests/phone-login.service.test.ts Unit tests for OTP request/verify behaviors.
packages/core/src/contracts/schemas/identity.ts Adds phone fields + E164 schema + phone login IO schemas/types.
packages/core/src/contracts/schemas/events.ts Adds phone login + OTP events and attemptsRemaining field.
packages/core/src/contracts/adapters/sms.ts Introduces SmsAdapter port + SMS_ADAPTER token.
packages/core/src/contracts/adapters/index.ts Exports SmsAdapter + SMS_ADAPTER.
packages/core/src/audit/plugin.ts Audits phone_login and phone_otp.cancelled events.
docs/catalog.json Updates catalog with new table/routes/events/adapter.
.husky/pre-commit Switches pre-commit from lint:fix to lint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/core/src/pam/identity/service/phone-login.service.ts
Comment thread packages/core/src/pam/identity/schema/index.ts Outdated
Comment thread packages/core/src/pam/identity/schema/index.ts Outdated
Comment thread packages/core/src/pam/identity/service/identity.service.ts
Comment thread packages/core/src/contracts/schemas/identity.ts Outdated
Comment thread packages/core/src/pam/identity/service/phone-login.service.ts
Comment thread packages/core/src/pam/identity/service/phone-login.service.ts Outdated
@zaxovaiko zaxovaiko self-requested a review July 15, 2026 12:36
zaxovaiko
zaxovaiko previously approved these changes Jul 15, 2026

@zaxovaiko zaxovaiko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@agniev-a-hub agniev-a-hub merged commit 4b9f0a9 into dev Jul 15, 2026
3 checks passed
@agniev-a-hub agniev-a-hub deleted the feat/73--mobile-sms-login branch July 15, 2026 20:49
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.

3 participants