From 96118035673753446a2203e94e6ee1cde4b7c0b4 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Thu, 15 Oct 2026 23:24:50 +0330 Subject: [PATCH] feat: serve the same CRM on crm.montact.ir as an alias Co-authored-by: Cursor --- apps/api/src/main.ts | 7 ++++- apps/api/src/tracking/tracking.service.ts | 2 +- deploy/.env.production.example | 3 +++ deploy/DEPLOY.md | 33 ++++++++++++++++++----- deploy/nginx-crm.montact.ir.conf | 30 +++++++++++++++++++++ deploy/nginx-crm.montzar.ir.conf | 5 ++-- 6 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 deploy/nginx-crm.montact.ir.conf diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index 4335d50..2da6de4 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -17,8 +17,13 @@ async function bootstrap() { }), ); + const corsRaw = config.get('CORS_ORIGIN') ?? 'http://localhost:5173'; + const corsOrigins = corsRaw + .split(',') + .map((origin) => origin.trim()) + .filter(Boolean); app.enableCors({ - origin: config.get('CORS_ORIGIN') ?? 'http://localhost:5173', + origin: corsOrigins.length <= 1 ? (corsOrigins[0] ?? 'http://localhost:5173') : corsOrigins, credentials: true, }); diff --git a/apps/api/src/tracking/tracking.service.ts b/apps/api/src/tracking/tracking.service.ts index 7b57e36..64626bc 100644 --- a/apps/api/src/tracking/tracking.service.ts +++ b/apps/api/src/tracking/tracking.service.ts @@ -49,7 +49,7 @@ export class TrackingService { publicBaseUrl(): string { const explicit = this.config.get('PUBLIC_API_BASE_URL')?.trim(); if (explicit) return explicit.replace(/\/$/, ''); - const cors = this.config.get('CORS_ORIGIN')?.trim(); + const cors = this.config.get('CORS_ORIGIN')?.split(',')[0]?.trim(); if (cors) return `${cors.replace(/\/$/, '')}/api`; return 'http://localhost:3000/api'; } diff --git a/deploy/.env.production.example b/deploy/.env.production.example index 696fd0e..ab824f2 100644 --- a/deploy/.env.production.example +++ b/deploy/.env.production.example @@ -3,6 +3,9 @@ NODE_ENV=production PORT=3030 +# چند دامنه با ویرگول — همان اپ روی crm.montzar.ir و crm.montact.ir +CORS_ORIGIN=https://crm.montzar.ir,https://crm.montact.ir +# لینک‌های عمومی/وب‌هوک (اولین دامنهٔ اصلی) PUBLIC_API_BASE_URL=https://crm.montzar.ir/api diff --git a/deploy/DEPLOY.md b/deploy/DEPLOY.md index a766fa5..6f5a81b 100644 --- a/deploy/DEPLOY.md +++ b/deploy/DEPLOY.md @@ -22,7 +22,7 @@ pm2 restart mento-crm-api --- هاست مشترک مونتایم: `185.50.38.53` (SSH پورت `3031`، کاربر `montime`) -دامنه: `https://crm.montzar.ir` +دامنه‌ها (همان اپ و همان مسیر): `https://crm.montzar.ir` و `https://crm.montact.ir` مسیر کد: `/var/www/crm` پورت داخلی API: `3030` PM2: `mento-crm-api` (cwd: `apps/api`، اسکریپت: `dist/src/main.js`) @@ -37,10 +37,11 @@ PM2: `mento-crm-api` (cwd: `apps/api`، اسکریپت: `dist/src/main.js`) ## کارهایی که شما باید انجام دهید (قبل/همراه استقرار) -1. **DNS:** رکورد `A` برای `crm.montzar.ir` مثل `ktg.montzar.ir` / `adm.montzar.ir` روی همان IP. -2. **Postgres:** دیتابیس و کاربر جدا (`mento_crm`) — به دیتابیس مونتایم دست نزنید. -3. **SMS:** همان حساب ترِز/رایگان مونتایم در `.env` (`SMS_USERNAME` / `SMS_PASSWORD` / `SMS_SENDER`). -4. **دسترسی Gitea** برای `git clone` / `git pull` روی سرور. +1. **DNS:** رکورد `A` برای `crm.montzar.ir` و `crm.montact.ir` مثل `ktg.montzar.ir` / `adm.montzar.ir` روی همان IP. +2. **پروکسی جلویی SSL:** مثل `crm.montzar.ir`، برای `crm.montact.ir` هم HTTPS تمام شود و به این سرور **HTTP :80** برسد. +3. **Postgres:** دیتابیس و کاربر جدا (`mento_crm`) — به دیتابیس مونتایم دست نزنید. +4. **SMS:** همان حساب ترِز/رایگان مونتایم در `.env` (`SMS_USERNAME` / `SMS_PASSWORD` / `SMS_SENDER`). +5. **دسترسی Gitea** برای `git clone` / `git pull` روی سرور. --- @@ -83,7 +84,7 @@ nano apps/api/.env |---|---| | `DATABASE_URL` | Postgres روی **`127.0.0.1:15432`** است نه `5432` | | `PORT` | `3030` | -| `CORS_ORIGIN` | `https://crm.montzar.ir` | +| `CORS_ORIGIN` | `https://crm.montzar.ir,https://crm.montact.ir` | | `SMS_*` | همان ترِز مونتایم | | `PORTAL_SHOW_OTP` | در production حتماً `false` | | `INTEGRATIONS_ENCRYPTION_KEY` | ۶۴ کاراکتر hex برای رمز توکن ته‌حساب (`openssl rand -hex 32`) | @@ -180,9 +181,27 @@ sudo ln -sf /etc/nginx/sites-available/crm.montzar.ir /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx ``` +فایل vhost هر دو نام را دارد: `crm.montzar.ir` و `crm.montact.ir` → همان `root` و همان API روی پورت ۳۰۳۰. + **HTTPS روی همین باکس:** مثل `ktg.montzar.ir`، فرانت‌پروکسی (`91.247.174.1`) SSL را تمام می‌کند و به این سرور **HTTP :80** می‌زند. اگر Certbot روی این vhost `return 404` یا فقط HTTPS بگذارد، سایت از بیرون قطع می‌شود — vhost را روی الگوی HTTP نگه دارید (فایل `deploy/nginx-crm.montzar.ir.conf`). +### ۸ب) اضافه کردن دامنهٔ alias (`crm.montact.ir`) روی همین استقرار + +بعد از `git pull` و آپدیت سریع: + +```bash +# CORS هر دو دامنه +nano /var/www/crm/apps/api/.env +# CORS_ORIGIN=https://crm.montzar.ir,https://crm.montact.ir + +sudo cp /var/www/crm/deploy/nginx-crm.montzar.ir.conf /etc/nginx/sites-available/crm.montzar.ir +sudo nginx -t && sudo systemctl reload nginx +pm2 restart mento-crm-api +``` + +تست: `https://crm.montact.ir` و `https://crm.montzar.ir` هر دو همان پنل را نشان دهند. + ### ۹) تست 1. `https://crm.montzar.ir` → ورود پنل @@ -281,7 +300,7 @@ grep -c AutomationAction /var/www/crm/node_modules/@mento/shared/dist/index.d.ts | این پروژه | بقیه — دست نزنید | |---|---| -| دامنه `crm.montzar.ir` | `ktg` / `adm` / مونتایم | +| دامنه‌های `crm.montzar.ir` و `crm.montact.ir` | `ktg` / `adm` / مونتایم | | پورت ۳۰۳۰ و ۳۰۴۰ (STT فقط localhost) | ۳۰۰۰ / ۳۰۰۱ / ۳۰۱۰ / ۳۰۲۰ | | PM2 نام `mento-crm-api` و `mento-stt` | پروسه‌های موجود | | `/var/www/crm` | `/var/www/ktg` و … | diff --git a/deploy/nginx-crm.montact.ir.conf b/deploy/nginx-crm.montact.ir.conf new file mode 100644 index 0000000..7f96f28 --- /dev/null +++ b/deploy/nginx-crm.montact.ir.conf @@ -0,0 +1,30 @@ +# Alias for the same CRM app — optional second site file. +# Prefer adding both names on crm.montzar.ir (see nginx-crm.montzar.ir.conf). +# If you enable this file separately, do NOT redefine upstream mento_crm_api. + +server { + listen 80; + listen [::]:80; + server_name crm.montact.ir; + + client_max_body_size 50M; + + root /var/www/crm/apps/web/dist; + index index.html; + + location /api/ { + proxy_pass http://mento_crm_api; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + } + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/deploy/nginx-crm.montzar.ir.conf b/deploy/nginx-crm.montzar.ir.conf index a6a081e..2e62800 100644 --- a/deploy/nginx-crm.montzar.ir.conf +++ b/deploy/nginx-crm.montzar.ir.conf @@ -1,5 +1,6 @@ # Place under /etc/nginx/sites-available/crm.montzar.ir -# First deploy: HTTP only. Then: sudo certbot --nginx -d crm.montzar.ir +# Same app for crm.montzar.ir and crm.montact.ir (alias). +# Front proxy terminates SSL and forwards HTTP :80 here — do not put Certbot-only HTTPS on this box. # # Do not edit adm.montzar.ir / ktg.montzar.ir / montime vhosts for this. @@ -11,7 +12,7 @@ upstream mento_crm_api { server { listen 80; listen [::]:80; - server_name crm.montzar.ir; + server_name crm.montzar.ir crm.montact.ir; client_max_body_size 50M;