feat(identity): sms login implementation#2
Merged
Conversation
…/73--mobile-sms-login
…/73--mobile-sms-login
zaxovaiko
reviewed
Jul 14, 2026
Contributor
There was a problem hiding this comment.
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.
zaxovaiko
reviewed
Jul 14, 2026
zaxovaiko
reviewed
Jul 14, 2026
zaxovaiko
reviewed
Jul 14, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
s and refactor
zaxovaiko
previously approved these changes
Jul 15, 2026
added 2 commits
July 15, 2026 15:11
…/73--mobile-sms-login
…ycom/openora into feat/73--mobile-sms-login
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
New files:
stdout)
(anti-enumeration, 60s cooldown, SHA-256 hashed code, 5-min TTL) + verify (5-attempt cancellation,
TOTP bypass, direct session insert, RG block check)
scenarios
Modified files:
smsOtpSession table + migration generated
PhoneLoginVerifyInputSchema added; UserSchema extended with phone fields; 3 new domain events
MockSmsAdapter as default
event when max attempts exhausted)
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 verifyis green (typecheck + lint + boundaries + module-shape + tests)pnpm verify:driftis green (catalog / OpenAPI not stale) - runpnpm regenif not/schemasubpath (no direct module imports)tenantIdand are RLS-covered (pnpm regenrunsgen:rls)