#!/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