From d8f4e8c4e56dfa915a987b01a7a1db926bec43b0 Mon Sep 17 00:00:00 2001 From: Alireza Hassani Date: Tue, 11 Aug 2026 16:03:33 +0330 Subject: [PATCH] Support local public invoice URLs with port overrides. Dev can set INVOICE_PUBLIC_BASE_URL or DEV_PORT/HOST so copied links reach the Vite viewer. Co-authored-by: Cursor --- .env.example | 6 +++++- src/invoices/invoices.service.ts | 24 +++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index 6e74a4d..4b4ea0c 100644 --- a/.env.example +++ b/.env.example @@ -94,5 +94,9 @@ SSL_SYNC_AGENT_TOKEN= # Public domain for platform invoice links (https://{domain}/invoices/{id}) INVOICE_PUBLIC_DOMAIN=meshkee.com -# Optional full origin for local (overrides domain), e.g. https://meshkee.app:5174 +# Optional full origin for local (overrides domain + business host), e.g. https://meshkee.app:5174 # INVOICE_PUBLIC_BASE_URL=https://meshkee.app:5174 +# Or keep production-style hosts and only append a port in non-production: +# INVOICE_PUBLIC_DEV_PORT=5174 +# INVOICE_PUBLIC_DEV_HOST=meshkee.app +# INVOICE_PUBLIC_DEV_PROTOCOL=https diff --git a/src/invoices/invoices.service.ts b/src/invoices/invoices.service.ts index 2e4fc4e..312027a 100644 --- a/src/invoices/invoices.service.ts +++ b/src/invoices/invoices.service.ts @@ -394,17 +394,27 @@ export class InvoicesService { .replace(/^https?:\/\//i, '') .replace(/\/$/, ''); - if (opts?.ownerScope === InvoiceOwnerScope.business) { - const host = opts.businessHost ? normalizeHost(opts.businessHost) : ''; - if (host) { - return `https://${host}/invoices/${publicId}`; - } - } - + // Local / explicit override (includes port), e.g. https://meshkee.app:5174 const base = process.env.INVOICE_PUBLIC_BASE_URL?.trim(); if (base) { return `${base.replace(/\/$/, '')}/invoices/${publicId}`; } + + if (opts?.ownerScope === InvoiceOwnerScope.business) { + const host = opts.businessHost ? normalizeHost(opts.businessHost) : ''; + if (host) { + // Dev-only: append port so links open the local public viewer. + const devPort = process.env.INVOICE_PUBLIC_DEV_PORT?.trim(); + if (process.env.NODE_ENV !== 'production' && devPort) { + const protocol = + process.env.INVOICE_PUBLIC_DEV_PROTOCOL?.trim() || 'https'; + const devHost = process.env.INVOICE_PUBLIC_DEV_HOST?.trim() || host; + return `${protocol}://${normalizeHost(devHost)}:${devPort}/invoices/${publicId}`; + } + return `https://${host}/invoices/${publicId}`; + } + } + const domain = process.env.INVOICE_PUBLIC_DOMAIN?.trim() || 'meshkee.com'; return `https://${domain}/invoices/${publicId}`; }