تخطي إلى المحتوى الرئيسي

ADR 0007: Hybrid phone OTP login (Twilio SMS + WhatsApp)

Status

Accepted — 2026-06-02

Context

Parents and field staff in Iraq often prefer mobile login without memorizing passwords. The product already stores users.phone and uses Express session cookies. We need passwordless OTP while keeping password login for operators who set credentials explicitly.

Decision

  1. Hybrid rule: if users.password_hash is set → login with email or normalized phone + password (no OTP). If no password → phone required; login via 6-digit OTP.
  2. Channels: Twilio SMS (plain body) and optional WhatsApp (Meta-approved Authentication template via Twilio Content API).
  3. API: POST /api/auth/login/method, /api/auth/otp/request, /api/auth/otp/verify; extend /api/auth/login with identifier.
  4. Storage: users.phone_normalized (unique), auth_otp_challenges (hashed code, TTL, attempt limit).
  5. Secrets: GitHub PRODUCTION_TWILIO_* → server .env via deploy/patch-env-github-secrets.sh.

Consequences

  • Twilio + Meta Business setup required for production WhatsApp; SMS needs Iraq geo permissions.
  • Operators must assign phone for OTP-only accounts; duplicate phones blocked by unique index.
  • Future Keycloak migration should preserve the same client contract (identifier + method discovery).

References

  • lib/phoneNormalize.ts, lib/smsOtp.ts, server.ts
  • .github/DEPLOY-SECRETS.md (Twilio OTP section)