v0.252.0 — the sentences the program builds follow the language (R-557 slice 2 release A)
gates / gates (push) Successful in 23s
gates / gates (push) Successful in 23s
Slice 1 translated the dashboard's markup. The sentences the program BUILDS were still Hungarian literals in Go, so an English household clicked an English button and was answered in Hungarian. 226 of them move into the bundle here. A flash was the hard part: it travels inside the redirect URL and is rendered by a DIFFERENT request, so it now carries a bundle key plus its parameters. A link minted by an older controller carries prose and is shown verbatim — never a raw key, never dropped. Also converted: page data and view-model text, the internal/api JSON answers, the alert banners (Alert.MessageKey, rendered on the way out of GetAlerts), 237 country names at display, and the four page titles built around an app name (R-566 closed). Hungarian is byte-identical, and that is measured rather than read: scripts/i18n_go_parity.py freezes every Go literal at the base commit (7 467) and refuses a key whose Hungarian is not that text, byte for byte. Three decoys, each seen to convict. Its own first version filtered the capture through an ASCII-Hungarian word list and missed seven real literals — the R-565 class. The filter is gone. Nothing on the wire moved, and wire goldens now hold it there: the report's health warnings and every notify event message stay Hungarian, because the hub MAILS the controller's sentence when it has no entry of its own. Slice 3 (R-558) owns those. MinAgent: 0.131.0 (unchanged). No hub release needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -171,9 +171,14 @@ func (s *Server) renderSharePasswordPage(w http.ResponseWriter, r *http.Request,
|
||||
|
||||
// ── admin share management (session-authed via RequireAuth + session CSRF via CsrfProtect) ─────────
|
||||
|
||||
// launcherShareRedirect returns to /launcher with a Hungarian flash (reuses urlQueryEscape).
|
||||
func (s *Server) launcherShareRedirect(w http.ResponseWriter, r *http.Request, flash string) {
|
||||
http.Redirect(w, r, "/launcher?flash="+urlQueryEscape(flash), http.StatusSeeOther)
|
||||
// launcherShareRedirect returns to /launcher with a flash.
|
||||
//
|
||||
// `key` is a bundle KEY, not a sentence (v0.252.0, R-557): the redirect is read by a DIFFERENT
|
||||
// request, and only that request knows the household's language. The launcher resolves it with
|
||||
// s.flashText, which shows a sentence minted by an older controller verbatim — so a link already in
|
||||
// a customer's tab still reads correctly.
|
||||
func (s *Server) launcherShareRedirect(w http.ResponseWriter, r *http.Request, key string) {
|
||||
http.Redirect(w, r, "/launcher?"+flashQuery("flash", key), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// launcherShareQRHandler serves the share link as a ~256px PNG QR code (admin-authed; not exempted, so
|
||||
@@ -199,44 +204,44 @@ func (s *Server) launcherShareQRHandler(w http.ResponseWriter, r *http.Request)
|
||||
// launcherShareEnableHandler mints the first token (POST /launcher/share/enable).
|
||||
func (s *Server) launcherShareEnableHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if s.settings.GetLauncherShareToken() != "" {
|
||||
s.launcherShareRedirect(w, r, "A megosztás már be van kapcsolva.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.already_on")
|
||||
return
|
||||
}
|
||||
tok, err := newShareToken()
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: token generation failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "A megosztás bekapcsolása nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.enable_failed")
|
||||
return
|
||||
}
|
||||
if err := s.settings.SetLauncherShareToken(tok); err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: saving token failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "A megosztás bekapcsolása nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.enable_failed")
|
||||
return
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] launcher share link enabled")
|
||||
s.launcherShareRedirect(w, r, "A megosztás bekapcsolva.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.enabled")
|
||||
}
|
||||
|
||||
// launcherShareRotateHandler mints a fresh token (POST /launcher/share/rotate). The old link 404s and
|
||||
// every outstanding guest cookie is invalidated (both are bound to the token).
|
||||
func (s *Server) launcherShareRotateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if s.settings.GetLauncherShareToken() == "" {
|
||||
s.launcherShareRedirect(w, r, "A megosztás nincs bekapcsolva.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.not_on")
|
||||
return
|
||||
}
|
||||
tok, err := newShareToken()
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: token generation failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "Az új link készítése nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.relink_failed")
|
||||
return
|
||||
}
|
||||
if err := s.settings.SetLauncherShareToken(tok); err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: saving token failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "Az új link készítése nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.relink_failed")
|
||||
return
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] launcher share link rotated")
|
||||
s.launcherShareRedirect(w, r, "Új megosztási link készült. A korábbi link és minden korábbi belépés érvénytelen.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.relinked")
|
||||
}
|
||||
|
||||
// launcherShareDisableHandler clears the token AND the share password (POST /launcher/share/disable) —
|
||||
@@ -244,14 +249,14 @@ func (s *Server) launcherShareRotateHandler(w http.ResponseWriter, r *http.Reque
|
||||
func (s *Server) launcherShareDisableHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err := s.settings.SetLauncherShareToken(""); err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: clearing token failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "A megosztás kikapcsolása nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.disable_failed")
|
||||
return
|
||||
}
|
||||
if err := s.settings.SetLauncherSharePasswordHash(""); err != nil {
|
||||
s.logger.Printf("[WARN] [web] share: clearing share password on disable failed: %v", err)
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] launcher share link disabled")
|
||||
s.launcherShareRedirect(w, r, "A megosztás kikapcsolva.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.disabled")
|
||||
}
|
||||
|
||||
// launcherSharePasswordHandler sets or clears the OPTIONAL per-share password (POST
|
||||
@@ -260,35 +265,35 @@ func (s *Server) launcherShareDisableHandler(w http.ResponseWriter, r *http.Requ
|
||||
func (s *Server) launcherSharePasswordHandler(w http.ResponseWriter, r *http.Request) {
|
||||
_ = r.ParseForm()
|
||||
if s.settings.GetLauncherShareToken() == "" {
|
||||
s.launcherShareRedirect(w, r, "A megosztás nincs bekapcsolva.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.not_on")
|
||||
return
|
||||
}
|
||||
if r.FormValue("action") == "clear" {
|
||||
if err := s.settings.SetLauncherSharePasswordHash(""); err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: clearing share password failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "A jelszó törlése nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.pw_clear_failed")
|
||||
return
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] launcher share password cleared")
|
||||
s.launcherShareRedirect(w, r, "A megosztási jelszó törölve.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.pw_cleared")
|
||||
return
|
||||
}
|
||||
pw := r.FormValue("password")
|
||||
if len(pw) < shareMinPassword {
|
||||
s.launcherShareRedirect(w, r, "A jelszónak legalább 8 karakter hosszúnak kell lennie.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.pw_too_short")
|
||||
return
|
||||
}
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(pw), 10)
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: hashing share password failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "A jelszó beállítása nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.pw_set_failed")
|
||||
return
|
||||
}
|
||||
if err := s.settings.SetLauncherSharePasswordHash(string(hash)); err != nil {
|
||||
s.logger.Printf("[ERROR] [web] share: saving share password failed: %v", err)
|
||||
s.launcherShareRedirect(w, r, "A jelszó beállítása nem sikerült.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.pw_set_failed")
|
||||
return
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] launcher share password set")
|
||||
s.launcherShareRedirect(w, r, "A megosztási jelszó beállítva. A korábbi belépések érvénytelenek.")
|
||||
s.launcherShareRedirect(w, r, "flash.share.pw_set")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user