From c0bac7aa231c672261b6c35c72bbed9b85840d65 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Thu, 23 Apr 2026 23:17:50 +0530 Subject: [PATCH] fix(prod): wire MARKETING_URL + COOKIE_DOMAIN into config template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step C of the OSS restructure (66c8f59) removed the automatic https://instanode.dev → https://api.instanode.dev swap that the old code used to paper over a misconfigured APP_URL. With the swap gone, the prod deploy has three regressions driven by config.prod.yaml.tpl never threading the new fields through: 1. POST /webhook/new returns a receive_url on instanode.dev (the static marketing host, which 405s POST) instead of api.instanode.dev. 2. OAuth login redirects to http://localhost:5173/dashboard.html (the default for MarketingURL when the env var isn't set). 3. Dashboard upgrade URL points at localhost:5173 for the same reason. This PR adds the three fields to the prod template so DO's envsubst step populates them from env vars. The AllowedOrigins list is hardcoded here (not env-driven) because YAML-list envsubst is awkward and the production origins are stable. The actual DO env var updates (APP_URL → api.instanode.dev, new MARKETING_URL + COOKIE_DOMAIN, rotated NEWRELIC_LICENSE_KEY as SECRET) are ops actions and must happen before this PR merges so the first deploy after merge reads populated values. Runbook in the PR description. --- config.prod.yaml.tpl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/config.prod.yaml.tpl b/config.prod.yaml.tpl index 0d9f79d..23e1f42 100644 --- a/config.prod.yaml.tpl +++ b/config.prod.yaml.tpl @@ -4,6 +4,20 @@ server: port: "8080" base_url: "${APP_URL}" + # MarketingURL is the public website host. Used for post-OAuth + # redirects, dashboard upgrade links, and email CTAs. On this + # deployment: api.instanode.dev is the API, instanode.dev is the + # static marketing site on GitHub Pages. + marketing_url: "${MARKETING_URL}" + # CookieDomain shares the session cookie across api.example.com + # and example.com. Empty = scoped to API host only. + cookie_domain: "${COOKIE_DOMAIN}" + # CORS exact-match allowlist. The marketing host needs to be here + # so dashboard.html fetch() calls with credentials:'include' work. + allowed_origins: + - "https://instanode.dev" + - "http://localhost:5173" + - "http://localhost:3000" read_timeout: "30s" write_timeout: "60s" idle_timeout: "120s"