librelad 82989069e2 refactor(backup): decompose backup-page god-file into 13 responsibility files
Faithful prototype-augment split of backup-page.js (2353->753 line base) into
fetch-client, dashboard, snapshots, locations, location-fields, ssh-key,
retention-presets, configuration, engine-details, location-modal,
snapshot-actions, migrate (+ the earlier cron-schedule). Methods relocated
verbatim (mechanical sed/awk extraction, no logic change); all augment
BackupPage.prototype and load after the base via the ordered kernel loader.
Verified: all 99 original methods present exactly once across base+clusters,
no duplicates, all 14 files node --check clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 14:02:45 +01:00

50 lines
3.1 KiB
JavaScript

// Auto-extracted from backup-page.js (verbatim) — augments BackupPage.prototype. Loaded after the base.
Object.assign(BackupPage.prototype, {
renderBackupSshKeyCard(l) {
const idx = l.idx;
const hasKey = l.ssh_key_exists === true;
const pub = l.ssh_public_key || '';
const body = hasKey ? `
<p class="backup-card-hint">Add this public key to the remote server's <code>~/.ssh/authorized_keys</code>:</p>
<textarea class="backup-ssh-pubkey" readonly rows="2" spellcheck="false">${this.escape(pub)}</textarea>
<div class="backup-ssh-key-actions">
<button type="button" class="backup-secondary-btn" data-action="ssh-key-copy" data-loc="${idx}">Copy public key</button>
<button type="button" class="backup-danger-btn" data-action="ssh-key-delete" data-loc="${idx}">Delete key</button>
</div>` : `
<p class="backup-card-hint">Paste an existing private key, or generate one and we'll show the public key to add on the remote.</p>
<textarea class="backup-ssh-keyinput" rows="4" spellcheck="false" placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"></textarea>
<div class="backup-ssh-key-actions">
<button type="button" class="backup-primary-btn" data-action="ssh-key-save" data-loc="${idx}">Save key</button>
<button type="button" class="backup-secondary-btn" data-action="ssh-key-generate" data-loc="${idx}">Generate keypair</button>
</div>`;
return `
<div class="backup-ssh-key-card" data-loc="${idx}">
<div class="backup-ssh-key-head">
<span class="backup-ssh-key-title">SSH key</span>
<span class="backup-ssh-key-status ${hasKey ? 'ok' : 'none'}">${hasKey ? '✓ Key configured' : 'No key yet'}</span>
</div>
${body}
</div>`;
},
async saveBackupSshKey(idx) {
const card = document.querySelector(`.backup-ssh-key-card[data-loc="${idx}"]`);
const key = (card?.querySelector('.backup-ssh-keyinput')?.value || '').trim();
if (!key) { this.notify('Paste a private key first', 'error'); return; }
const b64 = btoa(unescape(encodeURIComponent(key + '\n')));
await this.runTask(`libreportal backup location ssh-key-set ${idx} ${b64}`, 'backup', null);
},
async generateBackupSshKey(idx) {
await this.runTask(`libreportal backup location ssh-key-generate ${idx}`, 'backup', null);
},
async deleteBackupSshKey(idx) {
if (!confirm("Delete this location's SSH key? Backups here will fail until a new key is set and added on the remote.")) return;
await this.runTask(`libreportal backup location ssh-key-delete ${idx}`, 'backup', null);
},
async copyBackupSshKey(idx) {
const loc = (this.locations?.locations || []).find(l => l.idx === idx);
const pub = loc?.ssh_public_key || '';
try { await navigator.clipboard.writeText(pub); this.notify('Public key copied', 'success'); }
catch { this.notify('Copy failed — select the text and copy manually', 'error'); }
},
});