feat(auth): real SMS OTP via Kavenegar (replaces the mock 1234 code)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 50s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m11s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 34s

- OtpService: generates a 5-digit code, stores it (in-memory, 120s TTL, max 5
  tries, single-use), and sends it via Kavenegar verify/lookup
  (template "hokmotp", %token = code). Normalizes +98/98 → 09xxxxxxxxx.
- /api/auth/otp/request + /verify now use it. No SMS_API_KEY ⇒ dev mode
  (accepts a fixed code, returns devCode for local testing).
- Config: Sms section (appsettings) + Sms__* compose mapping + SMS_* in the
  ENV_FILE template.

Security: sanitized deploy/ENV_FILE.example back to placeholders (it had picked
up real secrets) and added /deploy/ENV_FILE.local to .gitignore as the real
master copy (never committed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-12 23:50:33 +03:30
parent 83d9c1c7d0
commit fdf4235fbd
6 changed files with 161 additions and 81 deletions
+4
View File
@@ -63,6 +63,10 @@ services:
Iab__BazaarRefreshToken: ${IAB_BAZAAR_REFRESH_TOKEN:-}
Iab__MyketAccessToken: ${IAB_MYKET_ACCESS_TOKEN:-}
Iab__AllowUnverified: ${IAB_ALLOW_UNVERIFIED:-false}
# SMS OTP (Kavenegar). Empty key ⇒ dev mode (no SMS, accepts the dev code).
Sms__Provider: ${SMS_PROVIDER:-kavenegar}
Sms__ApiKey: ${SMS_API_KEY:-}
Sms__Template: ${SMS_TEMPLATE:-hokmotp}
# Admin panel (marketing-site links editor) — shared-token auth.
Admin__Token: ${ADMIN_TOKEN:-}
# Where the admin-editable site-links JSON is persisted (mounted volume).