| .. | ||
| src | ||
| .env.example | ||
| .env.preview.example | ||
| .env.production.example | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
HyperTwist Auth Server
Self-hosted SuperTokens auth backend for the HyperTwist website.
Responsibilities:
- email/password sign-up and sign-in
- optional GitHub and Google OAuth
- session bootstrap for the browser dashboard
- browser-to-desktop token handoff with exact-origin checks, bounded issuance, and one-time verification tokens
- server-backed release-manifest authority for public/protected desktop distribution surfaces
- Paddle webhook endpoint with raw-body signature verification
- verified billing-event application into first-party account/download entitlement state
- public auth-health probe for the website with configured vs reachable core truth
- runtime configuration diagnostics for local vs mixed vs public auth posture
Quick start
cd /home/dev/src/HyperTwist/website/server
npm install
cp .env.example .env
npm run dev
The website frontend should point at this backend through:
VITE_SUPERTOKENS_API_DOMAIN=http://localhost:3001
VITE_SUPERTOKENS_WEBSITE_DOMAIN=http://localhost:4273
VITE_AUTH_API_BASE_URL=http://localhost:3001
Important note
/api/billing/paddle/webhook now verifies the Paddle-Signature header
against PADDLE_WEBHOOK_SECRET using the documented raw-body ts:h1
HMAC-SHA256 flow before it accepts the event.
The desktop-link lane is intentionally stricter than a generic session helper:
- request origin must match the configured website origin exactly
- token issuance is rate-limited per user
- verification consumes the token on first successful use
- verification now returns resolved download-entitlement posture alongside identity, plan, and role
The remaining Paddle deployment work is now configuration, not missing server ownership:
- real production checkout URLs
- live notification-destination secret management
- event-specific async processing after verification
The server now also supports a small first-party entitlement store:
BILLING_STATE_PATHoptionally relocates the persisted billing state filePADDLE_PRODUCT_PLAN_MAPcan map Paddle product IDs tofree/operator/studio/enterprisePADDLE_PRICE_PLAN_MAPcan map Paddle price IDs to the same plan codes- if neither map is present, the verified webhook lane can still derive plan from
custom_data.plan
The auth-health route now probes the configured SuperTokens core non-mutatively:
SUPERTOKENS_HEALTH_TIMEOUT_MSbounds the probe duration/api/auth/healthnow distinguishes configured, reachable, and ready state- the protected dashboard can now show when browser fallback posture is active because the shared auth core is unreachable
Recommended public hypertwist.app posture:
API_DOMAIN=https://hypertwist.appWEBSITE_DOMAIN=https://hypertwist.appPORT=3011on the current shared VPS so the lane does not collide with the existing FamiliarOS auth server on3001COOKIE_SECURE=true- real
PADDLE_WEBHOOK_SECRET - real plan-map configuration or equivalent verified-event plan resolution
That recommended same-origin production posture is recorded in:
docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md
The server now also supports a bounded first-party same-origin deployment mode:
- if
website/dist/index.htmlexists, the server auto-serves the built public site from../dist - SPA fallback is limited to non-file public/app routes and does not intercept
/api/*,/auth*, or/health WEBSITE_DIST_PATHcan override the bundle location when deployment layout differsSERVE_STATIC_WEBSITE=trueforces the server to expect a built bundle, whileSERVE_STATIC_WEBSITE=falsekeeps api-only mode explicit- the example env files now carry those static-serving controls directly so deployment posture is not implicit
- 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.tsprocess 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/meand/api/auth/desktop-linkthrough a bounded signed test-session harness that is only active whenTEST_MODE=testingandHYPERTWIST_TEST_SESSION_SECRETare explicitly set; this is validation-only, not a production auth widening - the repo now also ships first-party
systemdplusnginxhandoff templates underwebsite/deploy/for that same-origin public lane - the website package now also includes
npm run render:same-origin-deploymentso operators can emit resolvedsystemdandnginxfiles from real checkout paths instead of editing the examples by hand - the website package now also includes
npm run render:same-origin-bundleso one manifest file can own the public origin and emit validated frontend env, server env,systemd, andnginxoutputs together before installation - the website package now also includes
npm run run:vps-same-origin-staging-proofso the same bundle manifest can be exercised through a temporary VPS checkout on the real shared host before root-owned service/vhost cutover - the same bundle/readiness lane now distinguishes
launchfrompreviewposture, so non-public same-origin rehearsal may keep runtime modemixedwith the loopback SuperTokens warning and an emptyPADDLE_WEBHOOK_SECRETwhile public launch still requires real checkout/download/webhook values - the staging-proof helper now also supports
--archive-source worktreewhen operators need real host proof for the exact in-progress packet before commit - the same package now also ships
npm run run:vps-same-origin-live-deployfor the bounded root-owned checkout/env/build/systemd/nginx replacement flow that was used to cuthttps://hypertwist.appover to the first-party same-origin preview lane and then re-proved idempotently
The website package now also ships a deploy-time verification command:
cd /home/dev/src/HyperTwist/website
npm run check:runtime-readiness -- --frontend-env .env --server-env server/.env --health-url https://hypertwist.app
Use --skip-live-health when only file-level env verification is possible.
Keep the example env files separated by posture:
website/.env.exampleandwebsite/server/.env.exampleremain local-development defaultswebsite/.env.production.exampleandwebsite/server/.env.production.exampleare public-posture scaffolds that still intentionally fail readiness until placeholder values are replaced
The repo now also proves that behavior directly by running the real
check-runtime-readiness CLI against those production example files in test
mode and asserting that placeholder launch values still fail.
Release-manifest authority
The auth server now exposes:
GET /api/releases/manifest
This route is the shared runtime authority for desktop release metadata across the public website and the protected dashboard download lane.
Behavior:
- anonymous viewers receive release metadata without raw download URLs
- entitled session-backed viewers receive the same metadata plus the configured direct download URL for each allowed platform
- the payload also carries top-level support/docs/release-notes/corresponding-source/open-source-repo references so marketing and operator surfaces stay aligned
- the payload now also carries public commerce config for operator/studio checkout URLs plus live plan-price strings so public pricing and protected launch-readiness surfaces can read runtime checkout posture from the server
- the Windows platform entry now also carries first-party packaged-validation summary truth from the current higher-dimensional desktop lane, separate from whether a launch download URL has been configured yet
Primary server env inputs for this route:
RELEASE_MANIFEST_VERSIONRELEASE_MANIFEST_CHANNELSUPPORT_EMAILPUBLIC_DOCS_URLRELEASE_NOTES_URLMPL_SOURCE_URLOPEN_SOURCE_REPO_URLWINDOWS_*,MACOS_*, andLINUX_*release fields for url/version/channel/build/published-at/file-name/file-size/checksum
Compatibility note:
- the manifest still falls back to legacy
VITE_*download/source keys when the server-specific release env is not yet populated, so the new route can be adopted without breaking earlier preview scaffolds
The same deployment lane is now also probed by the runtime-readiness command through three live surfaces at the same public origin:
GET /api/auth/healthGET /api/releases/manifestGET /for the first-party shell marker
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.
The same verifier now also compares the live anonymous release-manifest payload against the currently configured launch authority for support/docs/source, checkout/price, and per-platform release metadata, so a stale host env or partially rolled deploy fails as configuration drift instead of passing on structural safety alone.
Live same-origin status on 2026-06-22:
- the root-owned cutover now has
https://hypertwist.appserving the first-party website/auth-server lane from the shared VPS - live
/health,/api/auth/health,/api/releases/manifest, and root-shell verification are green in preview posture - the remaining live gap is launch-tier checkout/download/webhook completion, not website-host cutover
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 cinpm run type-checknpm test