Skip to content

Commit a6ccff3

Browse files
committed
better validation of backup data
1 parent 387ac1e commit a6ccff3

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

src/pages/cipp/settings/backup.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,11 +421,17 @@ const Page = () => {
421421

422422
{/* Backup Restore Confirmation Dialog */}
423423
<CippApiDialog
424+
key={
425+
selectedBackupFile
426+
? `restore-${selectedBackupFile.name}-${selectedBackupFile.lastModified}`
427+
: "restore-dialog"
428+
}
424429
title="Confirm Backup Restoration"
425430
createDialog={{
426431
open: restoreDialog.open,
427432
handleClose: () => {
428433
restoreDialog.handleClose();
434+
// Clear state when user manually closes the dialog
429435
setValidationResult(null);
430436
setSelectedBackupFile(null);
431437
setSelectedBackupData(null);
@@ -439,10 +445,8 @@ const Page = () => {
439445
? "Are you sure you want to restore this backup? This will overwrite your current CIPP configuration."
440446
: null,
441447
onSuccess: () => {
442-
restoreDialog.handleClose();
443-
setValidationResult(null);
444-
setSelectedBackupFile(null);
445-
setSelectedBackupData(null);
448+
// Don't auto-close the dialog - let user see the results and close manually
449+
// The dialog will show the API results and user can close when ready
446450
},
447451
}}
448452
relatedQueryKeys={["BackupList", "ScheduledBackup"]}

src/utils/backupValidation.js

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -317,33 +317,31 @@ export const BackupValidator = {
317317
return false;
318318
}
319319

320-
// Must have either:
321-
// 1. PartitionKey and RowKey (Azure Table format)
322-
// 2. id field (some backup formats)
323-
// 3. At least 2 string properties (fallback for partial data)
324-
const hasAzureKeys = row.PartitionKey && row.RowKey;
325-
const hasId = row.id;
326-
const stringProps = Object.values(row).filter((v) => typeof v === "string").length;
327-
328-
if (hasAzureKeys || hasId || stringProps >= 2) {
329-
// Additional checks for obvious corruption
330-
const rowJson = JSON.stringify(row);
331-
332-
// Skip rows that are way too large (likely corrupted)
333-
if (rowJson.length > 10000000) {
334-
// 10MB limit
335-
return false;
336-
}
320+
// Must have all three required properties for CIPP table storage
321+
const hasTable = row.table && typeof row.table === "string";
322+
const hasPartitionKey = row.PartitionKey && typeof row.PartitionKey === "string";
323+
const hasRowKey = row.RowKey && typeof row.RowKey === "string";
337324

338-
// Skip rows with null bytes (always corruption)
339-
if (rowJson.includes("\0")) {
340-
return false;
341-
}
325+
// All three are required for valid CIPP backup row
326+
if (!hasTable || !hasPartitionKey || !hasRowKey) {
327+
return false;
328+
}
342329

343-
return true;
330+
// Additional checks for obvious corruption
331+
const rowJson = JSON.stringify(row);
332+
333+
// Skip rows that are way too large (likely corrupted)
334+
if (rowJson.length > 10000000) {
335+
// 10MB limit
336+
return false;
344337
}
345338

346-
return false;
339+
// Skip rows with null bytes (always corruption)
340+
if (rowJson.includes("\0")) {
341+
return false;
342+
}
343+
344+
return true;
347345
},
348346

349347
/**
@@ -354,11 +352,20 @@ export const BackupValidator = {
354352
return "Not a valid object";
355353
}
356354

357-
if (!row.PartitionKey && !row.RowKey && !row.id) {
358-
const stringProps = Object.values(row).filter((v) => typeof v === "string").length;
359-
if (stringProps < 2) {
360-
return "Missing required identifiers and insufficient data";
361-
}
355+
// Check for missing required CIPP backup properties
356+
const missingFields = [];
357+
if (!row.table || typeof row.table !== "string") {
358+
missingFields.push("table");
359+
}
360+
if (!row.PartitionKey || typeof row.PartitionKey !== "string") {
361+
missingFields.push("PartitionKey");
362+
}
363+
if (!row.RowKey || typeof row.RowKey !== "string") {
364+
missingFields.push("RowKey");
365+
}
366+
367+
if (missingFields.length > 0) {
368+
return `Missing required fields: ${missingFields.join(", ")}`;
362369
}
363370

364371
const rowJson = JSON.stringify(row);

0 commit comments

Comments
 (0)