2025-09-01 15:11:42 +09:00
|
|
|
NODE_ENV=production
|
|
|
|
|
|
|
|
|
|
# App
|
|
|
|
|
APP_BASE_URL=https://asolutions.jp
|
|
|
|
|
BFF_PORT=4000
|
2025-09-06 14:05:18 +09:00
|
|
|
APP_NAME=customer-portal-bff
|
2025-09-01 15:11:42 +09:00
|
|
|
|
|
|
|
|
# Database (PostgreSQL)
|
|
|
|
|
POSTGRES_DB=portal_prod
|
|
|
|
|
POSTGRES_USER=portal
|
|
|
|
|
POSTGRES_PASSWORD=CHANGE_ME
|
|
|
|
|
DATABASE_URL=postgresql://portal:CHANGE_ME@database:5432/portal_prod?schema=public
|
|
|
|
|
|
|
|
|
|
# Cache (Redis)
|
|
|
|
|
REDIS_URL=redis://cache:6379/0
|
2025-09-26 17:02:36 +09:00
|
|
|
AUTH_ALLOW_REDIS_TOKEN_FAILOPEN=false
|
|
|
|
|
# Redis-required token flow (when enabled, tokens require Redis to be available)
|
|
|
|
|
AUTH_REQUIRE_REDIS_FOR_TOKENS=false
|
|
|
|
|
# Maintenance mode for authentication service
|
|
|
|
|
AUTH_MAINTENANCE_MODE=false
|
|
|
|
|
AUTH_MAINTENANCE_MESSAGE=Authentication service is temporarily unavailable for maintenance. Please try again later.
|
2025-09-01 15:11:42 +09:00
|
|
|
|
|
|
|
|
# Security
|
|
|
|
|
JWT_SECRET=CHANGE_ME
|
|
|
|
|
JWT_EXPIRES_IN=7d
|
|
|
|
|
BCRYPT_ROUNDS=12
|
|
|
|
|
|
2025-11-05 15:47:06 +09:00
|
|
|
# CSRF Protection
|
|
|
|
|
CSRF_TOKEN_EXPIRY=3600000
|
|
|
|
|
CSRF_SECRET_KEY=CHANGE_ME_AT_LEAST_32_CHARACTERS_LONG
|
|
|
|
|
CSRF_COOKIE_NAME=csrf-secret
|
|
|
|
|
CSRF_HEADER_NAME=X-CSRF-Token
|
|
|
|
|
|
2025-09-01 15:11:42 +09:00
|
|
|
# CORS / Proxy
|
|
|
|
|
CORS_ORIGIN=https://asolutions.jp
|
|
|
|
|
TRUST_PROXY=true
|
|
|
|
|
|
2025-10-29 15:54:45 +09:00
|
|
|
# Rate Limiting (optional; defaults shown - ttl values in seconds)
|
|
|
|
|
RATE_LIMIT_TTL=60
|
2025-09-06 14:05:18 +09:00
|
|
|
RATE_LIMIT_LIMIT=100
|
2025-10-29 15:54:45 +09:00
|
|
|
AUTH_RATE_LIMIT_TTL=900
|
2025-09-06 14:05:18 +09:00
|
|
|
AUTH_RATE_LIMIT_LIMIT=3
|
2025-11-05 15:47:06 +09:00
|
|
|
AUTH_REFRESH_RATE_LIMIT_TTL=300
|
|
|
|
|
AUTH_REFRESH_RATE_LIMIT_LIMIT=10
|
|
|
|
|
LOGIN_RATE_LIMIT_TTL=900
|
|
|
|
|
LOGIN_RATE_LIMIT_LIMIT=5
|
|
|
|
|
LOGIN_CAPTCHA_AFTER_ATTEMPTS=3
|
|
|
|
|
SIGNUP_RATE_LIMIT_TTL=900
|
|
|
|
|
SIGNUP_RATE_LIMIT_LIMIT=5
|
|
|
|
|
PASSWORD_RESET_RATE_LIMIT_TTL=900
|
|
|
|
|
PASSWORD_RESET_RATE_LIMIT_LIMIT=5
|
|
|
|
|
|
|
|
|
|
# CAPTCHA Configuration
|
|
|
|
|
AUTH_CAPTCHA_PROVIDER=none
|
|
|
|
|
AUTH_CAPTCHA_SECRET=
|
|
|
|
|
AUTH_CAPTCHA_THRESHOLD=0
|
|
|
|
|
AUTH_CAPTCHA_ALWAYS_ON=false
|
2025-09-06 14:05:18 +09:00
|
|
|
|
2025-09-06 17:38:42 +09:00
|
|
|
# Validation error visibility (set true to show field-level errors to clients)
|
|
|
|
|
EXPOSE_VALIDATION_ERRORS=false
|
|
|
|
|
|
2025-09-01 15:11:42 +09:00
|
|
|
# WHMCS Credentials
|
|
|
|
|
WHMCS_BASE_URL=https://accounts.asolutions.co.jp
|
|
|
|
|
WHMCS_API_IDENTIFIER=
|
|
|
|
|
WHMCS_API_SECRET=
|
2025-09-06 14:05:18 +09:00
|
|
|
# Optional API access key if your deployment uses it
|
|
|
|
|
WHMCS_API_ACCESS_KEY=
|
|
|
|
|
# Optional webhook security for WHMCS webhooks
|
|
|
|
|
WHMCS_WEBHOOK_SECRET=
|
2025-09-06 13:57:14 +09:00
|
|
|
# Optional elevated admin credentials for privileged actions (eg. AcceptOrder)
|
|
|
|
|
# Provide the admin username and MD5 hash of the admin password.
|
|
|
|
|
# When set, the backend will use these ONLY for the AcceptOrder action.
|
|
|
|
|
WHMCS_ADMIN_USERNAME=
|
|
|
|
|
WHMCS_ADMIN_PASSWORD_MD5=
|
2025-09-01 15:11:42 +09:00
|
|
|
|
|
|
|
|
# Salesforce Credentials
|
|
|
|
|
SF_LOGIN_URL=https://asolutions.my.salesforce.com
|
|
|
|
|
SF_CLIENT_ID=
|
|
|
|
|
SF_PRIVATE_KEY_PATH=/app/secrets/sf-private.key
|
|
|
|
|
SF_USERNAME=
|
2025-09-06 14:05:18 +09:00
|
|
|
SF_WEBHOOK_SECRET=
|
2025-09-26 17:02:36 +09:00
|
|
|
# Salesforce Authentication Timeouts (in milliseconds)
|
|
|
|
|
SF_AUTH_TIMEOUT_MS=30000
|
|
|
|
|
SF_TOKEN_TTL_MS=720000
|
|
|
|
|
SF_TOKEN_REFRESH_BUFFER_MS=60000
|
|
|
|
|
|
|
|
|
|
# Queue Throttling Configuration
|
|
|
|
|
WHMCS_QUEUE_CONCURRENCY=15
|
|
|
|
|
WHMCS_QUEUE_INTERVAL_CAP=300
|
|
|
|
|
WHMCS_QUEUE_TIMEOUT_MS=30000
|
|
|
|
|
SF_QUEUE_CONCURRENCY=15
|
|
|
|
|
SF_QUEUE_LONG_RUNNING_CONCURRENCY=22
|
|
|
|
|
SF_QUEUE_INTERVAL_CAP=600
|
|
|
|
|
SF_QUEUE_TIMEOUT_MS=30000
|
|
|
|
|
SF_QUEUE_LONG_RUNNING_TIMEOUT_MS=600000
|
2025-09-01 15:11:42 +09:00
|
|
|
|
2025-09-06 10:01:44 +09:00
|
|
|
# Salesforce Platform Events (Provisioning)
|
|
|
|
|
SF_EVENTS_ENABLED=true
|
2025-11-06 16:32:29 +09:00
|
|
|
SF_CATALOG_EVENT_CHANNEL=/event/Product_and_Pricebook_Change__e
|
|
|
|
|
SF_ACCOUNT_EVENT_CHANNEL=/event/Account_Internet_Eligibility_Update__e
|
|
|
|
|
SF_ORDER_EVENT_CHANNEL=/event/Order_Fulfilment_Requested__e
|
2025-09-06 10:01:44 +09:00
|
|
|
SF_EVENTS_REPLAY=LATEST
|
|
|
|
|
SF_PUBSUB_NUM_REQUESTED=50
|
|
|
|
|
SF_PUBSUB_QUEUE_MAX=100
|
2025-11-06 16:32:29 +09:00
|
|
|
SF_PUBSUB_ENDPOINT=api.pubsub.salesforce.com:7443
|
|
|
|
|
|
|
|
|
|
# Salesforce Change Data Capture (CDC) for Catalog Cache Invalidation
|
|
|
|
|
# These use /data/ prefix for built-in CDC events (no setup needed in Salesforce)
|
|
|
|
|
SF_CATALOG_PRODUCT_CDC_CHANNEL=/data/Product2ChangeEvent
|
|
|
|
|
SF_CATALOG_PRICEBOOKENTRY_CDC_CHANNEL=/data/PricebookEntryChangeEvent
|
|
|
|
|
# Optional: Platform Event for account eligibility updates (requires Salesforce setup)
|
|
|
|
|
SF_ACCOUNT_ELIGIBILITY_CHANNEL=/event/Account_Internet_Eligibility_Update__e
|
|
|
|
|
|
|
|
|
|
# Salesforce Change Data Capture (CDC) for Order Cache Invalidation
|
|
|
|
|
# These use /data/ prefix for built-in CDC events (no setup needed in Salesforce)
|
|
|
|
|
# Smart filtering: Only invalidates cache for customer-facing field changes, NOT internal fulfillment fields
|
|
|
|
|
SF_ORDER_CDC_CHANNEL=/data/OrderChangeEvent
|
|
|
|
|
SF_ORDER_ITEM_CDC_CHANNEL=/data/OrderItemChangeEvent
|
2025-09-06 10:01:44 +09:00
|
|
|
|
2025-09-01 15:11:42 +09:00
|
|
|
# Salesforce Pricing
|
|
|
|
|
PORTAL_PRICEBOOK_ID=
|
|
|
|
|
|
|
|
|
|
# Logging
|
|
|
|
|
LOG_LEVEL=info
|
|
|
|
|
LOG_FORMAT=json
|
|
|
|
|
|
|
|
|
|
# Email (SendGrid)
|
|
|
|
|
SENDGRID_API_KEY=
|
|
|
|
|
EMAIL_FROM=no-reply@asolutions.jp
|
|
|
|
|
EMAIL_FROM_NAME=Assist Solutions
|
|
|
|
|
EMAIL_ENABLED=true
|
|
|
|
|
EMAIL_USE_QUEUE=true
|
|
|
|
|
SENDGRID_SANDBOX=false
|
|
|
|
|
EMAIL_TEMPLATE_RESET=
|
|
|
|
|
EMAIL_TEMPLATE_WELCOME=
|
|
|
|
|
|
2025-09-06 14:05:18 +09:00
|
|
|
# Freebit (SIM management; optional)
|
|
|
|
|
FREEBIT_BASE_URL=https://i1.mvno.net/emptool/api
|
|
|
|
|
FREEBIT_OEM_ID=PASI
|
|
|
|
|
FREEBIT_OEM_KEY=
|
|
|
|
|
FREEBIT_TIMEOUT=30000
|
|
|
|
|
FREEBIT_RETRY_ATTEMPTS=3
|
|
|
|
|
FREEBIT_DETAILS_ENDPOINT=/master/getAcnt/
|
|
|
|
|
|
2025-09-01 15:11:42 +09:00
|
|
|
# Node Options
|
|
|
|
|
NODE_OPTIONS=--max-old-space-size=512
|
|
|
|
|
|
2025-09-06 10:01:44 +09:00
|
|
|
# NOTE: Frontend (Next.js) uses a separate env file (portal-frontend.env)
|
|
|
|
|
# Do not include NEXT_PUBLIC_* variables here.
|
2025-11-06 16:32:29 +09:00
|
|
|
# Salesforce Account Portal Flags
|
|
|
|
|
ACCOUNT_PORTAL_STATUS_FIELD=Portal_Status__c
|
|
|
|
|
ACCOUNT_PORTAL_STATUS_SOURCE_FIELD=Portal_Registration_Source__c
|
|
|
|
|
ACCOUNT_PORTAL_LAST_SIGNED_IN_FIELD=Portal_Last_SignIn__c
|