R-193: the recovery screen — unlocking, and only unlocking (v0.200.0)
A customer whose machine was rebuilt had everything needed to get their data back and no way to find out: the only route was a command line. This is the screen that closes that. IT UNLOCKS, AND ONLY UNLOCKS (operator ruling). It explains, takes the recovery code, opens the repository and shows what is in there — apps, dates, sizes. It restores nothing: restore is already per-app and lives in the backups area, and a screen that unlocks and then offers to overwrite is two decisions wearing one button. ONE CORE, TWO CALLERS. RecoverInstallCore is split out of RecoverAndInstall; the CLI wrapper keeps its exit codes and printed lines byte-identical, and the handler drives the same function. Two implementations of the one operation that can permanently lose a customer's data would drift, and only one would be tested. Asserted from source on both sides by AST. THREE WAYS OUT, none a dismiss button: recover; 'most nem' (the full page stops interrupting, the backups-area entry point stays PERMANENTLY, bound to the offer and never to the postpone flag); and 'I do not want the old data' — confirmed TWICE and reaching the SHIPPED move-aside, which sets aside and never deletes. THE CODE IS HANDLED NO MORE LOOSELY THAN ON THE COMMAND LINE: POST body only, never logged, never persisted, never echoed, cleared on every path, no-store, autocomplete off. No lockout — the code is a ten-word phrase, and locking a customer out of their own data for a typo is worse than anything it prevents. TWO DEFECTS THE TESTS CAUGHT, both fixed: an UNCLAIMED (legacy-open) box would have been shown the page, because RequireAuth passes such a box through; and the inventory nil-dereferenced when no off-site target was configured, which is exactly the pristine rebuilt shape.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
{{define "recovery"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="hu">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Adatok visszaszerzése — Felhom</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="login-card" style="max-width:46rem">
|
||||
<img src="/static/felhom-logo.svg" alt="Felhom.eu" class="login-logo">
|
||||
|
||||
{{if .Unlocked}}
|
||||
<!-- ── AFTER THE UNLOCK: what is in there. Read-only — nothing was restored. ────────────── -->
|
||||
<h1 class="login-title">A mentéseid <span class="title-accent">elérhetők</span></h1>
|
||||
{{if .Flash}}<div class="alert alert-info">{{.Flash}}</div>{{end}}
|
||||
{{if .Error}}<div class="alert alert-error">{{.Error}}</div>{{end}}
|
||||
|
||||
{{if .InvEmpty}}
|
||||
<div class="alert alert-warning">
|
||||
A tároló megnyílt, de <strong>nincs benne egyetlen mentés sem</strong>. Ez azt jelenti, hogy a
|
||||
kulcs jó volt, de ehhez a géphez nem tartozik korábbi mentés. Ha korábban biztosan készültek
|
||||
mentések, keresd a Felhom ügyfélszolgálatát, mielőtt bármit tennél.
|
||||
</div>
|
||||
{{else if .InvUntagged}}
|
||||
<div class="alert alert-warning">
|
||||
A tároló megnyílt, és van benne tartalom, de nem tudtuk alkalmazásokhoz rendelni. A Biztonsági
|
||||
mentés oldalon nézheted meg részletesen.
|
||||
</div>
|
||||
{{else}}
|
||||
<p class="login-subtitle" style="margin-bottom:1rem">
|
||||
Ezek a <strong>te</strong> mentéseid, a lent jelzett időpontokból. Nézd át, hogy tényleg azt
|
||||
találod-e itt, amire számítasz — <strong>semmit nem állítottunk vissza és semmi nem változott.</strong>
|
||||
</p>
|
||||
<table class="data-table" style="width:100%;margin-bottom:1rem">
|
||||
<thead><tr><th>Alkalmazás</th><th>Legutóbbi mentés</th><th>Méret</th></tr></thead>
|
||||
<tbody>
|
||||
{{range .InvApps}}
|
||||
<tr>
|
||||
<td>{{.App}}</td>
|
||||
<td>{{fmtTime .LatestAt}}</td>
|
||||
<td>{{if gt .SizeBytes 0}}{{humanBytes .SizeBytes}}{{else}}—{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{end}}
|
||||
|
||||
<p class="form-hint">
|
||||
A visszaállítás alkalmazásonként történik, a <strong>Biztonsági mentés → Visszaállítás</strong>
|
||||
oldalon. Ott választhatod ki, melyik alkalmazás mit hozzon vissza.
|
||||
</p>
|
||||
<div class="form-actions">
|
||||
<a href="/backups/restore" class="btn btn-primary">Tovább a visszaállításhoz</a>
|
||||
<a href="/launcher" class="btn btn-outline">Vissza a kezdőlapra</a>
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
<!-- ── BEFORE ANY CODE: explain, then take the code. ───────────────────────────────────── -->
|
||||
<h1 class="login-title">Adatok <span class="title-accent">visszaszerzése</span></h1>
|
||||
<p class="login-subtitle">{{.CustomerName}}</p>
|
||||
|
||||
{{if .Flash}}<div class="alert alert-info">{{.Flash}}</div>{{end}}
|
||||
{{if .Error}}<div class="alert alert-error">{{.Error}}</div>{{end}}
|
||||
|
||||
<p>
|
||||
Ezt a gépet újratelepítették. A korábbi, <strong>házon kívüli mentéseid megvannak</strong> — a
|
||||
Felhom központi rendszere őriz hozzájuk egy lezárt csomagot{{with .SealedAt}}, amelyet
|
||||
<strong>{{.}}</strong> zártunk le{{end}}. A csomagot csak a <strong>te helyreállítási
|
||||
kódoddal</strong> lehet kinyitni.
|
||||
</p>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<strong>A helyreállítási kódot senki nem tudja pótolni</strong> — sem a Felhom, sem az
|
||||
ügyfélszolgálat, sem az üzemeltető. Ez szándékos: így a mentéseidet rajtad kívül senki nem
|
||||
tudja megnyitni. Ha a kód elveszett, a korábbi mentések nem nyithatók meg többé.
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Ha megadod a kódot, <strong>feloldjuk a mentéseid zárolását és megmutatjuk, mi van bennük</strong>
|
||||
— melyik alkalmazás, mikorról, mekkora. <strong>Ebben a lépésben semmit nem állítunk vissza és
|
||||
semmi nem változik.</strong> A visszaállítást utána, alkalmazásonként külön választhatod.
|
||||
</p>
|
||||
|
||||
<form method="POST" action="/recovery/unlock" autocomplete="off">
|
||||
{{.CSRFField}}
|
||||
<label for="recovery_code">Helyreállítási kód (tíz szó)</label>
|
||||
<input type="password" id="recovery_code" name="recovery_code"
|
||||
autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false"
|
||||
placeholder="tíz szó, szóközökkel elválasztva" required>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Mentések feloldása</button>
|
||||
<form method="POST" action="/recovery/postpone" style="display:inline">
|
||||
{{.CSRFField}}
|
||||
<button type="submit" class="btn btn-outline">Most nem</button>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p class="form-hint">
|
||||
A „Most nem” csak azt jelenti, hogy nem zavarunk vele többet a kezdőlapon. A mentéseid ettől
|
||||
megmaradnak, és ez az oldal a <strong>Biztonsági mentés → Távoli mentés</strong> oldalról
|
||||
bármikor újra elérhető.
|
||||
</p>
|
||||
|
||||
<!-- ── THE EXCEPTIONAL PATH. Deliberately not an equal third button. ───────────────────── -->
|
||||
<hr style="margin:1.5rem 0;border:none;border-top:1px solid var(--border,#2a3142)">
|
||||
{{if .ConfirmSetAside}}
|
||||
<div class="alert alert-error">
|
||||
<p><strong>Biztosan nem kéred vissza a korábbi mentéseket?</strong></p>
|
||||
<p>Ha megerősíted:</p>
|
||||
<ul>
|
||||
<li>a korábbi mentéseket <strong>félretesszük — nem töröljük</strong>;</li>
|
||||
<li>a helyreállítási kód nélkül <strong>többé nem lesznek megnyithatók</strong>;</li>
|
||||
<li>a gép <strong>új, üres mentési tárolót kezd</strong>, és mostantól oda ment;</li>
|
||||
<li>ez az oldal <strong>többé nem jelenik meg</strong>.</li>
|
||||
</ul>
|
||||
<p>Ha csak most nincs kéznél a kódod, válaszd inkább a „Most nem” lehetőséget.</p>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<form method="POST" action="/backup/offbox/reset">
|
||||
{{.CSRFField}}
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<button type="submit" class="btn btn-danger">Igen, félretehetitek a korábbi mentéseket</button>
|
||||
</form>
|
||||
<a href="/recovery" class="btn btn-outline">Mégsem</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<p class="form-hint">
|
||||
Ha a helyreállítási kódod véglegesen elveszett, és tudomásul veszed, hogy a korábbi mentések
|
||||
így nem nyithatók meg többé:
|
||||
{{if .CanSetAside}}
|
||||
<a href="/recovery?setaside=1">nem kérem vissza a korábbi adatokat</a>.
|
||||
{{else}}
|
||||
ez a lehetőség akkor válik elérhetővé, ha a gép már újra kapcsolódott a házon kívüli
|
||||
tárhelyhez. Addig a mentéseid érintetlenül megmaradnak.
|
||||
{{end}}
|
||||
</p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user