From 03042bb49caaf43c0643ab3c76874d07ac3b398d Mon Sep 17 00:00:00 2001 From: lucaronin Date: Sun, 19 Apr 2026 23:27:57 +0200 Subject: [PATCH] fix: normalize shipped telemetry secrets --- .github/workflows/release-stable.yml | 7 ++++++- .github/workflows/release.yml | 7 ++++++- src-tauri/src/telemetry.rs | 17 ++++++++++++++++- src/lib/telemetryConfig.test.ts | 12 ++++++++++++ src/lib/telemetryConfig.ts | 12 ++++++++++-- 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index 5a61687e..77db4f93 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -145,8 +145,13 @@ jobs: value = value[1:-1].strip() return value + def normalize_http_like(value: str) -> str: + if "://" in value: + return value + return f"https://{value}" + def is_http_url(value: str) -> bool: - parsed = urlparse(value) + parsed = urlparse(normalize_http_like(value)) return parsed.scheme in {"http", "https"} and bool(parsed.netloc) values = { diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee424091..dcff5ec2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -188,8 +188,13 @@ jobs: value = value[1:-1].strip() return value + def normalize_http_like(value: str) -> str: + if "://" in value: + return value + return f"https://{value}" + def is_http_url(value: str) -> bool: - parsed = urlparse(value) + parsed = urlparse(normalize_http_like(value)) return parsed.scheme in {"http", "https"} and bool(parsed.netloc) values = { diff --git a/src-tauri/src/telemetry.rs b/src-tauri/src/telemetry.rs index 2528aece..62a28663 100644 --- a/src-tauri/src/telemetry.rs +++ b/src-tauri/src/telemetry.rs @@ -31,8 +31,17 @@ fn normalize_embedded_env(raw: Option<&str>) -> Option { } } +fn normalize_http_like_value(value: &str) -> String { + if value.contains("://") { + value.to_string() + } else { + format!("https://{value}") + } +} + fn parse_embedded_sentry_dsn(raw: Option<&str>) -> Option { - normalize_embedded_env(raw)?.parse().ok() + let normalized = normalize_embedded_env(raw)?; + normalize_http_like_value(&normalized).parse().ok() } /// Initialize Sentry if the user has opted in to crash reporting. @@ -134,6 +143,12 @@ mod tests { assert!(parsed.is_some()); } + #[test] + fn test_parse_embedded_sentry_dsn_accepts_scheme_less_value() { + let parsed = parse_embedded_sentry_dsn(Some("public@example.ingest.sentry.io/1")); + assert!(parsed.is_some()); + } + #[test] fn test_parse_embedded_sentry_dsn_rejects_invalid_value() { let parsed = parse_embedded_sentry_dsn(Some("not a dsn")); diff --git a/src/lib/telemetryConfig.test.ts b/src/lib/telemetryConfig.test.ts index c74b839f..5a62aa76 100644 --- a/src/lib/telemetryConfig.test.ts +++ b/src/lib/telemetryConfig.test.ts @@ -41,6 +41,18 @@ describe('resolveFrontendTelemetryConfig', () => { }).posthogHost).toBe(defaultPostHogHost) }) + it('adds https to scheme-less DSNs and PostHog hosts', () => { + expect(resolveFrontendTelemetryConfig({ + VITE_SENTRY_DSN: 'public@example.ingest.sentry.io/123456', + VITE_POSTHOG_KEY: 'phc_test_key', + VITE_POSTHOG_HOST: 'eu.i.posthog.com', + })).toEqual({ + sentryDsn: 'https://public@example.ingest.sentry.io/123456', + posthogKey: 'phc_test_key', + posthogHost: 'https://eu.i.posthog.com', + }) + }) + it('drops invalid Sentry DSNs instead of passing them to the SDK', () => { expect(resolveFrontendTelemetryConfig({ VITE_SENTRY_DSN: 'not a dsn', diff --git a/src/lib/telemetryConfig.ts b/src/lib/telemetryConfig.ts index e742a375..5168a841 100644 --- a/src/lib/telemetryConfig.ts +++ b/src/lib/telemetryConfig.ts @@ -41,13 +41,21 @@ function isHttpUrl(value: string): boolean { } } +function normalizeHttpLikeValue(value: string): string { + if (!value) return '' + if (/^[a-z][a-z\d+\-.]*:\/\//i.test(value)) return value + return `https://${value}` +} + function normalizeSentryDsn(value: string): string { - return isHttpUrl(value) ? value : '' + const normalized = normalizeHttpLikeValue(value) + return isHttpUrl(normalized) ? normalized : '' } function normalizePostHogHost(value: string): string | null { if (!value) return DEFAULT_POSTHOG_HOST - return isHttpUrl(value) ? value : null + const normalized = normalizeHttpLikeValue(value) + return isHttpUrl(normalized) ? normalized : null } export function resolveFrontendTelemetryConfig(