feat(auth): real SMS OTP via Kavenegar (replaces the mock 1234 code)
- 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:
+31
-75
@@ -1,93 +1,49 @@
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
# Barg-e Vasat — ENV_FILE
|
||||
# Paste the contents of this file (filled in) into the Gitea repo secret:
|
||||
# https://git.soroushasadi.com/soroushdes/HokmPlay/settings/secrets → ENV_FILE
|
||||
# The deploy job writes it verbatim to `.env`, which docker compose reads.
|
||||
#
|
||||
# NOTE: NEXT_PUBLIC_SERVER_URL is baked into the web bundle at BUILD time —
|
||||
# changing it requires a new CI run (push a commit) to take effect.
|
||||
# Barg-e Vasat — ENV_FILE TEMPLATE (placeholders only — NO real secrets here)
|
||||
# Copy to deploy/ENV_FILE.local (git-ignored), fill real values, and paste the
|
||||
# WHOLE thing into the Gitea repo secret ENV_FILE. Saving the secret REPLACES
|
||||
# the entire file — always paste the complete contents.
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# Host ports (1500–1600 range so the stack coexists with manual dev on 3000/5005)
|
||||
# Ports
|
||||
WEB_PORT=1500
|
||||
API_PORT=1505
|
||||
DB_PORT=1510
|
||||
SITE_PORT=1520
|
||||
|
||||
# Database (postgres container)
|
||||
POSTGRES_PASSWORD=change-me-strong-password
|
||||
# Database — MUST match the existing postgres volume's password
|
||||
POSTGRES_PASSWORD=<strong-password>
|
||||
|
||||
# JWT — generate with: openssl rand -hex 32
|
||||
JWT_KEY=CHANGE-ME-to-a-32+char-random-secret
|
||||
JWT_KEY=<32+char-random-secret>
|
||||
JWT_ISSUER=hokm
|
||||
JWT_AUDIENCE=hokm-clients
|
||||
|
||||
# Browser-facing API origin (host-mapped api port).
|
||||
# If the browser is NOT on the deploy host, use the host LAN IP instead of
|
||||
# localhost, e.g. http://172.28.144.1:1505 (localhost can be VPN-hijacked).
|
||||
NEXT_PUBLIC_SERVER_URL=http://localhost:1505
|
||||
# URLs / CORS
|
||||
NEXT_PUBLIC_SERVER_URL=https://api.bargevasat.ir
|
||||
NEXT_PUBLIC_APP_URL=https://app.bargevasat.ir
|
||||
NEXT_PUBLIC_SITE_URL=https://bargevasat.ir
|
||||
CORS_ORIGINS=https://bargevasat.ir,https://www.bargevasat.ir,https://app.bargevasat.ir
|
||||
|
||||
# Origins allowed by the API's CORS (comma-separated). Must include the web URL.
|
||||
CORS_ORIGINS=http://localhost:1500
|
||||
# ZarinPal
|
||||
ZARINPAL_MERCHANT_ID=<your-merchant-id>
|
||||
ZARINPAL_SANDBOX=false
|
||||
ZARINPAL_CALLBACK_URL=https://api.bargevasat.ir/api/coins/pay/callback
|
||||
ZARINPAL_CLIENT_RETURN_URL=https://app.bargevasat.ir
|
||||
|
||||
# Package mirrors used during Docker builds. Default to the plain-HTTP Nexus
|
||||
# (no SSL) because the HTTPS mirror serves a partial cert chain that fresh
|
||||
# container trust stores reject. Override only if your Nexus moves.
|
||||
# NUGET_INDEX=http://171.22.25.73:8081/repository/nuget-group/index.json
|
||||
# NPM_REGISTRY=http://171.22.25.73:8081/repository/npm-group/
|
||||
# Admin panel token (openssl rand -hex 24)
|
||||
ADMIN_TOKEN=<admin-token>
|
||||
|
||||
# ZarinPal (sandbox for now — switch in admin/panel later)
|
||||
ZARINPAL_MERCHANT_ID=299685fb-cadf-4dfc-98e2-d4af5d81528d
|
||||
ZARINPAL_SANDBOX=true
|
||||
ZARINPAL_CALLBACK_URL=http://localhost:1505/api/coins/pay/callback
|
||||
ZARINPAL_CLIENT_RETURN_URL=http://localhost:1500
|
||||
|
||||
# Store in-app billing (Cafe Bazaar / Myket) — fill from the developer panels.
|
||||
# SKU == coin-pack id (p1/p2/…). Coins are credited only after the purchase
|
||||
# token verifies server-to-server.
|
||||
# In-app billing (Cafe Bazaar / Myket) — fill from the developer panels.
|
||||
IAB_PACKAGE_NAME=com.bargevasat.app
|
||||
# Cafe Bazaar (pardakht dev API): create an OAuth client, do the one-time consent
|
||||
# to obtain a refresh_token. https://pardakht.cafebazaar.ir/
|
||||
IAB_BAZAAR_CLIENT_ID=
|
||||
IAB_BAZAAR_CLIENT_SECRET=
|
||||
IAB_BAZAAR_REFRESH_TOKEN=
|
||||
# Myket developer panel → API access token.
|
||||
IAB_MYKET_ACCESS_TOKEN=
|
||||
# DEV ONLY: credit purchases WITHOUT verifying (set true to test before you have
|
||||
# store creds). NEVER true in production.
|
||||
IAB_BAZAAR_CLIENT_ID=<bazaar-client-id>
|
||||
IAB_BAZAAR_CLIENT_SECRET=<bazaar-client-secret>
|
||||
IAB_BAZAAR_REFRESH_TOKEN=<bazaar-refresh-token>
|
||||
IAB_MYKET_ACCESS_TOKEN=<myket-access-token>
|
||||
IAB_ALLOW_UNVERIFIED=false
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
# Marketing site (bargevasat.ir) + subdomain split
|
||||
# Game → app.bargevasat.ir ; marketing site → bargevasat.ir
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
SITE_PORT=1520
|
||||
# Browser-facing URLs baked into the marketing site at BUILD time:
|
||||
NEXT_PUBLIC_APP_URL=https://app.bargevasat.ir # the game (CTA buttons)
|
||||
NEXT_PUBLIC_SITE_URL=https://bargevasat.ir # canonical/SEO base
|
||||
# (NEXT_PUBLIC_SERVER_URL above is reused by the site to read store links.)
|
||||
|
||||
# Admin panel (edit Bazaar/Myket/iOS links at /admin). Shared-token auth.
|
||||
# Generate with: openssl rand -hex 24
|
||||
ADMIN_TOKEN=7ec8b2b242695de7d2692185acb4f1d345a589866ddd2de6
|
||||
|
||||
# With the split, set these too (game bundle + CORS for all 3 hosts):
|
||||
# NEXT_PUBLIC_SERVER_URL=https://api.bargevasat.ir
|
||||
# CORS_ORIGINS=https://bargevasat.ir,https://www.bargevasat.ir,https://app.bargevasat.ir
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
# PRODUCTION (bargevasat.ir) — use these values instead of the local ones above,
|
||||
# and deploy with the Caddy overlay (see PRODUCTION.md). DNS: bargevasat.ir,
|
||||
# www, api → server IP; open 80/443. Caddy fronts TLS, so host ports are internal.
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
# WEB_PORT=1500
|
||||
# API_PORT=1505
|
||||
# DB_PORT=1510
|
||||
# POSTGRES_PASSWORD=<strong>
|
||||
# JWT_KEY=<openssl rand -hex 32>
|
||||
# NEXT_PUBLIC_SERVER_URL=https://api.bargevasat.ir # baked at web build time
|
||||
# CORS_ORIGINS=https://bargevasat.ir,https://www.bargevasat.ir
|
||||
# ZARINPAL_MERCHANT_ID=<live-merchant-id>
|
||||
# ZARINPAL_SANDBOX=false
|
||||
# ZARINPAL_CALLBACK_URL=https://api.bargevasat.ir/api/coins/pay/callback
|
||||
# ZARINPAL_CLIENT_RETURN_URL=https://bargevasat.ir
|
||||
# IAB_ALLOW_UNVERIFIED=false # fill the IAB_* creds from the Bazaar panel post-publish
|
||||
# SMS OTP (Kavenegar). Template "hokmotp" has a %token placeholder we fill with
|
||||
# the code. Leave SMS_API_KEY empty for dev mode (no SMS sent, code = 1234).
|
||||
SMS_PROVIDER=kavenegar
|
||||
SMS_API_KEY=<kavenegar-api-key>
|
||||
SMS_TEMPLATE=hokmotp
|
||||
|
||||
Reference in New Issue
Block a user