Skip to content

Commit 2c443de

Browse files
committed
fix: temporarily allow WebDAV cleanup in job export/import
When a job export or import passes safety evaluation, the subsequent WebDAV DELETE (archive cleanup) was still caught by the HTTP middleware's level check. Now the commands add a temporary rule allowing DELETE on Impex paths for the duration of the operation. Also adds SafetyGuard.temporarilyAddRule() for arbitrary temporary rules.
1 parent e9508e9 commit 2c443de

3 files changed

Lines changed: 36 additions & 2 deletions

File tree

packages/b2c-cli/src/commands/job/export.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,15 @@ export default class JobExport extends JobCommand<typeof JobExport> {
184184
} as unknown as SiteArchiveExportResult & {localPath?: string; archiveKept?: boolean};
185185
}
186186

187+
// After safety evaluation passes, temporarily allow WebDAV operations
188+
// that are part of the export flow (download GET, cleanup DELETE on Impex paths).
189+
// Without this, the HTTP middleware would independently block the cleanup DELETE.
190+
const cleanupSafetyRule = this.safetyGuard.temporarilyAddRule({
191+
method: 'DELETE',
192+
path: '**/Impex/**',
193+
action: 'allow',
194+
});
195+
187196
this.log(
188197
t('commands.job.export.exporting', 'Exporting data from {{hostname}}...', {
189198
hostname,
@@ -274,6 +283,8 @@ export default class JobExport extends JobCommand<typeof JobExport> {
274283
);
275284
}
276285
throw error;
286+
} finally {
287+
cleanupSafetyRule();
277288
}
278289
}
279290

packages/b2c-cli/src/commands/job/import.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ export default class JobImport extends JobCommand<typeof JobImport> {
106106
} as unknown as SiteArchiveImportResult;
107107
}
108108

109+
// After safety evaluation passes, temporarily allow WebDAV operations
110+
// that are part of the import flow (upload PUT, cleanup DELETE on Impex paths).
111+
const cleanupSafetyRule = this.safetyGuard.temporarilyAddRule({
112+
method: 'DELETE',
113+
path: '**/Impex/**',
114+
action: 'allow',
115+
});
116+
109117
if (remote) {
110118
this.log(
111119
t('commands.job.import.importingRemote', 'Importing {{target}} from {{hostname}}...', {
@@ -193,6 +201,8 @@ export default class JobImport extends JobCommand<typeof JobImport> {
193201
);
194202
}
195203
throw error;
204+
} finally {
205+
cleanupSafetyRule();
196206
}
197207
}
198208
}

packages/b2c-tooling-sdk/src/safety/safety-guard.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,27 @@ export class SafetyGuard {
192192
*/
193193
temporarilyAllow(operation: SafetyOperation): () => void {
194194
const rule = this.operationToRule(operation);
195+
return this.temporarilyAddRule(rule);
196+
}
197+
198+
/**
199+
* Add a temporary safety rule for a scoped exemption.
200+
*
201+
* Unlike {@link temporarilyAllow} which derives a rule from an operation,
202+
* this accepts an arbitrary rule — useful for granting broad temporary
203+
* access (e.g., allowing WebDAV DELETE on Impex paths during a job export).
204+
*
205+
* Returns a cleanup function that removes the rule.
206+
*/
207+
temporarilyAddRule(rule: SafetyRule): () => void {
195208
this.temporaryAllows.push(rule);
196-
this.logger.trace({rule}, '[SafetyGuard] Added temporary allow');
209+
this.logger.trace({rule}, '[SafetyGuard] Added temporary rule');
197210

198211
return () => {
199212
const idx = this.temporaryAllows.indexOf(rule);
200213
if (idx >= 0) {
201214
this.temporaryAllows.splice(idx, 1);
202-
this.logger.trace({rule}, '[SafetyGuard] Removed temporary allow');
215+
this.logger.trace({rule}, '[SafetyGuard] Removed temporary rule');
203216
}
204217
};
205218
}

0 commit comments

Comments
 (0)