diff --git a/hub/internal/web/templates/app_detail.html b/hub/internal/web/templates/app_detail.html index 7cda896..7431c7b 100644 --- a/hub/internal/web/templates/app_detail.html +++ b/hub/internal/web/templates/app_detail.html @@ -6,6 +6,7 @@ {{.AppName}} — Felhom Hub + {{template "inline_confirm_js"}} {{template "icon_sprite"}} @@ -45,10 +46,9 @@

{{if .Summary}}{{if .Summary.DisplayName}}{{.Summary.DisplayName}}{{else}}{{.AppName}}{{end}}{{else}}{{.AppName}}{{end}}

-
+ - +
@@ -270,7 +270,7 @@
- +
+ {{template "inline_confirm_js"}} {{template "icon_sprite"}} @@ -405,10 +406,9 @@
The per-customer secret that fetches the whole config — masked by default; never place it on a command line (the installer reads it at a no-echo prompt). -
+ {{.CSRFField}} - +
@@ -446,10 +446,9 @@ The customer sets + owns the dashboard password (claim code → own password). The code goes ONLY to the registered address ({{.Email}}); the hub stores a hash — no plaintext code exists to display.
{{if .Claim}} -
+ {{.CSRFField}} - +
{{end}} @@ -713,16 +712,14 @@ {{else}} -
+ {{.CSRFField}} - +
{{end}} -
+ {{.CSRFField}} - +
@@ -1047,7 +1044,8 @@ if (document.getElementById('gen-controls')) { genUpdate(); } function disableGeo(customerID) { - if (!confirm('Összes geo-korlátozás eltávolítása?\n\nEz közvetlenül törli a Cloudflare WAF szabályokat és értesíti a controllert.')) return; + var geoBtn = document.getElementById('btn-geo-disable'); + felhomConfirm(geoBtn, 'Összes geo-korlátozás eltávolítása? Ez közvetlenül törli a Cloudflare WAF szabályokat és értesíti a controllert.', function () { var btn = document.getElementById('btn-geo-disable'); var msg = document.getElementById('geo-msg'); btn.disabled = true; @@ -1076,6 +1074,7 @@ btn.disabled = false; btn.textContent = 'Összes geo-korlátozás eltávolítása'; }); + }); } {{if .HasConfig}} // Load YAML preview diff --git a/hub/internal/web/templates/inline_confirm.html b/hub/internal/web/templates/inline_confirm.html new file mode 100644 index 0000000..b7fdefe --- /dev/null +++ b/hub/internal/web/templates/inline_confirm.html @@ -0,0 +1,32 @@ +{{define "inline_confirm_js"}} + +{{end}} diff --git a/hub/internal/web/templates/style.css b/hub/internal/web/templates/style.css index e5f58ef..88ef4a8 100644 --- a/hub/internal/web/templates/style.css +++ b/hub/internal/web/templates/style.css @@ -975,6 +975,10 @@ header h1 span { color: var(--blue-bright); } } body.js-tabs .tab-panel:not(.tab-panel-active) { display: none; } +/* Inline two-step confirm (take-two F-16) — the in-place replacement for native confirm() */ +.inline-confirm { display: inline-flex; align-items: center; gap: .5rem; flex-wrap: wrap; } +.inline-confirm-q { font-size: .8rem; color: var(--warn); } + @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } } diff --git a/scripts/hub_confirm_gate.py b/scripts/hub_confirm_gate.py new file mode 100644 index 0000000..03fbf55 --- /dev/null +++ b/scripts/hub_confirm_gate.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +"""Hub native-confirm gate (take-two F-16, the hub sibling of drill F-11) — native confirm()/ +prompt() dialogs are OS-modals that freeze browser automation (CDP) and are banned from the hub +UI; consequential buttons use the inline felhomConfirm helper (templates/inline_confirm.html). +The danger-zone typed-confirm flow does not use native dialogs either. + +Run from the repo root: python scripts/hub_confirm_gate.py +Exit 1 if any native confirm(/prompt( call remains in hub templates. +""" +import io, os, re, sys + +ROOT = os.path.join("hub", "internal", "web", "templates") + +# A bare confirm(/prompt( CALL with an argument: not preceded by an identifier character, so felhomConfirm( +# never matches. window.confirm( still matches ('.' is not an identifier char). +NATIVE = re.compile(r"(?