This commit is contained in:
+37
-3
@@ -16,6 +16,14 @@ const MAX_PLAINTEXT_BYTES = 512 * 1024;
|
||||
const REQUEST_TIMEOUT_MS = 12_000;
|
||||
const KEY_CONTEXT = Buffer.from('MHU2-ONLINE-KEY-V1', 'utf8');
|
||||
const AAD_CONTEXT = Buffer.from('MHU-ONLINE-BACKUP-V1', 'utf8');
|
||||
const ONLINE_BACKUP_RETENTION_SECONDS = Object.freeze({
|
||||
'1d': 24 * 60 * 60,
|
||||
'3d': 3 * 24 * 60 * 60,
|
||||
'7d': 7 * 24 * 60 * 60,
|
||||
'31d': 31 * 24 * 60 * 60,
|
||||
forever: null
|
||||
});
|
||||
const DEFAULT_ONLINE_BACKUP_RETENTION = '7d';
|
||||
|
||||
function checksum(idBytes, masterKey) {
|
||||
return crypto.createHash('sha256').update(KEY_CONTEXT).update(idBytes).update(masterKey).digest().subarray(0, CHECKSUM_LENGTH);
|
||||
@@ -131,7 +139,27 @@ function parseOnlineBackupKey(key) {
|
||||
};
|
||||
}
|
||||
|
||||
function createOnlineBackup(settings, appVersion, exportedAt = new Date().toISOString()) {
|
||||
function normalizeOnlineBackupRetention(value = DEFAULT_ONLINE_BACKUP_RETENTION) {
|
||||
const normalized = String(value || '').trim();
|
||||
if (!Object.prototype.hasOwnProperty.call(ONLINE_BACKUP_RETENTION_SECONDS, normalized)) {
|
||||
throw new Error('Gültigkeitsdauer der Online-Sicherung ist ungültig');
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function onlineBackupExpiration(exportedAt, retention) {
|
||||
const normalized = normalizeOnlineBackupRetention(retention);
|
||||
const seconds = ONLINE_BACKUP_RETENTION_SECONDS[normalized];
|
||||
if (seconds === null) return null;
|
||||
const created = new Date(exportedAt);
|
||||
if (!Number.isFinite(created.getTime())) throw new Error('Erstellungszeit der Online-Sicherung ist ungültig');
|
||||
return new Date(created.getTime() + seconds * 1000).toISOString();
|
||||
}
|
||||
|
||||
function createOnlineBackup(settings, appVersion, exportedAt = new Date().toISOString(), retention = DEFAULT_ONLINE_BACKUP_RETENTION) {
|
||||
const normalizedRetention = normalizeOnlineBackupRetention(retention);
|
||||
const expiresInSeconds = ONLINE_BACKUP_RETENTION_SECONDS[normalizedRetention];
|
||||
const expiresAt = onlineBackupExpiration(exportedAt, normalizedRetention);
|
||||
const idBytes = crypto.randomBytes(RECORD_ID_LENGTH);
|
||||
const masterKey = crypto.randomBytes(MASTER_KEY_LENGTH);
|
||||
const key = encodeKey(idBytes, masterKey);
|
||||
@@ -163,8 +191,10 @@ function createOnlineBackup(settings, appVersion, exportedAt = new Date().toISOS
|
||||
record: {
|
||||
id: parsed.id,
|
||||
blob: blobBytes.toString('base64url'),
|
||||
deleteVerifier
|
||||
}
|
||||
deleteVerifier,
|
||||
expiresInSeconds
|
||||
},
|
||||
expiresAt
|
||||
};
|
||||
}
|
||||
|
||||
@@ -241,10 +271,14 @@ async function deleteOnlineBackup(key, baseUrl = ONLINE_BACKUP_API_URL, options)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
DEFAULT_ONLINE_BACKUP_RETENTION,
|
||||
ONLINE_BACKUP_API_URL,
|
||||
ONLINE_BACKUP_RETENTION_SECONDS,
|
||||
createOnlineBackup,
|
||||
deleteOnlineBackup,
|
||||
downloadOnlineBackup,
|
||||
normalizeOnlineBackupRetention,
|
||||
onlineBackupExpiration,
|
||||
parseOnlineBackupKey,
|
||||
restoreOnlineBackup,
|
||||
uploadOnlineBackup
|
||||
|
||||
Reference in New Issue
Block a user