diff --git a/internal/core/dbtest_test.go b/internal/core/dbtest_test.go
index 0863b1b..c6f06b3 100644
--- a/internal/core/dbtest_test.go
+++ b/internal/core/dbtest_test.go
@@ -23,6 +23,15 @@ func appLogin(t *testing.T, ts *httptest.Server, st *store.Store, ctx context.Co
if err != nil {
t.Fatalf("create user: %v", err)
}
+ return u, appSession(t, ts, st, ctx, host, u)
+}
+
+// appSession signs an EXISTING user in, returning an app-host session cookie. It
+// is appLogin without the account creation, for tests that need a session for
+// someone another part of the fixture already created (a steward, a share
+// recipient) — calling appLogin for them would fail on the duplicate username.
+func appSession(t *testing.T, ts *httptest.Server, st *store.Store, ctx context.Context, host string, u *store.User) *http.Cookie {
+ t.Helper()
loginID, err := st.CreateLogin(ctx, u.ID)
if err != nil {
t.Fatalf("create login: %v", err)
@@ -35,9 +44,9 @@ func appLogin(t *testing.T, ts *httptest.Server, st *store.Store, ctx context.Co
resp.Body.Close()
c := cookieByName(resp, "meshtender_session")
if c == nil {
- t.Fatalf("no app session cookie after handoff for %q", username)
+ t.Fatalf("no app session cookie after handoff for %q", u.Username)
}
- return u, c
+ return c
}
// testConfig/testAuthConfig give the integration tests the app/auth/root hosts,
diff --git a/internal/core/repeaters.go b/internal/core/repeaters.go
index 64b19fd..2a175a9 100644
--- a/internal/core/repeaters.go
+++ b/internal/core/repeaters.go
@@ -104,9 +104,10 @@ func (s *Handlers) pageRepeater(w http.ResponseWriter, r *http.Request) {
"Radio": radio,
"ContactURI": contactURI,
"Error": r.URL.Query().Get("error"),
+ "OK": r.URL.Query().Get("ok"),
}
// When the owner has published a public page, surface its link plus a QR code
- // to print and place inside the enclosure (the NFC/QR tap target).
+ // for it.
if isOwner && rep.ExposePublicPage {
publicURL := s.Origin(r, s.rootHost()) + "/r/" + rep.PublicID
data["PublicPageURL"] = publicURL
diff --git a/internal/core/templates/add_repeater.html b/internal/core/templates/add_repeater.html
index 070fca4..c905b3a 100644
--- a/internal/core/templates/add_repeater.html
+++ b/internal/core/templates/add_repeater.html
@@ -61,19 +61,17 @@
-
-
{{template "icon-alert" "alert-icon"}}
-
-
This grants full admin control to MeshTender
-
-
This grants admin to MeshTender itself — not to other
- MeshTender users. Letting specific people operate the repeater is a separate step you control later
- via sharing and contributing to organizations.
-
MeshTender will not abuse this access — but that is a promise, not a technical limit.
-
This is a standing grant. It remains until you revoke it on the repeater
- (see below) — removing the repeater from this site does not revoke MeshTender's access.
-
-
+
{{template "icon-alert" "alert-icon"}}
+
+
This grants full admin control to MeshTender
+
+
This grants admin to MeshTender itself — not to other
+ MeshTender users. Letting specific people operate the repeater is a separate step you control later
+ via sharing and contributing to organizations.
+
MeshTender will not abuse this access — but that is a promise, not a technical limit.
+
This is a standing grant. It remains until you revoke it on the repeater
+ (see below) — removing the repeater from this site does not revoke MeshTender's access.
+
@@ -81,18 +79,16 @@
{{/* Add-existing only: USB setup sets the location explicitly, so there's no
fetch to disclose there. */}}
-
-
{{template "icon-map-pin" "alert-icon"}}
-
-
MeshTender will read the repeater's location
-
- When you confirm this repeater — or use “Fetch location” later — MeshTender reads its coordinates by
- running get lat / get lon through your modem, on its own behalf
- (not as a command you or anyone you share with runs). It uses them to place the repeater on the map and to
- tailor its region configuration. You stay in control: you can keep it off the public map, and
- you decide which commands other people may run on it.
-
-
+
{{template "icon-map-pin" "alert-icon"}}
+
+
MeshTender will read the repeater's location
+
+ When you confirm this repeater — or use “Fetch location” later — MeshTender reads its coordinates by
+ running get lat / get lon through your modem, on its own behalf
+ (not as a command you or anyone you share with runs). It uses them to place the repeater on the map and to
+ tailor its region configuration. You stay in control: you can keep it off the public map, and
+ you decide which commands other people may run on it.
+
{{end}}
@@ -241,7 +237,7 @@
@@ -321,7 +317,7 @@
diff --git a/internal/core/templates/delete_repeater.html b/internal/core/templates/delete_repeater.html
index 132d7c6..0928d7d 100644
--- a/internal/core/templates/delete_repeater.html
+++ b/internal/core/templates/delete_repeater.html
@@ -14,16 +14,27 @@
all go away. This can't be undone.
-
-
-
{{template "icon-alert" "alert-icon"}}
-
-
This does not revoke MeshTender's access
-
Your repeater still trusts MeshTender's identity at the firmware level. If you want MeshTender to truly lose access, revoke it on the device too — see below.
+ {{/* Deleting is rarely what someone wants when a node stays on the air and
+ only its keeper is changing — offer the handover before the red button. */}}
+
+
+
Is this repeater staying on the air?
+
+ If someone else is taking it over, transfer
+ ownership to a steward instead. Its documentation, maintenance history, and public page
+ address survive the handover; deleting throws all of that away.
+
+
{{template "icon-alert" "alert-icon"}}
+
+
This does not revoke MeshTender's access
+
Your repeater still trusts MeshTender's identity at the firmware level. If you want MeshTender to truly lose access, revoke it on the device too — see below.