#!/usr/bin/env bash # Fails the build if a production bundle contains anything that should only # ever exist server-side. # # It also fails on mock gateway code, for the same reason in a different # register: a production build that can reach a *LocalGateway is a production # build that can serve seeded fixtures as if they were real data. Those used to # ship - a fixture string from partner-hierarchy-local.gateway.ts was present in # a production bundle on 2026-08-21 - because naming both classes in a token # factory kept both reachable no matter what the flag said. # # Why this exists: the storefront used to send provider payment credentials # from the browser - an `authorization-key` header, a `userid-value` header, # and a hardcoded partner ID literal compiled into the bundle. That code is # gone (FH-1.3), and this check is what stops it coming back. A credential in # a JS bundle is not a leak you can revoke quietly; it is published. # # Usage: # npm run build && scripts/ci/scan-bundle.sh [dist-dir] set -euo pipefail DIST="${1:-dist}" if [[ ! -d "$DIST" ]]; then echo "scan-bundle: '$DIST' does not exist - build first" >&2 exit 2 fi # Each entry is "label|extended-regex". Keep patterns specific: a pattern that # fires on ordinary code trains people to ignore this check. PATTERNS=( "provider auth header|authorization-key" "provider user header|userid-value" "hardcoded partner id|web-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" "oauth client secret|client_secret[\"']?[[:space:]]*[:=]" "private key block|BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY" "aws access key|AKIA[0-9A-Z]{16}" "telegram bot token|[0-9]{8,10}:AA[0-9A-Za-z_-]{33}" "mock gateway class|[A-Za-z]+LocalGateway" "mock gateway fixture|ptr_local|customer_vk_mock" ) failed=0 for entry in "${PATTERNS[@]}"; do label="${entry%%|*}" pattern="${entry#*|}" if matches="$(grep -rIlE "$pattern" "$DIST" 2>/dev/null)"; then if [[ -n "$matches" ]]; then echo "FAIL: $label found in the built bundle" >&2 echo "$matches" | sed 's/^/ /' >&2 failed=1 fi fi done if [[ $failed -ne 0 ]]; then echo >&2 echo "Something reached the browser bundle that should not have." >&2 echo "Credentials belong behind the API; mock gateways belong in dev-only" >&2 echo "providers swapped out by angular.json fileReplacements." >&2 exit 1 fi echo "scan-bundle: clean ($DIST)"