From 8a38ecdecce515fe86ecf347b47ca87726001c9e Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Mon, 22 Jun 2026 06:50:15 +0000 Subject: [PATCH] Add website same-origin deployment handoff --- ...LING_AND_DISTRIBUTION_PACKET_2026-06-22.md | 3 + ..._RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md | 4 + ...ME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md | 205 ++++++++++++++++++ .../HyperTwist/FEATURE_REGISTRY.md | 2 +- .../HyperTwist/ROADMAP.md | 5 + website/README.md | 7 + website/deploy/README.md | 29 +++ .../deploy/nginx/hypertwist.app.conf.example | 45 ++++ ...rtwist-website-auth-server.service.example | 22 ++ website/server/README.md | 5 + 10 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md create mode 100644 website/deploy/README.md create mode 100644 website/deploy/nginx/hypertwist.app.conf.example create mode 100644 website/deploy/systemd/hypertwist-website-auth-server.service.example diff --git a/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md b/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md index 09ef6b7..54cba7b 100644 --- a/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md +++ b/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md @@ -184,6 +184,9 @@ for `hypertwist.app` when a built `website/dist/index.html` is present: - the runtime-readiness verifier now warns when same-origin public posture leaves that static-serving mode implicit - request-level server coverage now also proves the live route behavior for public/app routes versus `/api/*`, `/auth*`, `/health`, and missing asset paths - the frontend public deployment surface now also includes first-party `robots.txt` plus `sitemap.xml` assets for the current public route set, while keeping `/app`, `/login`, and `/register` out of crawler posture +- the repo now also includes first-party `website/deploy/` handoff templates + for `nginx` plus `systemd`, with the concrete operator cutover sequence + recorded in `docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md` This is browser-based user access for the operator/account surface. diff --git a/docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md b/docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md index 2968fad..b7cc04a 100644 --- a/docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md +++ b/docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md @@ -86,6 +86,8 @@ when a built website bundle exists: - set `SERVE_STATIC_WEBSITE=false` to keep api-only mode explicit - set `SERVE_STATIC_WEBSITE=true` to require bundle presence instead of silently staying api-only - the readiness verifier now warns when same-origin public posture leaves this static-serving mode ambiguous +- the repo now also carries first-party `systemd` and `nginx` handoff templates + under `website/deploy/` plus a same-origin deployment cutover guide ## If a split-host auth topology is chosen later @@ -142,7 +144,9 @@ auth-server ownership in the repo. - `website/README.md` - `website/server/README.md` +- `website/deploy/README.md` - `docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md` +- `docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md` - `docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md` - `docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md` - `docs/ops/HYPERTWIST_VPS_TLS_CERTIFICATE_AND_IONOS_SEPARATION_GUIDE_2026-05-30.md` diff --git a/docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md b/docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md new file mode 100644 index 0000000..bcf7f48 --- /dev/null +++ b/docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md @@ -0,0 +1,205 @@ +# HyperTwist Website Same-Origin Deployment Handoff + +Created on `2026-06-22`. + +## Purpose + +This note records the concrete cutover path for replacing the current +placeholder `hypertwist.app` page with the first-party HyperTwist website plus +auth-server lane already shipped in the repo. + +This is the next operator step after: + +- the public website implementation packet +- the server-backed release-manifest authority packet +- the runtime-readiness placeholder-detection hardening + +## Current live problem on `2026-06-22` + +The public origin is still serving the older placeholder rollout page: + +- `https://hypertwist.app/` +- `https://hypertwist.app/api/auth/health` +- `https://hypertwist.app/api/releases/manifest` + +All three currently return the placeholder HTML page instead of the real +same-origin website/auth-server deployment. + +## Intended production topology + +The simplest honest deployment is: + +1. build the frontend in `website/` +2. run `website/server` as the long-lived local process on the VPS +3. let the server auto-serve `../dist` +4. put NGINX in front of that process on `https://hypertwist.app` + +That gives one public origin for: + +- the marketing shell +- auth routes +- dashboard routes +- `GET /api/auth/health` +- `GET /api/releases/manifest` +- `POST /api/billing/paddle/webhook` + +## Repo-provided deployment templates + +The repo now includes first-party same-origin templates under: + +- `website/deploy/nginx/hypertwist.app.conf.example` +- `website/deploy/systemd/hypertwist-website-auth-server.service.example` +- `website/deploy/README.md` + +These are operator handoff templates, not automatically applied machine state. + +## Expected filesystem posture on the VPS + +Example working checkout: + +- repo root: `/srv/hypertwist/current` +- frontend: `/srv/hypertwist/current/website` +- server: `/srv/hypertwist/current/website/server` + +Expected build output: + +- `/srv/hypertwist/current/website/dist/index.html` + +Expected runtime env files: + +- `/srv/hypertwist/current/website/.env` +- `/srv/hypertwist/current/website/server/.env` + +## Cutover sequence + +### 1. Sync the current repo to the VPS + +Ensure the current `main` branch includes: + +- `f160b7e` `Harden live website deployment readiness probe` +- the earlier website/auth/distribution commits on `2026-06-22` + +### 2. Fill real production env values + +Start from: + +- `website/.env.production.example` +- `website/server/.env.production.example` + +Replace placeholders with real production values before launch. + +Minimum required live values include: + +- `VITE_SUPERTOKENS_API_DOMAIN=https://hypertwist.app` +- `VITE_SUPERTOKENS_WEBSITE_DOMAIN=https://hypertwist.app` +- `VITE_AUTH_API_BASE_URL=https://hypertwist.app` +- real operator checkout URL +- real Windows download URL +- real corresponding-source URL +- `API_DOMAIN=https://hypertwist.app` +- `WEBSITE_DOMAIN=https://hypertwist.app` +- `COOKIE_SECURE=true` +- real `PADDLE_WEBHOOK_SECRET` +- real billing product/price map +- real release-manifest metadata values + +### 3. Install dependencies and build the frontend + +```bash +cd /srv/hypertwist/current/website +npm ci +npm run build + +cd /srv/hypertwist/current/website/server +npm ci +``` + +### 4. Install the systemd service + +Use: + +- `website/deploy/systemd/hypertwist-website-auth-server.service.example` + +Before enabling it: + +- replace `User=` and `Group=` if the service does not run as `hypertwist` +- replace `WorkingDirectory=` with the real checkout path +- replace `EnvironmentFile=` with the real server env path + +Install sequence: + +```bash +sudo cp /srv/hypertwist/current/website/deploy/systemd/hypertwist-website-auth-server.service.example \ + /etc/systemd/system/hypertwist-website-auth-server.service + +sudo systemctl daemon-reload +sudo systemctl enable --now hypertwist-website-auth-server.service +sudo systemctl status hypertwist-website-auth-server.service --no-pager +``` + +### 5. Install the NGINX vhost + +Use: + +- `website/deploy/nginx/hypertwist.app.conf.example` + +Install sequence: + +```bash +sudo cp /srv/hypertwist/current/website/deploy/nginx/hypertwist.app.conf.example \ + /etc/nginx/sites-available/hypertwist.app + +sudo ln -s /etc/nginx/sites-available/hypertwist.app /etc/nginx/sites-enabled/hypertwist.app +sudo nginx -t +sudo systemctl reload nginx +``` + +This config expects the existing Certbot-managed certificate paths already +described in: + +- `docs/ops/HYPERTWIST_VPS_TLS_CERTIFICATE_AND_IONOS_SEPARATION_GUIDE_2026-05-30.md` + +### 6. Confirm the placeholder page is gone + +The current public-origin proof should flip from placeholder HTML to real +website/auth-server behavior: + +```bash +curl --silent --show-error https://hypertwist.app/api/auth/health +curl --silent --show-error https://hypertwist.app/api/releases/manifest +curl --silent --show-error https://hypertwist.app/ | rg "hypertwist-site-shell|id=\"root\"" +``` + +### 7. Run the first-party readiness verifier + +From the live checkout: + +```bash +cd /srv/hypertwist/current/website +npm run check:runtime-readiness -- --frontend-env .env --server-env server/.env --health-url https://hypertwist.app +``` + +Expected live success conditions: + +- `/api/auth/health` returns JSON and reports public-ready posture +- `/api/releases/manifest` returns JSON and keeps anonymous download URLs hidden +- `/` exposes the first-party shell marker and `#root` mount +- no placeholder rollout page text remains + +## Fast rollback logic + +If cutover breaks: + +1. inspect `journalctl -u hypertwist-website-auth-server.service -n 200 --no-pager` +2. inspect `sudo nginx -t` +3. confirm `website/dist/index.html` exists +4. confirm `website/server/.env` has no placeholder values left +5. if necessary, disable the site vhost and restore the prior placeholder-only + NGINX config while keeping the repo state intact for reattempt + +## Authority links + +- `website/README.md` +- `website/server/README.md` +- `docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md` +- `docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md` diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md index c568ada..e10fdc8 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -263,7 +263,7 @@ repo. | Feature | Status | Primary authority | Notes | |---|---|---|---| -| Public `hypertwist.app` marketing shell | Implemented now | first-party `website/` app + feature registry/roadmap authority | HyperTwist now has a dedicated first-party public web surface for homepage, about, resources, pricing, download, support, and legal routes. This lane is separate from the embedded Unreal browser runtime under `Content/Browser/` and does not claim browser-simulator parity. The same package now also carries a first-party external runtime-readiness verifier so deploy-time env and live health posture can be checked outside the dashboard, plus separated local-versus-production env templates whose placeholder values are intentionally rejected until real launch config is in place, bootstrap CI now validates both the frontend and auth-server website commands directly, and the auth server can now auto-serve the built `website/dist` bundle with bounded SPA fallback for same-origin public deployment. Request-level server coverage now also proves that public/app shell delivery does not shadow `/api/*`, `/auth*`, `/health`, or missing asset paths, while the pricing/download/notices routes now surface first-party preview-versus-launch posture from the same bounded launch checklist instead of relying on hidden operator-only status. The live website lane now also owns route-aware title/description/canonical/Open-Graph/Twitter metadata for the real `hypertwist.app` marketing surface so deployed public pages no longer remain on a single generic SPA title/description, plus first-party `robots.txt` and `sitemap.xml` assets for the public route set while keeping `/app`, `/login`, and `/register` out of crawler posture. The real `check-runtime-readiness` CLI is now also exercised against the checked-in production example env files, and a spawned `website/server` bootstrap proof now verifies the live same-origin process path from production-shaped env into `/health`, `/api/auth/health`, built-shell serving, and the public anonymous release-manifest posture for the shared desktop release lane. The same verifier now also probes the deployed root-shell marker and can explicitly fail when the public origin is still serving the older placeholder rollout page instead of the first-party website/auth-server lane. | +| Public `hypertwist.app` marketing shell | Implemented now | first-party `website/` app + feature registry/roadmap authority | HyperTwist now has a dedicated first-party public web surface for homepage, about, resources, pricing, download, support, and legal routes. This lane is separate from the embedded Unreal browser runtime under `Content/Browser/` and does not claim browser-simulator parity. The same package now also carries a first-party external runtime-readiness verifier so deploy-time env and live health posture can be checked outside the dashboard, plus separated local-versus-production env templates whose placeholder values are intentionally rejected until real launch config is in place, bootstrap CI now validates both the frontend and auth-server website commands directly, and the auth server can now auto-serve the built `website/dist` bundle with bounded SPA fallback for same-origin public deployment. Request-level server coverage now also proves that public/app shell delivery does not shadow `/api/*`, `/auth*`, `/health`, or missing asset paths, while the pricing/download/notices routes now surface first-party preview-versus-launch posture from the same bounded launch checklist instead of relying on hidden operator-only status. The live website lane now also owns route-aware title/description/canonical/Open-Graph/Twitter metadata for the real `hypertwist.app` marketing surface so deployed public pages no longer remain on a single generic SPA title/description, plus first-party `robots.txt` and `sitemap.xml` assets for the public route set while keeping `/app`, `/login`, and `/register` out of crawler posture. The real `check-runtime-readiness` CLI is now also exercised against the checked-in production example env files, and a spawned `website/server` bootstrap proof now verifies the live same-origin process path from production-shaped env into `/health`, `/api/auth/health`, built-shell serving, and the public anonymous release-manifest posture for the shared desktop release lane. The same verifier now also probes the deployed root-shell marker and can explicitly fail when the public origin is still serving the older placeholder rollout page instead of the first-party website/auth-server lane, while the repo now also carries first-party `website/deploy/` `nginx` plus `systemd` handoff templates and a concrete same-origin public-host cutover guide. | | Browser-based operator/account dashboard | Implemented now | first-party `website/` app + shared auth/dashboard packet | A protected browser dashboard is now live for operator access, account state, download posture, browser-access boundary explanation, notices review, and bounded billing/entitlement status. It reuses the shared SuperTokens auth posture proven in FamiliarOS and ScriptoriumAI while remaining HyperTwist-specific in product content and boundary claims, the current auth-health surface now truthfully distinguishes configured versus reachable or ready shared-core posture while exposing fallback-active reason instead of hardcoding readiness, and the same dashboard now also surfaces launch-readiness truth for download URLs, checkout links, source/notices URLs, billing-secret/map configuration, and local-versus-public runtime deployment posture. Focused frontend coverage now also protects deep-link login redirect preservation, safe `next`-path normalization across auth entry points, fallback/email auth-bootstrap normalization, login/register continuation behavior, public download-gating behavior, protected-route/shell behavior, real lazy-route tree behavior for key public and protected paths, top-level app-bootstrap and SuperTokens-wrapper posture, login/register unhappy-path and OAuth-button behavior, support-topic fallback routing when live checkout is not configured, desktop-link verify-url/dashboard readiness behavior, and explicit `noindex,nofollow` posture on protected/auth browser surfaces. The validation lane now also has a bounded signed test-session harness under `TEST_MODE=testing` that proves `/api/auth/me` and `/api/auth/desktop-link` behavior through the live spawned auth-server process without widening production auth posture. | | Desktop download posture and browser-to-desktop pairing | Implemented now | first-party `website/` app + `website/server` desktop-link endpoints | Public download targets, dashboard-side release posture, and short-lived desktop-link token generation/verification are now first-party owned. The current server posture now enforces exact website-origin matching, bounded per-user issuance, one-time token consumption, and billing-backed plan/download entitlement resolution with focused `website/server` tests green on `2026-06-22`, and the verify handshake now returns the same resolved download-entitlement posture the dashboard sees instead of only identity plus plan/role. The same lane now also owns a shared `GET /api/releases/manifest` runtime authority for release version/channel/build/published/file-size/checksum/docs/source metadata, with anonymous callers intentionally denied raw download URLs while entitled session-backed callers receive the configured direct platform URL. The public `/download` page now keeps raw download URLs behind the protected dashboard instead of exposing them directly, preserves requested platform continuity through `/app/downloads?platform=...`, and surfaces that requested target again after auth handoff inside the protected release lane. Both the public and protected download surfaces now also carry first-party rollout steps plus release/notices/source references so the desktop setup lane is more than a generic link bucket, and the dashboard plus public launch-status callouts now consume the same manifest-backed Windows download truth instead of only static frontend config. Actual release URLs remain deployment configuration rather than hardcoded product truth. | | Paddle-ready pricing and billing webhook seam | Implemented now | first-party `website/` app + `website/server` billing endpoint | The public pricing surface now exists with plan structure, checkout-link configuration seams, and the same `/api/billing/paddle/webhook` endpoint family used by the broader product website lane. The current server now verifies `Paddle-Signature` against `PADDLE_WEBHOOK_SECRET` using the documented raw-body HMAC flow, persists a bounded first-party billing state file, and applies verified Paddle events into account/download entitlement state that the browser dashboard consumes, with focused `website/server` tests green on `2026-06-22`. A spawned live-process proof now also verifies that a real signed webhook updates processed-event health and persisted billing state through the actual auth-server runtime, not only helper-level store tests, and transaction events no longer leak their id into stored `subscriptionId` state. Production checkout URLs, secret management, and broader operator/admin billing workflows remain deployment/application tasks, not shipped-code omissions. | diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md index e20ede9..4e0a3e8 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md @@ -258,6 +258,11 @@ Current consolidated milestone snapshot: instead of leaving it implicit, and request-level server coverage now proves that public/app routes stay served without shadowing `/api/*`, `/auth*`, or `/health`, + and the repo now also carries first-party same-origin `nginx` plus `systemd` + handoff templates under `website/deploy/` with a concrete public-host cutover + guide in + `C:\HyperTwist\docs\ops\HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md` + so the remaining live-host gap is no longer an undocumented operator step, and the live public website lane now also owns route-aware title/description/canonical/Open-Graph/Twitter metadata for the real `hypertwist.app` marketing surface while marking protected/auth routes as diff --git a/website/README.md b/website/README.md index 02892d6..c4ae38c 100644 --- a/website/README.md +++ b/website/README.md @@ -102,6 +102,7 @@ Relevant server env keys now include: - frontend app: `website/src/` - auth server: `website/server/` +- deployment templates: `website/deploy/` - embedded Unreal browser runtime: `Content/Browser/` - HyperTwist feature authority: `docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md` - HyperTwist roadmap authority: `docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md` @@ -131,6 +132,8 @@ Use the runtime-readiness command before public launch or deployment approval: - it now fails explicitly when the live origin is still serving the placeholder rollout page instead of the first-party website/auth-server lane - the auth server can now also serve the built `website/dist` bundle directly for same-origin `hypertwist.app` deployment when that build output is present +- the repo now also includes first-party same-origin `nginx` and `systemd` + handoff templates under `website/deploy/` - it now warns when same-origin public deployment leaves static website serving mode ambiguous - request-level server tests now also pin that same-origin shell behavior instead of relying only on helper-level assertions - the public pricing/download/notices pages now also surface preview-versus-launch posture directly from the same bounded launch checklist @@ -156,3 +159,7 @@ The focused frontend test coverage now also pins: - dashboard launch-readiness plus desktop-link verify-url behavior - route-aware metadata behavior for public versus protected surfaces plus richer download-lane guidance on both the public and protected release pages - spawned `website/server` bootstrap proof from production-shaped same-origin env into live `/health`, `/api/auth/health`, static public/app shell delivery, verified webhook reflection into billing state, and bounded session-backed `/api/auth/me` plus `/api/auth/desktop-link` behavior under `TEST_MODE=testing` + +Canonical same-origin cutover guide: + +- `docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md` diff --git a/website/deploy/README.md b/website/deploy/README.md new file mode 100644 index 0000000..0d02fb6 --- /dev/null +++ b/website/deploy/README.md @@ -0,0 +1,29 @@ +# HyperTwist Website Deployment Templates + +This folder contains first-party same-origin deployment templates for the +public `hypertwist.app` website plus auth-server lane. + +Files: + +- `nginx/hypertwist.app.conf.example` +- `systemd/hypertwist-website-auth-server.service.example` + +Expected deployment posture: + +- NGINX terminates TLS for `hypertwist.app` +- NGINX reverse-proxies the full public origin to the local + `website/server` Express process +- the Express process serves both the built `website/dist` bundle and the + `/api/*` plus `/auth*` route families on the same origin + +Before using these templates: + +- replace filesystem paths to match the real VPS checkout location +- replace service-user/group values if the process does not run as + `hypertwist` +- fill real production values into `website/.env` and `website/server/.env` +- build the frontend bundle with `npm run build` in `website/` + +Canonical operator guide: + +- `docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md` diff --git a/website/deploy/nginx/hypertwist.app.conf.example b/website/deploy/nginx/hypertwist.app.conf.example new file mode 100644 index 0000000..84c2e15 --- /dev/null +++ b/website/deploy/nginx/hypertwist.app.conf.example @@ -0,0 +1,45 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +upstream hypertwist_website_auth_server { + server 127.0.0.1:3001; + keepalive 32; +} + +server { + listen 80; + listen [::]:80; + server_name hypertwist.app www.hypertwist.app; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name hypertwist.app www.hypertwist.app; + + ssl_certificate /etc/letsencrypt/live/hypertwist.app/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/hypertwist.app/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + client_max_body_size 10m; + + location / { + proxy_pass http://hypertwist_website_auth_server; + 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 https; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port 443; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_read_timeout 60s; + proxy_send_timeout 60s; + } +} diff --git a/website/deploy/systemd/hypertwist-website-auth-server.service.example b/website/deploy/systemd/hypertwist-website-auth-server.service.example new file mode 100644 index 0000000..225eb0c --- /dev/null +++ b/website/deploy/systemd/hypertwist-website-auth-server.service.example @@ -0,0 +1,22 @@ +[Unit] +Description=HyperTwist same-origin website and auth server +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=hypertwist +Group=hypertwist +WorkingDirectory=/srv/hypertwist/current/website/server +Environment=NODE_ENV=production +EnvironmentFile=/srv/hypertwist/current/website/server/.env +ExecStart=/usr/bin/npm start +Restart=always +RestartSec=5 +TimeoutStopSec=20 +KillSignal=SIGTERM +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target diff --git a/website/server/README.md b/website/server/README.md index 3e6ed5a..4610b72 100644 --- a/website/server/README.md +++ b/website/server/README.md @@ -86,6 +86,7 @@ The server now also supports a bounded first-party same-origin deployment mode: - request-level tests now also prove that public/app routes serve the shell while `/api/*`, `/auth*`, `/health`, and missing asset paths remain unshadowed - a spawned bootstrap test now also proves the real `src/index.ts` process can start from production-shaped same-origin env, reach a ready SuperTokens core, expose green `/api/auth/health`, serve the built shell, accept a verified webhook, and reflect that processed billing event through live health plus the persisted entitlement file - the same spawned proof lane now also exercises `/api/auth/me` and `/api/auth/desktop-link` through a bounded signed test-session harness that is only active when `TEST_MODE=testing` and `HYPERTWIST_TEST_SESSION_SECRET` are explicitly set; this is validation-only, not a production auth widening +- the repo now also ships first-party `systemd` plus `nginx` handoff templates under `website/deploy/` for that same-origin public lane The website package now also ships a deploy-time verification command: @@ -149,6 +150,10 @@ That means the verifier can now fail explicitly when `hypertwist.app` is still serving the earlier placeholder rollout page instead of the real same-origin website/auth-server deployment. +Canonical deployment handoff: + +- `docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md` + The repo bootstrap CI now also validates this auth-server lane through: - `npm ci`