Files
tehran_taj/.env.example
s.esmaeiliandCursor 6592e88a2c Fix admin IAM redirect and separate pending wholesale lists.
Keep admin browser bootstrap from falling back to the customer app URL, and exclude activated customers from the pending-verification list so it no longer mirrors the main omde grid.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-25 22:44:48 +03:30

177 lines
8.6 KiB
Bash

# Database configuration
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=goldbank
# Host port for PostgreSQL. Each copy of this stack on the same machine
# must use a different port (the apps talk to hostname "db", not this port).
EXTERNAL_DB_PORT=5432
# Prisma connection string (inside Docker network use hostname "db")
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
# ---------------------------------------------------------------------------
# Dev server ports — SINGLE SOURCE OF TRUTH for this monorepo.
# Every app's dev script/config reads its port from here. Do not hardcode a
# port anywhere else. strictPort is enabled everywhere: if a port below is
# already taken, the dev server fails with a clear error instead of silently
# picking another port.
# ---------------------------------------------------------------------------
API_PORT=3000
ADMIN_PANEL_PORT=5180
USER_APP_PORT=5181
USER_APP_V2_PORT=5182
# API Configuration (kept for any tooling that still reads bare PORT)
PORT=3000
# ---------------------------------------------------------------------------
# Authentication
# ---------------------------------------------------------------------------
# Admin JWT signing secret. REQUIRED in any real deployment — without it the
# API falls back to a well-known development string.
JWT_SECRET=
# Admin token lifetime (default 12h).
JWT_EXPIRES_IN=
# Customer JWT signing secret. Deliberately SEPARATE from JWT_SECRET so an
# admin token can never validate as a customer token (T1).
JWT_CUSTOMER_SECRET=
# Customer token lifetime (default 30d).
JWT_CUSTOMER_EXPIRES_IN=
# ---------------------------------------------------------------------------
# Accounting software integration (Tahesab / Zarrin, D27). Everything else —
# which software, address, token, mappings — is set in the admin panel
# («پیکر بندی ← اتصال حسابداری»), and the integration is off until then.
# ---------------------------------------------------------------------------
# Encrypts the accounting token at rest. Set a long random value. Blank falls
# back to a key derived from JWT_SECRET (with a boot warning); changing that
# key later means re-entering the token in the admin panel.
ACCOUNTING_SECRET_KEY=
# "off" keeps this API instance out of the background sync (only needed when
# several instances run and you want exactly one doing it; a lease already
# stops two from running the same job).
ACCOUNTING_WORKER=
# ---------------------------------------------------------------------------
# Central IAM — delegated admin login (docs/iam-sso.md)
# ---------------------------------------------------------------------------
# OFF by default. When off, nothing changes: admin login stays a local bcrypt
# check and no request ever leaves this server.
#
# When on, the admin's phone + password are verified against the central
# identity service instead. There is NO UI change: no SSO button, no redirect.
# If the identity service is unreachable or does not know the account, the
# local password check still runs (see IAM_LOGIN_DELEGATION).
IAM_ENABLED=false
IAM_ISSUER=
# The client must be registered there as confidential AND trusted.
IAM_CLIENT_ID=
IAM_CLIENT_SECRET=
# One of the two; tenant_id wins when both are set.
IAM_TENANT_ID=
IAM_TENANT_SLUG=
# off | fallback (default, safest) | exclusive (local password no longer accepted)
IAM_LOGIN_DELEGATION=fallback
IAM_HTTP_TIMEOUT_MS=8000
# صفحه callback اپ کاربر. باید در کلاینت IAM دقیقاً ثبت شود.
IAM_REDIRECT_URI=
# callbackهای اضافه (دولوپ و دامنه دیگر) با کاما. آدرس ناشناس جایگزین نمی‌شود.
IAM_REDIRECT_URIS=
# بعد از ورود محلی، مرورگر برای کوکی نشست مشترک به اینجا برمی‌گردد.
IAM_BROWSER_RETURN_URL=
# خروج سراسری فقط اگر این آدرس در post_logout کلاینت ثبت شده باشد برمی‌گردد.
IAM_POST_LOGOUT_REDIRECT_URI=
# مقصدهای مجاز خروج اپ کاربر، با کاما. باید عیناً در post_logout کلاینت باشند.
IAM_ALLOWED_RETURN_URLS=
# پنل ادمین. خالی یعنی بررسی بی‌صدای ورود در پنل انجام نمی‌شود.
# IAM_ADMIN_BROWSER_RETURN_URL را خالی نگذارید اگر IAM_BROWSER_RETURN_URL
# (اپ کاربر) پر است — وگرنه بعد از ورود ادمین مرورگر به اپ کاربر می‌افتد.
IAM_ADMIN_REDIRECT_URI=
IAM_ADMIN_REDIRECT_URIS=
IAM_ADMIN_BROWSER_RETURN_URL=
IAM_ADMIN_POST_LOGOUT_REDIRECT_URI=
IAM_ADMIN_ALLOWED_RETURN_URLS=
# Revocable admin sessions (AdminSession table).
#
# An admin token is self-contained and lives for JWT_EXPIRES_IN (12h), so until
# this existed nothing could end a session early — not disabling the account, not
# a central sign-out. Every issued token now carries a `jti` recorded in the
# database, and a revoked row is refused on the next request.
#
# Unset = follows IAM_ENABLED (on with the IAM, so central revocation reaches
# here). `true` turns it on without the IAM; `false` opts out of the per-request
# lookup and central revocation then cannot end a session here.
AUTH_SESSION_TRACKING=
# To let the IAM end sessions here, register this path on the client there as its
# backchannel_logout_uri:
# https://<api-host>/api/iam/backchannel-logout
# ---------------------------------------------------------------------------
# ⚠ DELIVERY ONLY — REMOVE BEFORE THE REAL RELEASE (D20 / ISSUES REL-01)
# ---------------------------------------------------------------------------
# A fixed OTP that signs in ANY active customer, alongside the real code.
# MUST BE EXACTLY 4 DIGITS: the apps' login box has four single-character
# inputs and only submits at four (LoginView.vue:43). A longer code still works
# over the API but cannot be typed into either app.
# Leave it EMPTY or unset to disable it completely — that is the correct state
# for production. While it is set, the API prints a warning banner at boot.
OTP_MASTER_CODE=
# ---------------------------------------------------------------------------
# SMS gateway. The default "relay" driver works with everything blank (D26).
# A failed SMS never stops the server or an operation (D20).
# ---------------------------------------------------------------------------
# "relay" (default), "trez", or "none" to disable explicitly.
SMS_PROVIDER=
# relay — the owner's createsms gateway. All four are 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 — inside
# Docker that is the container's address.
SMS_RELAY_HOST=
# trez — only used with SMS_PROVIDER=trez. Never commit real values.
# Override only for staging; defaults to the provider's live endpoint.
SMS_TREZ_URL=
SMS_TREZ_USERNAME=
SMS_TREZ_PASSWORD=
SMS_TREZ_SENDER_LINE=
# ---------------------------------------------------------------------------
# Uploads
# ---------------------------------------------------------------------------
# Absolute path for uploaded files; defaults to <api>/storage/uploads.
UPLOAD_DIR=
# ---------------------------------------------------------------------------
# Profile completion ("تکمیل پروفایل")
# ---------------------------------------------------------------------------
# Comma-separated admin mobiles told when a customer uploads their documents.
# The reference hardcoded four numbers in its source
# (henza_server Major/CustomerController::sendSmsToAdmin); they live here
# instead so no personal number is committed. Blank means nobody is notified —
# the upload and the customer's own SMS still go through (D20).
PROFILE_ADMIN_MOBILES=
# ---------------------------------------------------------------------------
# Order placement
# ---------------------------------------------------------------------------
# Comma-separated admin mobiles told when a customer places an order. The
# reference hardcoded four numbers (henza_server
# Api/ApiMobileController::setOrder:740-743). Blank means nobody is notified —
# the order, the customer's SMS and the sales expert's SMS still go through.
ORDER_ADMIN_MOBILES=
# ---------------------------------------------------------------------------
# Brand
# ---------------------------------------------------------------------------
# The name at the top of every SMS («تهران تاج\n…») and the site link in the
# welcome SMS. Blank = the defaults in apps/api/src/common/brand.ts. The
# frontends take their brand from the repo-root brand.ts instead; the full
# rebrand checklist is docs/BRANDING.md.
BRAND_NAME=
BRAND_SITE_URL=