diff --git a/.gitignore b/.gitignore index d9bf8f57..ffbfbdb0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules/ **/package-lock.json # Environment files +.stack.env .env .env.local .env.development diff --git a/apps/portal/src/lib/providers.tsx b/apps/portal/src/lib/providers.tsx index 8cde2984..552dd61a 100644 --- a/apps/portal/src/lib/providers.tsx +++ b/apps/portal/src/lib/providers.tsx @@ -51,7 +51,7 @@ export function QueryProvider({ children, nonce }: QueryProviderProps) { return ( {children} - {process.env.NODE_ENV === "development" && } + {process.env.NODE_ENV === "development" && } ); } diff --git a/docker/Prod - Portainer/README.md b/docker/Prod - Portainer/README.md index db3c4726..fb78db25 100644 --- a/docker/Prod - Portainer/README.md +++ b/docker/Prod - Portainer/README.md @@ -23,7 +23,7 @@ docker images | grep portal 2. Name: `customer-portal` 3. Paste contents of `docker-compose.yml` 4. Scroll down to **Environment Variables** -5. Copy variables from `stack.env.example` and fill in your values +5. Copy variables from `stack.env.example` and fill in your production values ### 3. Generate Secrets diff --git a/docker/Prod - Portainer/docker-compose.yml b/docker/Prod - Portainer/docker-compose.yml index a1e1016f..aa42ad71 100644 --- a/docker/Prod - Portainer/docker-compose.yml +++ b/docker/Prod - Portainer/docker-compose.yml @@ -25,7 +25,7 @@ services: links: - backend healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"] + test: ["CMD", "node", "-e", "fetch('http://localhost:3000/api/health').then(r=>r.ok||process.exit(1)).catch(()=>process.exit(1))"] interval: 30s timeout: 10s start_period: 40s @@ -117,7 +117,7 @@ services: # - Database migration when RUN_MIGRATIONS=true # - Waiting for dependencies (nc checks in entrypoint) healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/health"] + test: ["CMD", "node", "-e", "fetch('http://localhost:4000/health').then(r=>r.ok||process.exit(1)).catch(()=>process.exit(1))"] interval: 30s timeout: 10s start_period: 60s diff --git a/docker/Prod - Portainer/stack.env.example b/docker/Prod - Portainer/env.example similarity index 73% rename from docker/Prod - Portainer/stack.env.example rename to docker/Prod - Portainer/env.example index a6a80259..8bfbbf0b 100644 --- a/docker/Prod - Portainer/stack.env.example +++ b/docker/Prod - Portainer/env.example @@ -1,8 +1,8 @@ # ============================================================================= -# Customer Portal - Portainer Environment Variables (TEMPLATE) +# Customer Portal - Portainer Environment Variables # ============================================================================= -# Copy this file and fill in your actual values. -# DO NOT commit files with real secrets to version control. +# Copy these into Portainer UI when creating/updating the stack +# Replace all placeholder values with your actual secrets # ============================================================================= # ----------------------------------------------------------------------------- @@ -18,26 +18,24 @@ BACKEND_PORT=4000 # Application # ----------------------------------------------------------------------------- APP_NAME=customer-portal-bff -APP_BASE_URL=https://your-domain.com -CORS_ORIGIN=https://your-domain.com +APP_BASE_URL=https://asolutions.jp +CORS_ORIGIN=https://asolutions.jp # ----------------------------------------------------------------------------- # Database (PostgreSQL) # ----------------------------------------------------------------------------- POSTGRES_DB=portal_prod POSTGRES_USER=portal -# Generate with: openssl rand -base64 24 -POSTGRES_PASSWORD= +POSTGRES_PASSWORD= # ----------------------------------------------------------------------------- # Security & Auth # ----------------------------------------------------------------------------- # Generate with: openssl rand -base64 32 -JWT_SECRET= +JWT_SECRET= JWT_EXPIRES_IN=7d BCRYPT_ROUNDS=12 -# Generate with: openssl rand -base64 32 -CSRF_SECRET_KEY= +CSRF_SECRET_KEY= # Auth Settings AUTH_ALLOW_REDIS_TOKEN_FAILOPEN=false @@ -51,45 +49,44 @@ RATE_LIMIT_LIMIT=100 # ----------------------------------------------------------------------------- # WHMCS Integration # ----------------------------------------------------------------------------- -WHMCS_BASE_URL=https://your-whmcs-instance.com -WHMCS_API_IDENTIFIER= -WHMCS_API_SECRET= - +WHMCS_BASE_URL=https://accounts.asolutions.co.jp +WHMCS_API_IDENTIFIER= +WHMCS_API_SECRET= # ----------------------------------------------------------------------------- # Salesforce Integration # ----------------------------------------------------------------------------- -SF_LOGIN_URL=https://your-org.my.salesforce.com -SF_CLIENT_ID= -SF_USERNAME= +SF_LOGIN_URL=https://asolutions.my.salesforce.com +SF_CLIENT_ID= +SF_USERNAME= SF_EVENTS_ENABLED=true # Salesforce Private Key (Base64 encoded) # To encode: base64 -w 0 < sf-private.key -SF_PRIVATE_KEY_BASE64= +SF_PRIVATE_KEY_BASE64= + # ----------------------------------------------------------------------------- # Freebit SIM API # ----------------------------------------------------------------------------- FREEBIT_BASE_URL=https://i1.mvno.net/emptool/api -FREEBIT_OEM_ID= -FREEBIT_OEM_KEY= +FREEBIT_OEM_ID=PASI +FREEBIT_OEM_KEY= # ----------------------------------------------------------------------------- # Email (SendGrid) # ----------------------------------------------------------------------------- EMAIL_ENABLED=true -EMAIL_FROM=no-reply@your-domain.com -EMAIL_FROM_NAME=Your Company Name +EMAIL_FROM=no-reply@asolutions.jp +EMAIL_FROM_NAME=Assist Solutions SENDGRID_API_KEY= # ----------------------------------------------------------------------------- # Salesforce Portal Config # ----------------------------------------------------------------------------- -PORTAL_PRICEBOOK_ID= +PORTAL_PRICEBOOK_ID= PORTAL_PRICEBOOK_NAME=Portal # ----------------------------------------------------------------------------- # Logging # ----------------------------------------------------------------------------- LOG_LEVEL=info - diff --git a/docker/Prod - Portainer/stack.env b/docker/Prod - Portainer/stack.env deleted file mode 100644 index e3634cfc..00000000 --- a/docker/Prod - Portainer/stack.env +++ /dev/null @@ -1,112 +0,0 @@ -# ============================================================================= -# Customer Portal - Portainer Environment Variables -# ============================================================================= -# Copy these into Portainer UI when creating/updating the stack -# Replace all placeholder values with your actual secrets -# ============================================================================= - -# ----------------------------------------------------------------------------- -# Images & Ports -# ----------------------------------------------------------------------------- -FRONTEND_IMAGE=portal-frontend -BACKEND_IMAGE=portal-backend -IMAGE_TAG=latest -FRONTEND_PORT=3000 -BACKEND_PORT=4000 - -# ----------------------------------------------------------------------------- -# Application -# ----------------------------------------------------------------------------- -APP_NAME=customer-portal-bff -APP_BASE_URL=https://asolutions.jp -CORS_ORIGIN=https://asolutions.jp - -# ----------------------------------------------------------------------------- -# Database (PostgreSQL) -# ----------------------------------------------------------------------------- -POSTGRES_DB=portal_prod -POSTGRES_USER=portal -POSTGRES_PASSWORD=wf8vVNxaGXqJbE4AMwBg8olJtUptLNcH - -# ----------------------------------------------------------------------------- -# Security & Auth -# ----------------------------------------------------------------------------- -# Generate with: openssl rand -base64 32 -JWT_SECRET=N+HXXwJBM93omVC8mCbrrWKNR/deCmSe5q4TTwMFur8= -JWT_EXPIRES_IN=7d -BCRYPT_ROUNDS=12 -CSRF_SECRET_KEY=/W6PPJ0DeduasE4GqeLIxfdSNg9TDNwyuVNz0IWz0Bs= - -# Auth Settings -AUTH_ALLOW_REDIS_TOKEN_FAILOPEN=false -AUTH_REQUIRE_REDIS_FOR_TOKENS=false -AUTH_MAINTENANCE_MODE=false - -# Rate Limiting -RATE_LIMIT_TTL=60 -RATE_LIMIT_LIMIT=100 - -# ----------------------------------------------------------------------------- -# WHMCS Integration -# ----------------------------------------------------------------------------- -WHMCS_BASE_URL=https://dev-wh.asolutions.co.jp -WHMCS_API_IDENTIFIER=WZckHGfzAQEum3v5SAcSfzgvVkPJEF2M -WHMCS_API_SECRET=YlqKyynJ6I1088DV6jufFj6cJiW0N0y4 -# ----------------------------------------------------------------------------- -# Salesforce Integration -# ----------------------------------------------------------------------------- -SF_LOGIN_URL=https://asolutions.my.salesforce.com -SF_CLIENT_ID=3MVG9n_HvETGhr3Af33utEHAR_KbKEQh_.KRzVBBA6u3tSIMraIlY9pqNqKJgUILstAPS4JASzExj3OpCRbLz -SF_USERNAME=portal.integration@asolutions.co.jp -SF_EVENTS_ENABLED=true - -# Salesforce Private Key (Base64 encoded) -# To encode: base64 -w 0 < sf-private.key -SF_PRIVATE_KEY_BASE64=MIIDvzCCAqegAwIBAgIUWD/Nx/Tem+FbPzsowuIYP6eioWwwDQYJKoZIhvcNAQEL -BQAwbzELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMQ4wDAYDVQQHDAVUb2t5 -bzEZMBcGA1UECgwQQXNzaXN0IFNvbHV0aW9uczELMAkGA1UECwwCSVQxGDAWBgNV -BAMMD0N1c3RvbWVyIFBvcnRhbDAeFw0yNTA4MTUwNTAxMDNaFw0yNjA4MTUwNTAx -MDNaMG8xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEOMAwGA1UEBwwFVG9r -eW8xGTAXBgNVBAoMEEFzc2lzdCBTb2x1dGlvbnMxCzAJBgNVBAsMAklUMRgwFgYD -VQQDDA9DdXN0b21lciBQb3J0YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCtBK38ZXzz3LA8dKqHbwz+ucWLPqz8sjoXY4V0W+fMhifn5Oi4u3k2mlqg -J2bGFPn8DH5cRafM0+CCwO9TV6PbYxolsO7NKjFxSERJPqj5tZ0bpZljul4J0wiJ -ZyT8NWK+WV9aga+zrHOThgvUSPJAb3I1FbRSSha9k2UsaZ5Ubo43EFMRAoAU1DqV -tRvG9UW+Ditrlr/8hhDT8WREwzwdGc4GVtM2AsiNNbKM5kcjhu8sgKZ2j+ZCM+0l -yk0JUcciSYUWgY79XEvCVAAiUGiL3qtxurEe02f9/ISWawbJne1SQIhaXZycsehm -VHN4ySW5uj2waOu4IzDXOqW75e+1AgMBAAGjUzBRMB0GA1UdDgQWBBTOBfxQ/VS+ -MtjqnY2ielB6n4qHVDAfBgNVHSMEGDAWgBTOBfxQ/VS+MtjqnY2ielB6n4qHVDAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAcpPfUF4kPuiB91Igq -gwpRZmUJjq0+fIv2Llyn3Q+srk/IOcnkjJgaksGTXPwsMErtcD60z1tIzp39aDl2 -wUmTxssXg41X7jBpy9Q7wXduvZwpSHbwrz8GShGKnwBCITTVHg0PRCIMn9DvJg3H -So/A2TQyazhWSh1yz4P6hAn7UKAG4rzMPjyzq+RYFOSKKCtdJ5ImqIkrNnHhQj/4 -py/E6K6/ZkroKWr6z1gFU2E8xQQ+u1YNAEjL8U+vd0ftLmYTHCciaZdy4emo5BRg -V8oZp81Kw1Da+nVuBCMtZ4ICYLBI8LVtfkzdFDr3MShRWcPe+k6/lbDfT98qy01O -26sJ - - -# ----------------------------------------------------------------------------- -# Freebit SIM API -# ----------------------------------------------------------------------------- -FREEBIT_BASE_URL=https://i1-q.mvno.net/emptool/api -FREEBIT_OEM_ID=PASI -FREEBIT_OEM_KEY=6Au3o7wrQNR07JxFHPmf0YfFqN9a31t5 - -# ----------------------------------------------------------------------------- -# Email (SendGrid) -# ----------------------------------------------------------------------------- -EMAIL_ENABLED=true -EMAIL_FROM=no-reply@asolutions.jp -EMAIL_FROM_NAME=Assist Solutions -SENDGRID_API_KEY= - -# ----------------------------------------------------------------------------- -# Salesforce Portal Config -# ----------------------------------------------------------------------------- -PORTAL_PRICEBOOK_ID=01sTL000008eLVlYAM -PORTAL_PRICEBOOK_NAME=Portal - -# ----------------------------------------------------------------------------- -# Logging -# ----------------------------------------------------------------------------- -LOG_LEVEL=info