Files
tehran_taj/apps/api/.env.example
T
s.esmaeiliandClaude Opus 5.5 7f851676b5 fix(sms): inside Docker, send the server's public IP as the relay host, not the container's
Messages went out locally but not from the server. The relay gateway
identifies the sending server by `host`, and the owner's ruling (D26)
is that this is the server's IP. With SMS_RELAY_HOST unset, the driver
sent the machine's first external IPv4. On the bare PHP server that was
the real IP; inside the API container it is the container's (172.x).
Reproduced: a container on this machine reports 172.17.0.3.

- relay.driver: when SMS_RELAY_HOST is unset and the machine address is
  private (RFC 1918, CGNAT, link-local), the public IPv4 is looked up
  once (ipify, ifconfig.me, icanhazip in turn) and cached. If every
  lookup fails, it falls back to the old value. SMS_RELAY_HOST still wins.
- SmsService logs the host it will send at boot, and warns when it is
  still private, so a wrong value is visible instead of silent.
- Removed a debug console.log that wrote every recipient's mobile to the
  server log.
- .env.example and SERVER-SETUP-CHECKLIST: SMS_RELAY_HOST = this
  server's public IP.

Tests: relay-host.spec (5). All 254 API tests pass.

اپ: پیامک کد ورود دوباره به‌درستی ارسال می‌شود.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:58:13 +03:30

72 lines
3.4 KiB
Bash

DATABASE_URL="postgresql://postgres:postgres@localhost:5432/gold_bank?schema=public"
# Must match API_PORT in the repo-root .env (source of truth for all dev
# ports). NestJS/Prisma only load .env from this app's own directory, so this
# value is kept in sync manually rather than read from the root file.
PORT=3000
# Customer app sessions (security hotfix stage 2).
# Separate from JWT_SECRET so an admin token can never validate as a customer
# token. Falls back to JWT_SECRET, then to a dev-only string, when unset —
# development only: in production it is REQUIRED, at least 32 characters and
# different from JWT_SECRET, or the API refuses to start (REL-03).
JWT_CUSTOMER_SECRET=
# Customer token lifetime. The reference issued a token that never expired.
JWT_CUSTOMER_EXPIRES_IN=30d
# ---------------------------------------------------------------------------
# SMS gateway — Trez panel (port of henza_server/app/Models/Sms.php:57-82)
# ---------------------------------------------------------------------------
# Trez: NEVER commit real values. The reference hardcoded its live production
# credentials in the source (SEC-12); those are treated as compromised and are
# not reused. Set the real values in .env, which is gitignored.
#
# The server always starts (D20). A misconfigured provider only warns, and
# outside production OTP codes are then logged locally instead.
# With nothing set, the relay driver SENDS REAL SMS (D26) — set
# SMS_PROVIDER=none on a development machine that must not.
# "relay" (default, D26), "trez", or "none" to disable sending entirely.
SMS_PROVIDER=relay
# relay — all optional; URL and secret have built-in defaults.
SMS_RELAY_URL=
SMS_RELAY_SECRET=
# The "host" field: this server's public IP (owner ruling D26). Blank sends the
# machine's first external IPv4 — and when that is a private address (inside
# Docker it is the container's 172.x), the public IP is looked up once at boot.
# Setting it explicitly on the server is the surest; the boot log shows the value.
SMS_RELAY_HOST=
# "kave" (default, Kavenegar) or "default" to let the gateway pick the line.
SMS_RELAY_PLATFORM=
# trez — only used with SMS_PROVIDER=trez.
# Defaults to the reference endpoint when unset; override for staging.
SMS_TREZ_URL=
# Required for trez:
SMS_TREZ_USERNAME=
SMS_TREZ_PASSWORD=
# The panel's sender line — the `PhoneNumber` form field.
SMS_TREZ_SENDER_LINE=
# Comma-separated admin numbers for order/document notifications. The reference
# hardcoded six mobile numbers across its controllers (STUB-05); empty means
# no admin notifications are sent.
SMS_ADMIN_RECIPIENTS=
# Accounting integration (D27) — configured in the admin panel; these two only
# protect the stored token and control the background worker.
ACCOUNTING_SECRET_KEY=
# "off" keeps this instance out of the background sync.
ACCOUNTING_WORKER=
# SEC-04 — browser origins allowed to call the API, comma-separated, exact
# (e.g. https://adm.example.ir,https://app.example.ir). Blank = any origin,
# development only. In production (NODE_ENV=production) the API refuses to
# start until CORS_ORIGINS lists full origins and JWT_SECRET is a random value
# of at least 32 characters (SEC-04). See docs/SERVER-SETUP-CHECKLIST.md.
CORS_ORIGINS=
# SEC-05 — the seed runs once on a fresh database at boot. In production it
# creates roles and permissions only; set "true" to force the demo data
# (sample customers, orders, debt and known-password accounts). Never in a
# real deployment.
SEED_DEMO_DATA=