feat: add domain settings support in backup import and export processes

This commit is contained in:
shuaiplus
2026-05-07 19:36:32 +08:00
parent 669d7ef242
commit a00279f47d
3 changed files with 39 additions and 3 deletions
+19 -2
View File
@@ -51,6 +51,7 @@ export interface BackupPayload {
db: {
config: SqlRow[];
users: SqlRow[];
domain_settings: SqlRow[];
user_revisions: SqlRow[];
folders: SqlRow[];
ciphers: SqlRow[];
@@ -284,6 +285,7 @@ export function validateBackupPayloadContents(
const configRows = ensureRowArray(payload.db.config, 'config');
const userRows = ensureRowArray(payload.db.users, 'users');
const revisionRows = ensureRowArray(payload.db.user_revisions, 'user_revisions');
const domainSettingsRows = ensureRowArray(payload.db.domain_settings || [], 'domain_settings');
const folderRows = ensureRowArray(payload.db.folders, 'folders');
const cipherRows = ensureRowArray(payload.db.ciphers, 'ciphers');
const attachmentRows = ensureRowArray(payload.db.attachments, 'attachments');
@@ -314,6 +316,18 @@ export function validateBackupPayloadContents(
}
}
const domainSettingUserIds = new Set<string>();
for (const row of domainSettingsRows) {
const userId = String(row.user_id || '').trim();
if (!userId || !userIds.has(userId)) {
throw new Error(`Backup archive contains domain settings for an unknown user: ${userId || '(empty)'}`);
}
if (domainSettingUserIds.has(userId)) {
throw new Error(`Backup archive contains duplicate domain settings for user: ${userId}`);
}
domainSettingUserIds.add(userId);
}
const folderIds = new Set<string>();
for (const row of folderRows) {
const id = String(row.id || '').trim();
@@ -365,9 +379,10 @@ export async function buildBackupArchive(
includeAttachments,
});
const encoder = new TextEncoder();
const [configRows, userRows, revisionRows, folderRows, cipherRows, attachmentRows] = await Promise.all([
const [configRows, userRows, domainSettingsRows, revisionRows, folderRows, cipherRows, attachmentRows] = await Promise.all([
queryRows(env.DB, 'SELECT key, value FROM config ORDER BY key ASC'),
queryRows(env.DB, 'SELECT id, email, name, master_password_hint, master_password_hash, key, private_key, public_key, kdf_type, kdf_iterations, kdf_memory, kdf_parallelism, security_stamp, role, status, verify_devices, totp_secret, totp_recovery_code, api_key, created_at, updated_at FROM users ORDER BY created_at ASC'),
queryRows(env.DB, 'SELECT id, email, name, master_password_hint, master_password_hash, key, private_key, public_key, kdf_type, kdf_iterations, kdf_memory, kdf_parallelism, security_stamp, role, status, verify_devices, totp_secret, totp_recovery_code, created_at, updated_at FROM users ORDER BY created_at ASC'),
queryRows(env.DB, 'SELECT user_id, equivalent_domains, custom_equivalent_domains, excluded_global_equivalent_domains, updated_at FROM domain_settings ORDER BY user_id ASC'),
queryRows(env.DB, 'SELECT user_id, revision_date FROM user_revisions ORDER BY user_id ASC'),
queryRows(env.DB, 'SELECT id, user_id, name, created_at, updated_at FROM folders ORDER BY created_at ASC'),
queryRows(env.DB, 'SELECT id, user_id, type, folder_id, name, notes, favorite, data, reprompt, key, created_at, updated_at, archived_at, deleted_at FROM ciphers ORDER BY created_at ASC'),
@@ -394,6 +409,7 @@ export async function buildBackupArchive(
tableCounts: {
config: exportedConfigRows.length,
users: userRows.length,
domain_settings: domainSettingsRows.length,
user_revisions: revisionRows.length,
folders: folderRows.length,
ciphers: cipherRows.length,
@@ -415,6 +431,7 @@ export async function buildBackupArchive(
'db.json': encoder.encode(JSON.stringify({
config: exportedConfigRows,
users: userRows,
domain_settings: domainSettingsRows,
user_revisions: revisionRows,
folders: folderRows,
ciphers: cipherRows,