diff --git a/src/helpers/ServiceWorkerHelper.ts b/src/helpers/ServiceWorkerHelper.ts index 7bf731faf..970d0a16f 100755 --- a/src/helpers/ServiceWorkerHelper.ts +++ b/src/helpers/ServiceWorkerHelper.ts @@ -12,6 +12,7 @@ import { OutcomesConfig } from "../models/Outcomes"; import OutcomesHelper from './shared/OutcomesHelper'; import { cancelableTimeout, CancelableTimeoutPromise } from './sw/CancelableTimeout'; import { OSServiceWorkerFields } from "../service-worker/types"; +import Utils from "../context/shared/utils/Utils"; declare var self: ServiceWorkerGlobalScope & OSServiceWorkerFields; @@ -36,6 +37,14 @@ export default class ServiceWorkerHelper { return ServiceWorkerHelper.appendServiceWorkerParams(workerFullPath, appId); } + public static getPossibleServiceWorkerHrefs( + config: ServiceWorkerManagerConfig, + appId: string + ): string[] { + const workerFullPaths = [config.workerAPath.getFullPath(), config.workerBPath.getFullPath()]; + return workerFullPaths.map((href) => ServiceWorkerHelper.appendServiceWorkerParams(href, appId)); + } + private static appendServiceWorkerParams(workerFullPath: string, appId: string): string { const fullPath = new URL(workerFullPath, OneSignalUtils.getBaseUrl()).href; const appIdHasQueryParam = Utils.encodeHashAsUriComponent({appId}); diff --git a/src/managers/ServiceWorkerManager.ts b/src/managers/ServiceWorkerManager.ts index 35e7b50e4..6d2225e83 100644 --- a/src/managers/ServiceWorkerManager.ts +++ b/src/managers/ServiceWorkerManager.ts @@ -167,10 +167,46 @@ export class ServiceWorkerManager { return permission === "granted"; } - // 5. We have a OneSignal ServiceWorker installed, is there an update? + // 5. We have a OneSignal ServiceWorker installed, but did the path or scope of the ServiceWorker change? + if (await this.changedServiceWorkerParams()) { + return true; + } + + // 6. We have a OneSignal ServiceWorker installed, is there an update? return this.workerNeedsUpdate(); } + private async changedServiceWorkerParams(): Promise { + // 1. No workerRegistration + const workerRegistration = await this.context.serviceWorkerManager.getRegistration(); + if (!workerRegistration) { + Log.info("[changedServiceWorkerParams] workerRegistration not found at scope", this.config.registrationOptions.scope); + return true; + } + + // 2. Different scope + const existingSwScope = new URL(workerRegistration.scope).pathname + const configuredSwScope = this.config.registrationOptions.scope; + if (existingSwScope != configuredSwScope) { + Log.info("[changedServiceWorkerParams] ServiceWorker scope changing", { a_old: existingSwScope, b_new: configuredSwScope}); + return true; + } + + // 3. Different href?, asking if (path + filename [A or B] + queryParams) is different + const availableWorker = ServiceWorkerUtilHelper.getAvailableServiceWorker(workerRegistration); + const serviceWorkerHrefs = ServiceWorkerHelper.getPossibleServiceWorkerHrefs( + this.config, + this.context.appConfig.appId + ); + // We don't care if the only differences is between OneSignal's A(Woker) vs B(WorkerUpdater) filename. + if (serviceWorkerHrefs.indexOf(availableWorker?.scriptURL || "") === -1) { + Log.info("[changedServiceWorkerParams] ServiceWorker herf changing:", { a_old: availableWorker?.scriptURL, b_new: serviceWorkerHrefs }); + return true; + } + + return false; + } + /** * Performs a service worker update by swapping out the current service worker * with a content-identical but differently named alternate service worker