hypertwist/scripts/run-hypertwist-web-surface-validation.sh
2026-06-30 05:27:38 +00:00

198 lines
6.6 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
strict_auth_server_audit=0
skip_audits=0
with_responsive_e2e=0
usage() {
cat <<'EOF'
Usage:
scripts/run-hypertwist-web-surface-validation.sh [--strict-auth-server-audit] [--skip-audits] [--with-responsive-e2e]
Runs the current first-party HyperTwist web-surface validation packet:
- website type-check, focused tests, and production build
- website/server type-check and full test suite
- Content/Browser shell verification and production build
- production dependency audits for website, website/server, and Content/Browser
Current auth-server nuance:
the default mode accepts the known upstream `supertokens-node -> nodemailer`
production advisory as a documented residual warning. Pass
`--strict-auth-server-audit` to fail on that residual too.
Optional responsive-browser hardening:
`--with-responsive-e2e` also runs the bounded Playwright public-route and
protected-route responsiveness packets for homepage, about, resources,
pricing, download, support, register, `/app`, `/app/launch-status`,
`/app/downloads`, `/app/browser-access`, `/app/account`, and
`/app/notices`. This expects Playwright browser prerequisites to be
available on the host.
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--strict-auth-server-audit)
strict_auth_server_audit=1
;;
--skip-audits)
skip_audits=1
;;
--with-responsive-e2e)
with_responsive_e2e=1
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 1
;;
esac
shift
done
run_step() {
local description="$1"
shift
printf '\n[%s] %s\n' "$(date -u '+%H:%M:%S')" "$description"
(
cd "$repo_root"
"$@"
)
}
run_clean_prod_audit() {
local workdir="$1"
local label="$2"
printf '\n[%s] %s production audit\n' "$(date -u '+%H:%M:%S')" "$label"
(
cd "$workdir"
npm audit --omit=dev --audit-level=high
)
}
run_auth_server_audit() {
local workdir="$repo_root/website/server"
local audit_json
printf '\n[%s] website/server production audit\n' "$(date -u '+%H:%M:%S')"
audit_json="$(
cd "$workdir"
npm audit --omit=dev --json || true
)"
if [[ -z "$audit_json" ]]; then
echo "website/server audit returned no output." >&2
return 1
fi
AUDIT_JSON="$audit_json" STRICT_AUTH_SERVER_AUDIT="$strict_auth_server_audit" node <<'EOF'
const report = JSON.parse(process.env.AUDIT_JSON || '{}')
const strict = process.env.STRICT_AUTH_SERVER_AUDIT === '1'
const vulnerabilities = report.vulnerabilities || {}
const metadata = report.metadata?.vulnerabilities || {}
const total = Number(metadata.total || 0)
if (total === 0) {
console.log('website/server production audit is clean.')
process.exit(0)
}
const keys = Object.keys(vulnerabilities).sort()
const expectedKeys = ['nodemailer', 'supertokens-node']
const nodemailer = vulnerabilities.nodemailer
const supertokens = vulnerabilities['supertokens-node']
const matchesKnownResidual =
metadata.info === 0 &&
metadata.low === 0 &&
metadata.moderate === 0 &&
metadata.high === 2 &&
metadata.critical === 0 &&
keys.length === expectedKeys.length &&
expectedKeys.every((key, index) => keys[index] === key) &&
nodemailer?.name === 'nodemailer' &&
nodemailer?.severity === 'high' &&
Array.isArray(nodemailer?.effects) &&
nodemailer.effects.length === 1 &&
nodemailer.effects[0] === 'supertokens-node' &&
Array.isArray(nodemailer?.nodes) &&
nodemailer.nodes.length === 1 &&
nodemailer.nodes[0] === 'node_modules/nodemailer' &&
supertokens?.name === 'supertokens-node' &&
supertokens?.severity === 'high' &&
Array.isArray(supertokens?.via) &&
supertokens.via.length === 1 &&
supertokens.via[0] === 'nodemailer'
if (matchesKnownResidual && !strict) {
console.log(
'website/server production audit retains the documented upstream residual advisory: supertokens-node -> nodemailer.',
)
process.exit(0)
}
console.error('website/server production audit found unexpected or strict-mode-blocking vulnerabilities.')
console.error(JSON.stringify(report, null, 2))
process.exit(1)
EOF
}
run_step "website type-check" npm --prefix website run type-check
run_step \
"higher-dimensional packaged-validation summary freshness" \
node scripts/render-hypertwist-web-package-validation-summary.mjs --check
run_step \
"website focused route/auth/release validation" \
npm --prefix website test -- --run \
src/__tests__/package-validation.test.ts \
src/__tests__/platform-auth.bootstrap.test.tsx \
src/__tests__/download-center-page.test.tsx \
src/__tests__/public-launch.test.ts \
src/__tests__/protected-app-pages.test.tsx \
src/__tests__/DashboardOverviewPage.test.tsx \
src/__tests__/app-route-tree.test.tsx \
src/__tests__/public-route-registry.test.ts \
src/__tests__/route-shells.test.tsx \
src/__tests__/release-manifest.test.ts \
src/__tests__/supertokens-client.test.ts \
src/__tests__/public-marketing-pages.test.tsx \
src/__tests__/public-auth-pages.test.tsx
run_step \
"website deployment/readiness tooling validation" \
npm --prefix website test -- --run \
scripts/render-public-search-assets-lib.test.mjs \
scripts/runtime-readiness-lib.test.mjs \
scripts/runtime-readiness-cli.test.mjs \
scripts/render-same-origin-bundle-lib.test.mjs
run_step "website production build" npm --prefix website run build
if [[ "$with_responsive_e2e" -eq 1 ]]; then
run_step \
"website responsive public-route Playwright proof" \
npm --prefix website run test:e2e:responsive
run_step \
"website responsive protected-route Playwright proof" \
npm --prefix website run test:e2e:protected-responsive
fi
run_step "website/server type-check" npm --prefix website/server run type-check
run_step "website/server test suite" npm --prefix website/server test -- --run
run_step "Content/Browser shell verification" npm --prefix Content/Browser run verify:shell
run_step "Content/Browser production build" npm --prefix Content/Browser run build
if [[ "$skip_audits" -eq 0 ]]; then
run_clean_prod_audit "$repo_root/website" "website"
run_auth_server_audit
run_clean_prod_audit "$repo_root/Content/Browser" "Content/Browser"
else
printf '\n[%s] Skipping production audits by request.\n' "$(date -u '+%H:%M:%S')"
fi
printf '\n[%s] HyperTwist web-surface validation completed successfully.\n' "$(date -u '+%H:%M:%S')"
if [[ "$skip_audits" -eq 0 && "$strict_auth_server_audit" -eq 0 ]]; then
echo "Auth-server note: known upstream supertokens-node -> nodemailer residual is accepted in default mode until upstream-compatible remediation exists."
fi