Clarify website static serving deployment posture
This commit is contained in:
parent
34e973b4eb
commit
efcddb67f0
9 changed files with 58 additions and 1 deletions
|
|
@ -160,6 +160,7 @@ for `hypertwist.app` when a built `website/dist/index.html` is present:
|
|||
- static delivery auto-enables from `website/server -> ../dist`
|
||||
- SPA fallback remains limited to public/app routes and excludes `/api/*`, `/auth*`, and `/health`
|
||||
- `WEBSITE_DIST_PATH` and `SERVE_STATIC_WEBSITE` now expose explicit deployment control for that lane
|
||||
- the runtime-readiness verifier now warns when same-origin public posture leaves that static-serving mode implicit
|
||||
|
||||
This is browser-based user access for the operator/account surface.
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ Recommended server env posture:
|
|||
- `API_BASE_PATH=/auth`
|
||||
- `WEBSITE_BASE_PATH=/auth`
|
||||
- `COOKIE_SECURE=true`
|
||||
- `SERVE_STATIC_WEBSITE=true` when the auth server owns same-origin public delivery
|
||||
- real `PADDLE_WEBHOOK_SECRET`
|
||||
- real `PADDLE_PRODUCT_PLAN_MAP` and/or `PADDLE_PRICE_PLAN_MAP`
|
||||
|
||||
|
|
@ -52,6 +53,8 @@ The repo now carries two distinct env-template families:
|
|||
|
||||
The production examples intentionally include `replace-me` placeholder values so
|
||||
the readiness command still fails until real launch values are inserted.
|
||||
They now also carry the explicit static-serving control variables for the
|
||||
same-origin lane.
|
||||
|
||||
## Why same-origin is the clean default
|
||||
|
||||
|
|
@ -73,6 +76,7 @@ when a built website bundle exists:
|
|||
- override with `WEBSITE_DIST_PATH` when deployment layout differs
|
||||
- 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
|
||||
|
||||
## If a split-host auth topology is chosen later
|
||||
|
||||
|
|
|
|||
|
|
@ -223,7 +223,9 @@ Current consolidated milestone snapshot:
|
|||
auth-bootstrap normalization, and dashboard launch-readiness plus desktop-link
|
||||
verify-url behavior, and the auth server can now auto-serve the built
|
||||
`website/dist` bundle with bounded SPA fallback for same-origin `hypertwist.app`
|
||||
deployment when that build output is present,
|
||||
deployment when that build output is present, while the env templates and
|
||||
runtime-readiness verifier now also make that static-serving posture explicit
|
||||
instead of leaving it implicit,
|
||||
persists a bounded first-party billing-state file, applies verified Paddle
|
||||
events into account/download entitlement state, and surfaces that resolved
|
||||
billing/download posture back through `/api/auth/me`, the protected browser
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ Use the runtime-readiness command before public launch or deployment approval:
|
|||
- it fails if required public launch values are still missing
|
||||
- it can optionally verify live `/api/auth/health` posture from the deployed site
|
||||
- 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
|
||||
- it now warns when same-origin public deployment leaves static website serving mode ambiguous
|
||||
|
||||
The repo bootstrap CI now also validates this lane through:
|
||||
|
||||
|
|
|
|||
|
|
@ -222,6 +222,24 @@ function evaluateServerConfig(serverEnv) {
|
|||
pushWarning(bucket, 'API_DOMAIN and WEBSITE_DOMAIN differ; same-origin public posture is the clean default.')
|
||||
}
|
||||
|
||||
const serveStaticWebsite = normalizeTrimmed(serverEnv.SERVE_STATIC_WEBSITE).toLowerCase()
|
||||
const websiteDistPath = normalizeTrimmed(serverEnv.WEBSITE_DIST_PATH) || '../dist'
|
||||
const sameOriginPublicPosture = Boolean(
|
||||
apiDomain
|
||||
&& websiteDomain
|
||||
&& apiDomain.origin === websiteDomain.origin
|
||||
&& !isLoopbackHostname(apiDomain.hostname)
|
||||
&& !isLoopbackHostname(websiteDomain.hostname),
|
||||
)
|
||||
|
||||
if (sameOriginPublicPosture) {
|
||||
if (serveStaticWebsite === 'false' || serveStaticWebsite === '0' || serveStaticWebsite === 'no') {
|
||||
pushWarning(bucket, 'SERVE_STATIC_WEBSITE=false; ensure a separate same-origin web server serves the built website bundle.')
|
||||
} else if (serveStaticWebsite !== 'true' && serveStaticWebsite !== '1' && serveStaticWebsite !== 'yes') {
|
||||
pushWarning(bucket, `SERVE_STATIC_WEBSITE is not explicitly set; confirm ${websiteDistPath} is present for first-party same-origin serving or that an external same-origin web server serves the frontend.`)
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
Boolean(normalizeTrimmed(serverEnv.GITHUB_CLIENT_ID))
|
||||
!== Boolean(normalizeTrimmed(serverEnv.GITHUB_CLIENT_SECRET))
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ describe('buildRuntimeReadinessReport', () => {
|
|||
WEBSITE_DOMAIN: 'https://hypertwist.app',
|
||||
SUPERTOKENS_CORE_URI: 'https://auth-core.internal',
|
||||
COOKIE_SECURE: 'true',
|
||||
SERVE_STATIC_WEBSITE: 'true',
|
||||
PADDLE_WEBHOOK_SECRET: 'secret',
|
||||
PADDLE_PRICE_PLAN_MAP: '{"pri_operator":"operator"}',
|
||||
},
|
||||
|
|
@ -65,6 +66,31 @@ describe('buildRuntimeReadinessReport', () => {
|
|||
expect(report.failures).toEqual([])
|
||||
})
|
||||
|
||||
it('warns when same-origin public posture leaves static website serving ambiguous', () => {
|
||||
const report = buildRuntimeReadinessReport({
|
||||
frontendEnv: {
|
||||
VITE_SUPERTOKENS_API_DOMAIN: 'https://hypertwist.app',
|
||||
VITE_SUPERTOKENS_WEBSITE_DOMAIN: 'https://hypertwist.app',
|
||||
VITE_AUTH_API_BASE_URL: 'https://hypertwist.app',
|
||||
VITE_WINDOWS_DOWNLOAD_URL: 'https://downloads.hypertwist.app/windows.exe',
|
||||
VITE_PADDLE_CHECKOUT_URL_OPERATOR: 'https://buy.paddle.com/operator',
|
||||
VITE_MPL_SOURCE_URL: 'https://hypertwist.app/open-source/source',
|
||||
VITE_OPEN_SOURCE_REPO_URL: 'https://git.scriptoriumai.io/scriptoriumadmin/hypertwist',
|
||||
},
|
||||
serverEnv: {
|
||||
API_DOMAIN: 'https://hypertwist.app',
|
||||
WEBSITE_DOMAIN: 'https://hypertwist.app',
|
||||
SUPERTOKENS_CORE_URI: 'https://auth-core.internal',
|
||||
COOKIE_SECURE: 'true',
|
||||
PADDLE_WEBHOOK_SECRET: 'secret',
|
||||
PADDLE_PRICE_PLAN_MAP: '{"pri_operator":"operator"}',
|
||||
},
|
||||
liveHealth: null,
|
||||
})
|
||||
|
||||
expect(report.warnings).toContain('SERVE_STATIC_WEBSITE is not explicitly set; confirm ../dist is present for first-party same-origin serving or that an external same-origin web server serves the frontend.')
|
||||
})
|
||||
|
||||
it('fails localhost-grade posture and missing public-launch configuration', () => {
|
||||
const report = buildRuntimeReadinessReport({
|
||||
frontendEnv: {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ WEBSITE_DOMAIN=http://localhost:4273
|
|||
API_BASE_PATH=/auth
|
||||
WEBSITE_BASE_PATH=/auth
|
||||
COOKIE_SECURE=false
|
||||
SERVE_STATIC_WEBSITE=false
|
||||
WEBSITE_DIST_PATH=
|
||||
GITHUB_CLIENT_ID=
|
||||
GITHUB_CLIENT_SECRET=
|
||||
GOOGLE_CLIENT_ID=
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ WEBSITE_DOMAIN=https://hypertwist.app
|
|||
API_BASE_PATH=/auth
|
||||
WEBSITE_BASE_PATH=/auth
|
||||
COOKIE_SECURE=true
|
||||
SERVE_STATIC_WEBSITE=true
|
||||
WEBSITE_DIST_PATH=
|
||||
GITHUB_CLIENT_ID=
|
||||
GITHUB_CLIENT_SECRET=
|
||||
GOOGLE_CLIENT_ID=
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ The server now also supports a bounded first-party same-origin deployment mode:
|
|||
- SPA fallback is limited to non-file public/app routes and does not intercept `/api/*`, `/auth*`, or `/health`
|
||||
- `WEBSITE_DIST_PATH` can override the bundle location when deployment layout differs
|
||||
- `SERVE_STATIC_WEBSITE=true` forces the server to expect a built bundle, while `SERVE_STATIC_WEBSITE=false` keeps api-only mode explicit
|
||||
- the example env files now carry those static-serving controls directly so deployment posture is not implicit
|
||||
|
||||
The website package now also ships a deploy-time verification command:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue