f037be7a6a
gates / gates (push) Successful in 48s
R-970: /api/config, /api/config/hash, /api/config/apply removed (they read and replaced controller.yaml with every secret, reachable with the box's own hub API key, unsigned; nothing called them). The hub-key Bearer door on /api/selfupdate/ and /api/geo/ and the matching CSRF exemption are gone; the dashboard keeps using those with a session. The route table is buildMux, so a test drives the real one. Data tab: the export password field is autocomplete=new-password with a non-login name; the 2nd copy's status rows that repeated the form are gone (the no-target reason moves into the form). R-1103: app_fields.html loses its installed-only branches (no page serves them since R-1095); the tests that rendered that dead path are retired, their rules asserted on the settings tab (R-694 moved there). Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
69 lines
3.2 KiB
Go
69 lines
3.2 KiB
Go
package web
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
|
|
)
|
|
|
|
// R-254 site two — WHAT §7.2 ESTABLISHED, PINNED SO IT CANNOT DRIFT BACK.
|
|
//
|
|
// The deploy page has TWO places a generated secret can appear, and they are NOT the same question:
|
|
//
|
|
// - the PRE-DEPLOY hidden input — a form must carry what it submits. README §318 documents why:
|
|
// the customer is shown the generated secrets so they can note them down, and submitting them
|
|
// back is what makes the saved value the SAME one they saw ("no silent re-generation on submit").
|
|
// This is NOT the defect and is deliberately left alone.
|
|
// - the READONLY display input on an ALREADY-DEPLOYED app — nothing is being submitted there (the
|
|
// hidden input is correctly omitted), yet the value was rendered into the body of a page the
|
|
// customer merely opens. That IS R-249's shape, and it is what v0.208.0 fixes.
|
|
//
|
|
// Both directions are asserted, because "fixed" here means one branch changed and the other did not.
|
|
|
|
const testDeploySecret = "TESTONLY-generated-db-pw-Xy91"
|
|
|
|
func renderDeployPage(t *testing.T, alreadyDeployed bool) string {
|
|
t.Helper()
|
|
s := securityHarness(t)
|
|
s.loadTemplates()
|
|
data := map[string]interface{}{
|
|
"Page": "stacks", "Title": "Telepítés", "Domain": "example.hu",
|
|
"Stack": stacks.Stack{Name: "vaultwarden", Deployed: alreadyDeployed},
|
|
"Meta": stacks.Metadata{DisplayName: "Vaultwarden", Slug: "vaultwarden"},
|
|
"AlreadyDeployed": alreadyDeployed,
|
|
"AutoFields": []stacks.DeployField{
|
|
{EnvVar: "DB_PASSWORD", Label: "Adatbázis jelszó", Type: "secret"},
|
|
},
|
|
"AutoFieldValues": map[string]string{"DB_PASSWORD": testDeploySecret},
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := s.tmpl.ExecuteTemplate(&buf, "deploy", data); err != nil {
|
|
t.Fatalf("render deploy: %v", err)
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// v0.322.0 (R-1103): TestDeployPage_DeployedApp_DoesNotCarryTheSecret is retired — the install form no longer renders
|
|
// for an installed app (R-1095, 302 to the settings tab). Its rule (an installed app's generated secret is not in the
|
|
// page; an eye fetches it) is asserted where the value is shown now: TestAppPage_LoginPairPanel (SECRET_KEY,
|
|
// ADMIN_USER, ADMIN_PASSWORD never in the settings page; every eye answers) and TestR255_NoPlantedSecretReachesAnyPage.
|
|
|
|
// The OTHER half of §7.2's answer: the pre-deploy form still carries the value, deliberately. If this
|
|
// ever starts failing, someone has "fixed" a form by stopping it submitting what it must submit —
|
|
// which would silently re-generate the secret on save and hand the customer a password that is not
|
|
// the one they wrote down.
|
|
func TestDeployPage_PreDeployForm_StillCarriesTheValue_Deliberately(t *testing.T) {
|
|
html := renderDeployPage(t, false)
|
|
|
|
if !strings.Contains(html, `<input type="hidden" name="DB_PASSWORD" value="`+testDeploySecret+`">`) {
|
|
t.Error("the pre-deploy form no longer submits the generated secret — the saved value would " +
|
|
"then not be the one the customer was shown (README §318, 'no silent re-generation on submit')")
|
|
}
|
|
if strings.Contains(html, `onclick="revealAutoField(`) {
|
|
t.Error("the deployed-app reveal control leaked onto the pre-deploy form, where the value is " +
|
|
"already legitimately present")
|
|
}
|
|
}
|