Files
incredigo/internal/browserrot/sites.go
T
leetcrypt ce8a5257a6 browserrot(gitea): fix login submit selector from live read-only inspection
Read-only GET of a live Gitea /user/login showed the sign-in button is
<button class="ui primary button"> with NO type=submit attribute, so the seed
".ui.primary.button[type=submit]" would miss. Corrected to ".ui.primary.button"
(the mobile navbar toggle lacks "primary", so it stays unambiguous). Confirmed
during M-B4 rung-1 pre-live-fire prep; change-form selectors remain auth-gated
and self-heal-covered until the live run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-20 23:46:36 -07:00

58 lines
2.6 KiB
Go

package browserrot
import (
"strings"
"incredigo/internal/rotate"
)
// Curated recipes for self-hosted software whose markup is stable and known. These
// seed the Tier-1 selector table; on a first real run any miss is repaired by the
// Tier-2 self-heal (Healer) and re-persisted (recipes.go), so a slightly-off seed
// self-corrects rather than failing permanently. A recipe stays ProofUnproven until
// it has actually driven a rotation on that host — same proof-as-data discipline as
// the API drivers (rotate/proofs.go); only then does it promote to LIVE-REAL.
// GiteaSite builds a change-password recipe for a Gitea instance. baseURL is the
// scheme+host (e.g. "https://git.churchofmalware.org"), username the account login.
//
// Gitea reaches the change-password controls only inside an authenticated session
// (/user/settings/account 302s to /user/login otherwise), so LoginBeforeChange is on.
// The password form on the account page carries old_password / password / retype; the
// result renders in a flash message. These selectors match current Gitea markup but are
// UNPROVEN against any specific instance/version — VERIFY on first run (self-heal will
// rewrite any that drift). The SuccessText markers are the one part self-heal cannot fix
// (they are content, not selectors): a wrong marker only makes Rotate fail SAFE (old
// secret kept, human flagged), never a silent bad rotation.
func GiteaSite(baseURL, username string) Site {
base := strings.TrimRight(baseURL, "/")
return Site{
Host: strings.TrimPrefix(strings.TrimPrefix(base, "https://"), "http://"),
ChangeURL: base + "/user/settings/account",
Form: Form{
CurrentSel: "#old_password",
NewSel: "#password",
ConfirmSel: "#retype",
SubmitSel: "form[action$='/user/settings/account'] button[type=submit]",
SuccessSel: ".ui.positive.message, .flash-success",
SuccessText: "has been updated",
},
Login: Login{
URL: base + "/user/login",
UserSel: "#user_name",
PassSel: "#password",
// Gitea's sign-in button is <button class="ui primary button"> with NO
// type=submit attribute (confirmed by read-only inspection of a live
// instance 2026-07-20) — it submits as the form's only button. The mobile
// #navbar-expand-toggle button lacks "primary", so this stays unambiguous.
SubmitSel: ".ui.primary.button",
// Post-login, Gitea lands on the dashboard. The sign-out control's text is a
// stable "logged in" marker across themes; confirm on first run.
SuccessSel: "body",
SuccessText: username,
},
LoginBeforeChange: true,
Proof: rotate.ProofUnproven,
}
}