diff --git a/package.json b/package.json index 91af33b3a..d9a3c8ba0 100644 --- a/package.json +++ b/package.json @@ -77,12 +77,12 @@ }, { "path": "./build/releases/OneSignalSDK.page.es6.js", - "limit": "42.7 kB", + "limit": "42.57 kB", "gzip": true }, { "path": "./build/releases/OneSignalSDK.sw.js", - "limit": "12.65 kB", + "limit": "12.51 kB", "gzip": true }, { diff --git a/src/shared/helpers/context.test.ts b/src/shared/helpers/context.test.ts new file mode 100644 index 000000000..3aea63f2d --- /dev/null +++ b/src/shared/helpers/context.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, test } from 'vite-plus/test'; + +import type { AppConfig } from '../config/types'; +import type { ContextInterface } from '../context/types'; +import { getServiceWorkerManager } from './context'; + +const buildContext = (path: string, serviceWorkerPath: string): ContextInterface => + ({ + _appConfig: { + userConfig: { path, serviceWorkerPath }, + } as AppConfig, + }) as ContextInterface; + +const workerPathFor = (path: string, serviceWorkerPath: string): string => { + const manager = getServiceWorkerManager(buildContext(path, serviceWorkerPath)); + return manager['_config'].workerPath._getFullPath(); +}; + +describe('getServiceWorkerManager worker path', () => { + test('joins default root path with worker file name', () => { + expect(workerPathFor('/', 'OneSignalSDKWorker.js')).toBe('/OneSignalSDKWorker.js'); + }); + + test('collapses a leading slash in serviceWorkerPath to avoid a protocol-relative URL', () => { + expect(workerPathFor('/', '/OneSignalSDKWorker.js')).toBe('/OneSignalSDKWorker.js'); + }); + + test('joins a nested path with a trailing slash', () => { + expect(workerPathFor('/push/onesignal/', 'OneSignalSDKWorker.js')).toBe( + '/push/onesignal/OneSignalSDKWorker.js', + ); + }); + + test('normalizes slashes on both sides of the join', () => { + expect(workerPathFor('/push/', '/OneSignalSDKWorker.js')).toBe('/push/OneSignalSDKWorker.js'); + }); +}); diff --git a/src/shared/helpers/context.ts b/src/shared/helpers/context.ts index 3b33513c2..0011a66a9 100644 --- a/src/shared/helpers/context.ts +++ b/src/shared/helpers/context.ts @@ -17,9 +17,12 @@ export function getServiceWorkerManager(context: ContextInterface): ServiceWorke if (config.userConfig) { if (config.userConfig.path) { - serviceWorkerManagerConfig.workerPath = new Path( - `${config.userConfig.path}${config.userConfig.serviceWorkerPath}`, - ); + // Join with exactly one slash. A leading "//" forms a protocol-relative + // URL, which the browser resolves to a different origin and rejects with a + // SecurityError when registering the worker. + const basePath = config.userConfig.path.replace(/\/+$/, ''); + const workerPath = (config.userConfig.serviceWorkerPath ?? '').replace(/^\/+/, ''); + serviceWorkerManagerConfig.workerPath = new Path(`${basePath}/${workerPath}`); } if (config.userConfig.serviceWorkerParam) { serviceWorkerManagerConfig.registrationOptions = config.userConfig.serviceWorkerParam;