R-729 + R-545: the household can remove its own off-site target („Távoli mentési cél törlése")
POST /backup/offbox/clear (reveal-then-confirm) forgets the target and deletes ssh_key + known_hosts; nothing on the target is touched. repo_password is kept whenever anything could depend on it (hub sealed package — the R-241 rule; escrowed; a successful run; snapshots) and deleted only otherwise. Refused for the Felhom tier (rclone-pinned), while the single-flight is held, and while an abandonment countdown runs. i18n parity fixtures of backups_remote gain the additive block only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -331,6 +331,49 @@ func (s *Server) offboxResetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
offboxRedirect(w, r, "flash.offbox.restart_started", false)
|
||||
}
|
||||
|
||||
// offboxClearHandler is the household's „Távoli mentési cél törlése" press (R-729 / R-545): forget the
|
||||
// target and delete its transport secrets, never the repository. Reveal-then-confirm like the reset
|
||||
// (confirm=1). The refusals and what is kept are backup.ClearOffboxTarget's; this maps them to words.
|
||||
func (s *Server) offboxClearHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if s.backupMgr == nil {
|
||||
offboxRedirect(w, r, "flash.offbox.mgr_unavailable", true)
|
||||
return
|
||||
}
|
||||
_ = r.ParseForm()
|
||||
if r.FormValue("confirm") != "1" {
|
||||
offboxRedirect(w, r, "flash.offbox.clear_needs_confirmation", true)
|
||||
return
|
||||
}
|
||||
res, err := s.backupMgr.ClearOffboxTarget()
|
||||
switch {
|
||||
case errors.Is(err, backup.ErrOffboxClearNoTarget):
|
||||
offboxRedirect(w, r, "flash.offbox.target_not_set", true)
|
||||
return
|
||||
case errors.Is(err, backup.ErrOffboxClearHubTier):
|
||||
offboxRedirect(w, r, "flash.offbox.clear_hub_tier", true)
|
||||
return
|
||||
case errors.Is(err, backup.ErrOffboxClearBusy):
|
||||
offboxRedirect(w, r, "flash.offbox.clear_busy", true)
|
||||
return
|
||||
case errors.Is(err, backup.ErrOffboxClearAbandonOn):
|
||||
offboxRedirect(w, r, "flash.offbox.clear_abandon_pending", true)
|
||||
return
|
||||
case err != nil:
|
||||
s.logger.Printf("[ERROR] [web] off-site target clear failed: %v", err)
|
||||
offboxRedirect(w, r, "flash.offbox.save_failed", true)
|
||||
return
|
||||
}
|
||||
if !res.KeptRepoPassword {
|
||||
// The key is gone, so a copy still staged on the agent for an unfinished ceremony is a stale
|
||||
// secret with nothing behind it. Best-effort, like the confirm path's wipe.
|
||||
if werr := s.wipeStagedEscrow(r.Context()); werr != nil {
|
||||
s.logger.Printf("[WARN] [web] off-site target cleared, but the agent-staged escrow copy was not wiped: %v", werr)
|
||||
}
|
||||
}
|
||||
s.reportTriggerNow()
|
||||
offboxRedirect(w, r, "flash.offbox.target_cleared", false)
|
||||
}
|
||||
|
||||
// offboxStatusHandler (Part C) is the poll source for the remote-backup run status — the page polls it
|
||||
// after "Távoli mentés most" and flips to the terminal state without a manual reload. Session-auth'd.
|
||||
func (s *Server) offboxStatusHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
||||
)
|
||||
|
||||
// R-729 / R-545 — the „Távoli mentési cél törlése" press: the route is wired, needs confirm=1, and
|
||||
// clears the household's own target; the page offers it for an own target and NOT for the Felhom tier.
|
||||
|
||||
func clearServer(t *testing.T, tgt *settings.OffboxTarget) (*Server, string) {
|
||||
t.Helper()
|
||||
s := noteServer(t)
|
||||
s.cfg.Paths.DataDir = t.TempDir()
|
||||
bm := backup.NewManager(s.cfg, s.settings, s.logger)
|
||||
if err := s.settings.SetOffboxTarget(tgt); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := bm.WriteOffboxSecrets("KEYMATERIAL", "nas.local ssh-ed25519 HOSTKEY"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s.backupMgr = bm
|
||||
s.wipeStagedEscrowFn = func(context.Context) error { return nil }
|
||||
return s, filepath.Join(s.cfg.Paths.DataDir, "offbox")
|
||||
}
|
||||
|
||||
func postClear(t *testing.T, s *Server, form string) (flash, flashErr string) {
|
||||
t.Helper()
|
||||
req := httptest.NewRequest(http.MethodPost, "/backup/offbox/clear", strings.NewReader(form))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
w := httptest.NewRecorder()
|
||||
s.offboxClearHandler(w, req)
|
||||
if w.Code != http.StatusFound {
|
||||
t.Fatalf("want redirect, got %d", w.Code)
|
||||
}
|
||||
u, _ := url.Parse(w.Header().Get("Location"))
|
||||
return u.Query().Get("flash"), u.Query().Get("flash_error")
|
||||
}
|
||||
|
||||
func TestR729_ClearHandler_NeedsConfirmAndThenClears(t *testing.T) {
|
||||
s, dir := clearServer(t, &settings.OffboxTarget{Enabled: false, Host: "nas.local", Port: 22, User: "felhom", RepoPath: "/srv/repo"})
|
||||
|
||||
// Without confirm=1 nothing happens.
|
||||
if _, fe := postClear(t, s, ""); fe != "flash.offbox.clear_needs_confirmation" {
|
||||
t.Fatalf("no-confirm: flash_error=%q", fe)
|
||||
}
|
||||
if s.settings.GetOffboxTarget() == nil {
|
||||
t.Fatal("an unconfirmed press removed the target")
|
||||
}
|
||||
|
||||
f, fe := postClear(t, s, "confirm=1")
|
||||
if fe != "" || f != "flash.offbox.target_cleared" {
|
||||
t.Fatalf("confirmed clear: flash=%q flash_error=%q", f, fe)
|
||||
}
|
||||
if s.settings.GetOffboxTarget() != nil {
|
||||
t.Fatal("R-729: the target survived a confirmed clear")
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, "ssh_key")); !os.IsNotExist(err) {
|
||||
t.Fatalf("R-545: the SSH key survived a confirmed clear (stat err=%v)", err)
|
||||
}
|
||||
// Both languages say the backups on the destination were not touched.
|
||||
if hu := s.msgLang("hu", f); !strings.Contains(hu, "nem ny") {
|
||||
t.Errorf("hu success text does not say the destination was untouched: %q", hu)
|
||||
}
|
||||
if en := s.msgLang("en", f); !strings.Contains(en, "not touched") {
|
||||
t.Errorf("en success text does not say the destination was untouched: %q", en)
|
||||
}
|
||||
}
|
||||
|
||||
func TestR729_ClearHandler_RefusesHubTier(t *testing.T) {
|
||||
s, dir := clearServer(t, &settings.OffboxTarget{Enabled: true, Host: "box.example", Port: 23, User: "u1", RepoPath: "/home/repo", Transport: settings.TransportRclonePinned})
|
||||
if _, fe := postClear(t, s, "confirm=1"); fe != "flash.offbox.clear_hub_tier" {
|
||||
t.Fatalf("hub tier: flash_error=%q", fe)
|
||||
}
|
||||
if s.settings.GetOffboxTarget() == nil {
|
||||
t.Fatal("the Felhom tier was removed from the box")
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, "ssh_key")); err != nil {
|
||||
t.Fatalf("the Felhom tier's key was deleted: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Render test per branch of the template gate (seam-built-but-never-wired lesson).
|
||||
func TestR729_RemotePage_OffersClearOnlyForOwnTarget(t *testing.T) {
|
||||
d := splitTestData()
|
||||
html := renderBackupPage(t, "backups_remote", d)
|
||||
if !strings.Contains(html, `action="/backup/offbox/clear"`) {
|
||||
t.Fatal("R-729: an own target renders no clear press")
|
||||
}
|
||||
d["Offbox"] = &settings.OffboxTarget{Enabled: true, Host: "box.example", LastStatus: "ok", EscrowState: "escrowed", Transport: settings.TransportRclonePinned}
|
||||
if strings.Contains(renderBackupPage(t, "backups_remote", d), `action="/backup/offbox/clear"`) {
|
||||
t.Fatal("R-729: the Felhom tier must not be offered for removal")
|
||||
}
|
||||
d["Offbox"] = nil
|
||||
d["OffboxConfigured"] = false
|
||||
if strings.Contains(renderBackupPage(t, "backups_remote", d), `action="/backup/offbox/clear"`) {
|
||||
t.Fatal("R-729: no target, yet a clear press renders")
|
||||
}
|
||||
}
|
||||
|
||||
// The route reaches the handler (a case only in a comment is the decoy this guards against).
|
||||
func TestR729_ClearRouteIsWired(t *testing.T) {
|
||||
src, err := os.ReadFile("server.go")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(src), `path == "/backup/offbox/clear" && r.Method == http.MethodPost:`+" // R-729 / R-545\n\t\ts.offboxClearHandler(w, r)") {
|
||||
t.Fatal("R-729: /backup/offbox/clear is not routed to offboxClearHandler")
|
||||
}
|
||||
}
|
||||
@@ -753,6 +753,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.offboxRunHandler(w, r)
|
||||
case path == "/backup/offbox/reset" && r.Method == http.MethodPost:
|
||||
s.offboxResetHandler(w, r)
|
||||
case path == "/backup/offbox/clear" && r.Method == http.MethodPost: // R-729 / R-545
|
||||
s.offboxClearHandler(w, r)
|
||||
case path == "/backup/offbox/status" && r.Method == http.MethodGet:
|
||||
s.offboxStatusHandler(w, r)
|
||||
case path == "/backup/offbox/restore" && r.Method == http.MethodPost:
|
||||
|
||||
@@ -270,6 +270,20 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">{{T "backups_remote.mentes"}}</button>
|
||||
</form>
|
||||
</details>
|
||||
{{/* R-729 / R-545: the household's own target can be removed. Never the repository on it; the
|
||||
Felhom-provided tier (Pinned) is not offered. Reveal-then-confirm, like the orphan reset. */}}
|
||||
{{if .Offbox}}{{if not .Offbox.Pinned}}
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">{{T "backups_remote.tavoli_mentesi_cel_torlese"}}</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">{{T "backups_remote.cel_torlese_magyarazat"}}</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">{{.CSRFField}}
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">{{T "backups_remote.cel_torlese_megerosites"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
|
||||
+13
@@ -276,6 +276,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -262,6 +262,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -265,6 +265,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -363,6 +363,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -277,6 +277,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -213,6 +213,8 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -214,6 +214,8 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
+13
@@ -278,6 +278,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
+13
@@ -268,6 +268,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -268,6 +268,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -282,6 +282,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -266,6 +266,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -266,6 +266,19 @@
|
||||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
|
||||
<div style="margin-top:.75rem" id="offbox-clear">
|
||||
<button type="button" class="btn btn-xs btn-outline" id="offbox-clear-reveal" onclick="var c=document.getElementById('offbox-clear-confirm');c.style.display='block';this.style.display='none'">Távoli mentési cél törlése</button>
|
||||
<div id="offbox-clear-confirm" style="display:none;margin-top:.6rem">
|
||||
<p class="form-hint" style="margin:0 0 .5rem">A gép elfelejti ezt a távoli mentési célt, és törli a hozzá tartozó SSH kulcsot. A célgépen lévő mentésekhez nem nyúl: azok ott maradnak, ahol vannak. Ezután nem fut távoli mentés, amíg új célt nem állítasz be.</p>
|
||||
<form method="POST" action="/backup/offbox/clear" style="display:inline">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Igen, töröld a célt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user