Files
tehran_taj/apps/api/.env.example
T
s.esmaeiliandClaude Opus 5.5 9d3b5388ba fix(security): a production server refuses to start until its keys, allowed origins and test login are right (REL-01, REL-03, SEC-04)
With NODE_ENV=production (always, in the Docker image) the API lists
every problem at once and does not start while any of these holds:
- OTP_MASTER_CODE is set: the fixed test login signs in any customer. A
  test server built from the production image must say so with
  TEST_SERVER_ALLOW_MASTER_CODE=yes.
- JWT_CUSTOMER_SECRET is missing, equal to JWT_SECRET, or under 32
  characters.
- JWT_SECRET is missing, the published dev key, or under 32 characters.
- CORS_ORIGINS is empty, `*`, or not full origins. It no longer falls
  back to allow-all.

Checked live: a misconfigured start lists all four problems; a correct
one starts, answers the allowed origin, and blocks any other.
docs/SERVER-SETUP-CHECKLIST.md is the operator's list. DELIVERY.md,
docker-compose.yml and .env.example are updated to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 17:00:17 +03:30

69 lines
3.2 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; blank sends this machine's first external IPv4.
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=