Files
AtreidesAssetsFree/client/pages/db-file.js
T

115 lines
4.5 KiB
JavaScript
Raw Normal View History

2026-10-30 12:28:48 +01:00
// Generated, do not edit. sha256:8e7f997881d1fd01e18e1023544e1df65cb2a48e77ba25495de5fe5ba3785bef
import { setAppSetting } from '../app-settings.js';
import { t } from '../i18n/index.js';
import { serverFoutTekst } from '../data/_rpc.js';
import * as dialog from '../ui/dialog.js';
export async function backupDb() {
const res = await dialog.form({
title: t('dbfile.backup'),
fields: [{ key: 'w1', label: t('dbfile.backupPass'), type: 'password' },
{ key: 'w2', label: t('dbfile.backupPassAgain'), type: 'password' }],
confirmLabel: t('dbfile.backupConfirm'),
});
if (!res) return false;
if (res.w1 !== res.w2) { dialog.alert({ title: t('dialog.error'), message: t('dbfile.backupPassMismatch') }); return false; }
try {
const r = await fetch('/api/db/backup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ passphrase: res.w1 }),
});
if (!r.ok) throw new Error(serverFoutTekst(await r.json().catch(() => null)) || `HTTP ${r.status}`);
const blob = await r.blob();
const naam = (r.headers.get('Content-Disposition') || '').match(/filename="([^"]+)"/)?.[1] || 'assetapp.assetbak';
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url; a.download = naam; a.click();
URL.revokeObjectURL(url);
await stempelBackup();
await dialog.alert({ message: t('dbfile.backupDone') });
return true;
} catch (err) {
dialog.alert({ title: t('dialog.error'), message: err.message });
return false;
}
}
export async function exportDb() {
const a = document.createElement('a');
a.href = '/api/db/export';
a.download = '';
a.click();
await stempelBackup();
}
export function restoreDb(onChanged = () => {}) {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.assetbak,.sqlite,.db';
fileInput.onchange = async () => {
const file = fileInput.files[0];
if (!file) return;
try {
const kop = new Uint8Array(await file.slice(0, 15).arrayBuffer());
const isBackup = new TextDecoder('latin1').decode(kop) === 'ASSETAPP-BACKUP';
if (!(await dialog.confirm({
message: isBackup ? t('dbfile.confirmRestoreBackup') : t('dbfile.confirmImport'), danger: true,
}))) return;
const headers = { 'Content-Type': 'application/octet-stream' };
if (isBackup) {
const res = await dialog.form({
title: t('dbfile.import'),
fields: [{ key: 'w', label: t('dbfile.backupPass'), type: 'password' }],
confirmLabel: t('dbfile.import'),
});
if (!res) return;
headers['X-Backup-Passphrase'] = res.w;
}
const res = await fetch('/api/db/import', { method: 'POST', headers, body: await file.arrayBuffer() });
const json = await res.json().catch(() => null);
if (!res.ok) throw new Error(serverFoutTekst(json) || `HTTP ${res.status}`);
const regels = [`${t('dbfile.importDone')} (versie ${json.versie}).`];
if (json.wezen) regels.push(`${t('dbfile.importOrphans')} ${json.wezen}`);
regels.push(json.versleuteld ? `${t('dbfile.restoredSecrets')} ${json.geheimen}` : json.geheimenWaarschuwing);
dialog.alert({ message: regels.join('\n\n') });
onChanged();
} catch (err) {
dialog.alert({ title: t('dialog.error'), message: err.message });
}
};
fileInput.click();
}
export async function startFresh(onChanged = () => {}) {
if (!(await dialog.confirm({ message: t('dbfile.confirmFresh'), danger: true }))) return;
const woord = t('dbfile.freshWord');
const res = await dialog.form({
title: t('dbfile.fresh'),
fields: [{ key: 'w', label: `${t('dbfile.freshTypeLabel')} ${woord}`, type: 'text' }],
confirmLabel: t('dbfile.fresh'),
});
if (!res) return;
if ((res.w || '').trim().toLowerCase() !== woord.toLowerCase()) {
dialog.alert({ title: t('dialog.error'), message: t('dbfile.freshWordMismatch') });
return;
}
try {
const r = await fetch('/api/db/fresh', { method: 'POST' });
const json = await r.json().catch(() => null);
if (!r.ok) throw new Error(serverFoutTekst(json) || `HTTP ${r.status}`);
dialog.alert({ message: `${t('dbfile.freshDone')} (versie ${json.versie}).\n\n${json.geheimenWaarschuwing}` });
onChanged();
} catch (err) {
dialog.alert({ title: t('dialog.error'), message: err.message });
}
}
async function stempelBackup() {
try { await setAppSetting('last_backup_at', new Date().toISOString()); } catch { }
document.dispatchEvent(new CustomEvent('providers-changed'));
}