diff --git a/src/push/monitor.ts b/src/push/monitor.ts index d104e80c..4152c425 100644 --- a/src/push/monitor.ts +++ b/src/push/monitor.ts @@ -37,7 +37,7 @@ import { MonitorConfig, } from '../dsl/monitor'; import { PushOptions } from '../common_types'; -import { isParamOptionSupported } from './utils'; +import { isParamOptionSupported, normalizeMonitorName } from './utils'; // Allowed extensions for lightweight monitor files const ALLOWED_LW_EXTENSIONS = ['.yml', '.yaml']; @@ -139,7 +139,10 @@ export async function buildMonitorSchema(monitors: Monitor[], isV2: boolean) { }; if (type === 'browser') { - const outPath = join(bundlePath, config.name + '.zip'); + const outPath = join( + bundlePath, + normalizeMonitorName(config.name) + '.zip' + ); const content = await bundler.build(source.file, outPath); monitor.setContent(content); Object.assign(schema, { content, filter }); diff --git a/src/push/utils.ts b/src/push/utils.ts index 450fa872..ddeff384 100644 --- a/src/push/utils.ts +++ b/src/push/utils.ts @@ -106,3 +106,18 @@ export function isLightweightMonitorSupported( export function isParamOptionSupported(version: string) { return semver.satisfies(version, '>=8.7.2'); } + +/** + * Helper that replaces url paths traversal issues when bundling + */ +export function normalizeMonitorName(p: string, replacement = '_') { + // replace encoded and non encoded dots + p = p.replace(/%2e|\./gi, replacement); + // encoded slashes + p = p.replace(/%2f|%5c/gi, replacement); + // backslashes + p = p.replace(/[/\\]+/g, replacement); + // remove colons + p = p.replace(/[:]+/g, replacement); + return p; +}