feat(auth): mobile-only register/login with OTP verification

- Register and login by mobile number; email is now an optional
  contact field only (never used to authenticate)
- After registration, the phone is verified via a 6-digit SMS code
- Login supports both password and one-time-code (OTP) methods
- Phone OTP delivered via Kavenegar (verify/lookup); API key in env
- Account page: edit name/optional email, change password, and
  change mobile number with OTP re-verification
- Codes are hashed, expire in 5m, capped at 5 attempts, rate-limited
- Seed gives the admin a verified phone so mobile login still works

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
keyhan
2026-06-16 16:40:08 +03:30
parent ce6813db99
commit 37c103fa20
31 changed files with 1756 additions and 143 deletions
+10
View File
@@ -20,6 +20,16 @@ JWT_REFRESH_EXPIRES_IN=7d
REDIS_HOST=localhost
REDIS_PORT=6379
# OTP SMS — Kavenegar (verify/lookup template API)
# Create an approved OTP template in the Kavenegar panel and put its name here.
# The template must contain a single %token placeholder for the code.
KAVENEGAR_API_KEY=
KAVENEGAR_OTP_TEMPLATE=
# Without these, OTP codes are logged to the API console in development only.
# Seed admin mobile (login is mobile-only) — used by `npm run seed`.
ADMIN_PHONE=09120000000
# In-cluster Docker Registry (Kaniko push + app image pull — same URL)
REGISTRY_URL=registry.cloudhost-builds.svc.cluster.local:5000
# REGISTRY_PULL_URL=registry.cloudhost-builds.svc.cluster.local:5000