Files
Gnuboard7/tests/scenarios/bootstrap-parse-failure.yaml
T
HeuJung b6c5e1f323 feat(core): 리버스 프록시 신뢰 설정 지원 및 미설정 진단
TLS 가 앞단에서 종단되고 앱에는 HTTP 로 전달되는 구성에서 X-Forwarded-* 가 전부
무시되어 화면 백지·IP 왜곡·webhook 403 이 함께 발생했다. 코어에 신뢰 프록시 설정
지점이 아예 없던 것이 원인이다.

- config/trustedproxy.php 로 내장 TrustProxies 미들웨어에 값을 공급한다.
 bootstrap/app.php 는 건드리지 않는다 — withMiddleware 클로저는 .env 로드 전에
 평가되어 env 가 항상 null 이 되는 조용한 no-op 이다.
- 판정은 App\Support\TrustedProxyDiagnostic 단일 SSoT 에서 계산하고 대시보드
 알림·환경설정 고급 탭·설치 마법사·trusted-proxy:status 네 면이 소비한다.
 판정식은 "HTTPS 인식 실패" 가 아니라 "X-Forwarded-* 수신 중 AND 신뢰 프록시
 미설정" 이다 — HTTP 전용 사이트가 프록시 뒤에 있으면 화면은 정상인 채로
 나머지만 조용히 어긋나기 때문이다.
- 값 편집 UI 와 쓰기 엔드포인트는 두지 않는다(잠금 역설 + XFF 위조 경로).
- 혼합 콘텐츠 차단을 부트스트랩 폴백의 별도 사유로 가른다. 새로고침으로 낫지
 않으므로 버튼을 렌더하지 않고, 원인·조치는 콘솔로 운영자에게 보낸다.
- 대시보드 알림을 심각도로 배치한다 — warning 은 상단 배너, 그 외는 하단 카드.
 같은 알림이 두 곳에 뜨지 않으며, 여러 건은 간격을 두고 쌓인다.

공개 이슈: (@lyg-kaban 제보)
2026-08-28 18:09:27 +09:00

64 lines
3.7 KiB
YAML

feature: bootstrap_parse_failure
description: |
부팅 스크립트 실패 사유별 안내 분기 (공개 #121).
번들을 **받았는데 실행되지 않는** 경우와 **끝내 받지 못한** 경우는 사용자가 취해야 할
행동이 정반대다. 파싱 실패 시 스크립트 태그는 error 가 아니라 load 를 발생시키므로
재시도조차 일어나지 않고 곧장 "전역 부재" 경로로 간다 — 종전에는 그 경로가 네트워크
문구를 그대로 그려, 새로고침해도 낫지 않는 상황에서 새로고침을 권했다.
핵심 동작:
- window 의 error 이벤트로 번들 SyntaxError 를 관측(element 이벤트로는 구분 불가)
- 관측되면 renderFallback('incompatible') — 전용 문구 + 새로고침 버튼 생략
- 관측되지 않으면 renderFallback('corrupt') — 기존 문구 유지(사유 미상)
- 재시도 소진 경로는 두 갈래다 — HTTPS 페이지가 http:// 자산을 요청해 브라우저가
차단한 경우는 renderFallback('blocked'), 그 외는 renderFallback('network')
- 'blocked' 는 회선이 멀쩡하고 새로고침으로도 낫지 않으므로 버튼을 렌더하지 않고,
화면 문구는 방문자 기준(서버 설정 지시 없음) · 원인과 조치는 콘솔에 운영자 기준
- 코어 엔진 번들에서 정규식 lookbehind 제거(파싱 하한 Safari 16.4 → 14.1)
axes:
entrypoint: [user, admin]
failure_mode: [parse_error, network_exhausted, mixed_content_blocked, none]
effects:
- syntax_error_renders_incompatible_notice
- incompatible_notice_omits_reload_button
- network_failure_renders_network_notice
- network_notice_keeps_reload_button
- blocked_branch_is_emitted_with_https_http_judgment
- mixed_content_blocked_renders_blocked_notice
- blocked_notice_omits_reload_button
- blocked_notice_splits_visitor_screen_and_operator_console
- normal_boot_renders_no_fallback
- shipped_core_bundle_has_no_lookbehind
- bootstrap_partial_emits_reason_branch
- incompatible_strings_defined_per_locale
- core_source_has_no_lookbehind
- variable_extraction_contract_unchanged
test_files:
- tests/Playwright/specs/smoke/bootstrap-parse-failure.spec.ts
- tests/Feature/View/BootstrapFallbackDiagnosisTest.php
- resources/js/core/template-engine/__tests__/DataBindingEngine.test.ts
notes: |
`blocked` 축(공개 #124)은 프록시 없이 재현한다 — 문서 HTML 의 코어 스크립트 URL 만
`http://` 로 바꾸면 브라우저가 혼합 콘텐츠로 차단하므로, 인증서도 TLS 종단 프록시도
필요 없다. 다만 판정이 `location.protocol === 'https:'` 를 보므로, E2E 의 기대값은
실행 시점 base URL 의 스킴에서 파생된다(http base 에서는 `network` 가 정답이다).
분기 자체의 방출과 문구·대상 분리는 BootstrapFallbackDiagnosisTest 가 스킴과 무관하게
단언한다.
로케일 축은 E2E cross product 에 넣지 않는다 — 화면 문구는 서버가 렌더한 문자열을
그대로 심는 구조라 브라우저 경로가 로케일마다 갈리지 않기 때문이다. ko/en/ja 문구의
실존과 상호 구분은 BootstrapFallbackDiagnosisTest 가 직접 단언하고, 번들 ja 언어팩의
키 동기는 언어팩 동기 검사가 담당한다.
하한 미만 실기기(iOS 15) 에서 "깨진 채로 이용 가능한가" 는 재현 수단이 없어 이 매니페스트
범위 밖이다 — 최신 WebKit(Playwright) 도 lookbehind 를 지원해 결함 자체가 재현되지 않는다.
배포 번들에 lookbehind 등 파싱 하한 초과 문법이 재유입되는 회귀는 위 테스트와 별개로
저장소의 정적 검사가 차단한다 (이 매니페스트의 검증 범위 밖).