3.5 KiB
3.5 KiB
cross-origin — multi-origin Service Worker registration
Purpose
registerCrossOriginPackedResourceServiceWorker lets an application
register a packed-resource Service Worker hosted on a different origin
(typically a CDN subdomain). Before any browser request is dispatched
the helper validates the SW URL's origin against a caller-supplied
allowlist, so attacker-controlled or misconfigured CDN origins cannot
slip past. On success the helper returns both the new registration and
the container's current registration list so multi-tenant apps can
confirm the CDN-origin SW is actually controlling the page.
Features
- Strict allowlist validation BEFORE
register()fires - Parses
swUrlvia theURLconstructor — malformed URLs reject withPACKER_BROWSER.UNAUTHORIZED_ORIGIN - Delegates to
registerPackedResourceServiceWorkerso all the underlying contract (AbortSignal, error wrapping, message resolution) remains intact - Returns the full registration list (parity with
clients.matchAll({ includeUncontrolled: true }))
Usage: Basic
import { registerCrossOriginPackedResourceServiceWorker } from "@suaveplan/packer-browser/utils";
await registerCrossOriginPackedResourceServiceWorker({
swUrl: "https://cdn.example.com/sw.js",
scope: "/packed/",
allowedOrigins: ["https://cdn.example.com"],
});
Usage: Advanced
import {
PACKER_BROWSER_CODES,
PackerBrowserError,
registerCrossOriginPackedResourceServiceWorker,
} from "@suaveplan/packer-browser";
try {
const { registration, registrations } =
await registerCrossOriginPackedResourceServiceWorker({
swUrl: "https://cdn.example.com/sw.js",
scope: "/",
allowedOrigins: [
"https://cdn.example.com",
"https://cdn-fallback.example.com",
],
container: navigator.serviceWorker,
signal: shutdownController.signal,
});
console.log("registered", registration.scope, "of", registrations.length);
} catch (err) {
if (
err instanceof PackerBrowserError &&
err.code === PACKER_BROWSER_CODES.UNAUTHORIZED_ORIGIN
) {
console.warn("Origin not allowed; falling back to first-party SW.");
}
}
API Reference
registerCrossOriginPackedResourceServiceWorker(opts: RegisterCrossOriginOptions): Promise<RegisterCrossOriginResult>opts.swUrl: string— absolute SW URL. Required.opts.scope: string— registration scope. Required.opts.allowedOrigins: ReadonlyArray<string>— exact-string match. Required.opts.container?— injectable container. Default:navigator.serviceWorker.opts.messageResolver?— i18n resolver.opts.signal?— AbortSignal forwarded toregister().- Returns
{ registration, registrations }.
Implementation Notes
- Origin equality is exact-string — there is no host-suffix matching.
Allowlisting both
https://cdn.example.comandhttps://cdn-fallback.example.comis explicit by design. - Malformed
swUrlstrings (relative paths, plain identifiers) yieldUNAUTHORIZED_ORIGIN, notSW_REGISTRATION_FAILED, because the helper deliberately rejects before consulting the container. - The
registrationslist is the fullcontainer.getRegistrations()return value when a container is supplied; without one (e.g. in a Node smoke harness) the underlyingregister()already rejects withSW_REGISTRATION_FAILEDso the caller never sees a partial list.