UNPKG

@clerk/chrome-extension

Version:

Clerk SDK for Chrome extensions

516 lines (496 loc) • 17.8 kB
import { Clerk } from '@clerk/clerk-js/no-rhc'; import browser2 from 'webextension-polyfill'; var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // ../shared/dist/chunk-DL452J2I.mjs function isClerkAPIResponseError(err) { return "clerkError" in err; } function isClerkRuntimeError(err) { return "clerkRuntimeError" in err; } var ClerkRuntimeError = class _ClerkRuntimeError extends Error { constructor(message, { code }) { const prefix = "\u{1F512} Clerk:"; const regex = new RegExp(prefix.replace(" ", "\\s*"), "i"); const sanitized = message.replace(regex, ""); const _message = `${prefix} ${sanitized.trim()} (code="${code}") `; super(_message); this.toString = () => { return `[${this.name}] Message:${this.message}`; }; Object.setPrototypeOf(this, _ClerkRuntimeError.prototype); this.code = code; this.message = _message; this.clerkRuntimeError = true; this.name = "ClerkRuntimeError"; } }; var DefaultMessages = Object.freeze({ InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`, InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid. You can get your Publishable key at https://dashboard.clerk.com/last-active?path=api-keys. (key={{key}})`, MissingPublishableKeyErrorMessage: `Missing publishableKey. You can get your key at https://dashboard.clerk.com/last-active?path=api-keys.`, MissingSecretKeyErrorMessage: `Missing secretKey. You can get your key at https://dashboard.clerk.com/last-active?path=api-keys.`, MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider` }); function buildErrorThrower({ packageName, customMessages }) { let pkg = packageName; const messages = { ...DefaultMessages, ...customMessages }; function buildMessage(rawMessage, replacements) { if (!replacements) { return `${pkg}: ${rawMessage}`; } let msg = rawMessage; const matches = rawMessage.matchAll(/{{([a-zA-Z0-9-_]+)}}/g); for (const match of matches) { const replacement = (replacements[match[1]] || "").toString(); msg = msg.replace(`{{${match[1]}}}`, replacement); } return `${pkg}: ${msg}`; } return { setPackageName({ packageName: packageName2 }) { if (typeof packageName2 === "string") { pkg = packageName2; } return this; }, setMessages({ customMessages: customMessages2 }) { Object.assign(messages, customMessages2 || {}); return this; }, throwInvalidPublishableKeyError(params) { throw new Error(buildMessage(messages.InvalidPublishableKeyErrorMessage, params)); }, throwInvalidProxyUrl(params) { throw new Error(buildMessage(messages.InvalidProxyUrlErrorMessage, params)); }, throwMissingPublishableKeyError() { throw new Error(buildMessage(messages.MissingPublishableKeyErrorMessage)); }, throwMissingSecretKeyError() { throw new Error(buildMessage(messages.MissingSecretKeyErrorMessage)); }, throwMissingClerkProviderError(params) { throw new Error(buildMessage(messages.MissingClerkProvider, params)); }, throw(message) { throw new Error(buildMessage(message)); } }; } // ../shared/dist/chunk-7ELT755Q.mjs var __defProp2 = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); // ../shared/dist/chunk-7FNX7RWY.mjs var noop = (..._args) => { }; // ../shared/dist/chunk-TETGTEI2.mjs var isomorphicAtob = (data) => { if (typeof atob !== "undefined" && typeof atob === "function") { return atob(data); } else if (typeof global !== "undefined" && global.Buffer) { return new global.Buffer(data, "base64").toString(); } return data; }; // ../shared/dist/chunk-I6MTSTOF.mjs var DEV_OR_STAGING_SUFFIXES = [ ".lcl.dev", ".stg.dev", ".lclstage.dev", ".stgstage.dev", ".dev.lclclerk.com", ".stg.lclclerk.com", ".accounts.lclclerk.com", "accountsstage.dev", "accounts.dev" ]; // ../shared/dist/chunk-NJGRVCG7.mjs var PUBLISHABLE_KEY_LIVE_PREFIX = "pk_live_"; var PUBLISHABLE_KEY_TEST_PREFIX = "pk_test_"; function parsePublishableKey(key, options = {}) { key = key || ""; if (!key || !isPublishableKey(key)) { if (options.fatal && !key) { throw new Error( "Publishable key is missing. Ensure that your publishable key is correctly configured. Double-check your environment configuration for your keys, or access them here: https://dashboard.clerk.com/last-active?path=api-keys" ); } if (options.fatal && !isPublishableKey(key)) { throw new Error("Publishable key not valid."); } return null; } const instanceType = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) ? "production" : "development"; let frontendApi = isomorphicAtob(key.split("_")[2]); frontendApi = frontendApi.slice(0, -1); if (options.proxyUrl) { frontendApi = options.proxyUrl; } else if (instanceType !== "development" && options.domain) { frontendApi = `clerk.${options.domain}`; } return { instanceType, frontendApi }; } function isPublishableKey(key) { key = key || ""; const hasValidPrefix = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) || key.startsWith(PUBLISHABLE_KEY_TEST_PREFIX); const hasValidFrontendApiPostfix = isomorphicAtob(key.split("_")[2] || "").endsWith("$"); return hasValidPrefix && hasValidFrontendApiPostfix; } function createDevOrStagingUrlCache() { const devOrStagingUrlCache = /* @__PURE__ */ new Map(); return { isDevOrStagingUrl: (url) => { if (!url) { return false; } const hostname = typeof url === "string" ? url : url.hostname; let res = devOrStagingUrlCache.get(hostname); if (res === void 0) { res = DEV_OR_STAGING_SUFFIXES.some((s) => hostname.endsWith(s)); devOrStagingUrlCache.set(hostname, res); } return res; } }; } // src/types.ts var SCOPE = { BACKGROUND: "background" }; // ../shared/dist/chunk-K64INQ4C.mjs var DEV_BROWSER_JWT_KEY = "__clerk_db_jwt"; // src/internal/constants.ts var AUTH_HEADER = { PRODUCTION: "Authorization", DEVELOPMENT: "Clerk-Db-Jwt" }; var CLIENT_JWT_KEY = "__client"; var DEFAULT_LOCAL_HOST_PERMISSION = "http://localhost"; var STORAGE_KEY_CLIENT_JWT = "__clerk_client_jwt"; // src/internal/utils/errors.ts var errorLogger = (err) => console.error(err, err.stack); var errorThrower = buildErrorThrower({ packageName: "@clerk/chrome-extension" }); var missingManifestKeyError = (key) => `Missing \`${key}\` entry in manifest.json`; function assertPublishableKey(publishableKey) { if (!publishableKey) { errorThrower.throwMissingPublishableKeyError(); } } // ../shared/dist/chunk-KS5GUWZX.mjs var workerTimers_worker_default = 'const respond=r=>{self.postMessage(r)},workerToTabIds={};self.addEventListener("message",r=>{const e=r.data;switch(e.type){case"setTimeout":workerToTabIds[e.id]=setTimeout(()=>{respond({id:e.id}),delete workerToTabIds[e.id]},e.ms);break;case"clearTimeout":workerToTabIds[e.id]&&(clearTimeout(workerToTabIds[e.id]),delete workerToTabIds[e.id]);break;case"setInterval":workerToTabIds[e.id]=setInterval(()=>{respond({id:e.id})},e.ms);break;case"clearInterval":workerToTabIds[e.id]&&(clearInterval(workerToTabIds[e.id]),delete workerToTabIds[e.id]);break}});\n'; var createWebWorker = (source, opts = {}) => { if (typeof Worker === "undefined") { return null; } try { const blob = new Blob([source], { type: "application/javascript; charset=utf-8" }); const workerScript = globalThis.URL.createObjectURL(blob); return new Worker(workerScript, opts); } catch (e) { console.warn("Clerk: Cannot create worker from blob. Consider adding worker-src blob:; to your CSP"); return null; } }; var fallbackTimers = () => { const setTimeout = globalThis.setTimeout.bind(globalThis); const setInterval = globalThis.setInterval.bind(globalThis); const clearTimeout = globalThis.clearTimeout.bind(globalThis); const clearInterval = globalThis.clearInterval.bind(globalThis); return { setTimeout, setInterval, clearTimeout, clearInterval, cleanup: noop }; }; var createWorkerTimers = () => { let id = 0; const generateId = () => id++; const callbacks = /* @__PURE__ */ new Map(); const post = (w, p) => w == null ? void 0 : w.postMessage(p); const handleMessage = (e) => { var _a; (_a = callbacks.get(e.data.id)) == null ? void 0 : _a(); }; let worker = createWebWorker(workerTimers_worker_default, { name: "clerk-timers" }); worker == null ? void 0 : worker.addEventListener("message", handleMessage); if (!worker) { return fallbackTimers(); } const init = () => { if (!worker) { worker = createWebWorker(workerTimers_worker_default, { name: "clerk-timers" }); worker == null ? void 0 : worker.addEventListener("message", handleMessage); } }; const cleanup = () => { if (worker) { worker.terminate(); worker = null; callbacks.clear(); } }; const setTimeout = (cb, ms) => { init(); const id2 = generateId(); callbacks.set(id2, () => { cb(); callbacks.delete(id2); }); post(worker, { type: "setTimeout", id: id2, ms }); return id2; }; const setInterval = (cb, ms) => { init(); const id2 = generateId(); callbacks.set(id2, cb); post(worker, { type: "setInterval", id: id2, ms }); return id2; }; const clearTimeout = (id2) => { init(); callbacks.delete(id2); post(worker, { type: "clearTimeout", id: id2 }); }; const clearInterval = (id2) => { init(); callbacks.delete(id2); post(worker, { type: "clearInterval", id: id2 }); }; return { setTimeout, setInterval, clearTimeout, clearInterval, cleanup }; }; // ../shared/dist/chunk-EK64A5LG.mjs function Poller({ delayInMs } = { delayInMs: 1e3 }) { const workerTimers = createWorkerTimers(); let timerId; let stopped = false; const stop = () => { if (timerId) { workerTimers.clearTimeout(timerId); workerTimers.cleanup(); } stopped = true; }; const run = async (cb) => { stopped = false; await cb(stop); if (stopped) { return; } timerId = workerTimers.setTimeout(() => { void run(cb); }, delayInMs); }; return { run, stop }; } function ensureFormattedUrl(url) { return url.startsWith("http") ? url : `https://${url}`; } async function getClientCookie({ url, name }) { return await browser2.cookies.get({ name, url: ensureFormattedUrl(url) }); } // src/internal/utils/jwt-handler.ts function shouldSync(sync, _params) { return Boolean(sync); } function JWTHandler(store, params) { const { sync, frontendApi, ...cookieParams } = params; const CACHE_KEY = store.createKey(frontendApi, STORAGE_KEY_CLIENT_JWT, "v2"); const set = async (value) => { return await store.set(CACHE_KEY, value).catch(errorLogger); }; const remove = async () => { return await store.remove(CACHE_KEY).catch(errorLogger); }; const get = async () => { if (shouldSync(sync)) { const syncedJWT = await getClientCookie(cookieParams).catch(errorLogger); if (syncedJWT) { await set(syncedJWT.value); return syncedJWT.value; } } return await store.get(CACHE_KEY); }; const poll = async (delayInMs = 1500) => { const { run, stop } = Poller({ delayInMs }); void run(async () => { const currentJWT = await get(); if (currentJWT) { stop(); } }); }; return { get, poll, set, remove }; } // src/internal/utils/manifest.ts function validateRootManifestKey(manifest, key) { if (!manifest[key]) { errorThrower.throw(missingManifestKeyError(key)); } } function validateManifestPermission(manifest, key) { var _a; if (!((_a = manifest.permissions) == null ? void 0 : _a.includes(key))) { errorThrower.throw(missingManifestKeyError(`permissions.${key}`)); } } function hasAdditionalFeatures(features) { return Boolean(features) && Object.keys(features).length > 0; } function validateManifest(manifest, features) { validateRootManifestKey(manifest, "permissions"); validateManifestPermission(manifest, "storage"); if (!hasAdditionalFeatures(features)) { return; } if (features.background) { validateRootManifestKey(manifest, "background"); } if (features.sync) { validateManifestPermission(manifest, "cookies"); validateRootManifestKey(manifest, "host_permissions"); } } // src/internal/utils/request-handler.ts function requestHandler(jwtHandler, { isProd }) { const handler = async (requestInit) => { requestInit.credentials = "omit"; const currentJWT = await jwtHandler.get(); if (!currentJWT) { return; } if (isProd) { prodHandler(requestInit, currentJWT); } else { devHandler(requestInit, currentJWT); } }; return handler; } function devHandler(requestInit, jwt) { var _a; (_a = requestInit.url) == null ? void 0 : _a.searchParams.append("__clerk_db_jwt", jwt); } function prodHandler(requestInit, jwt) { var _a; (_a = requestInit.url) == null ? void 0 : _a.searchParams.append("_is_native", "1"); requestInit.headers.set(AUTH_HEADER.PRODUCTION, `Bearer ${jwt}`); } // src/internal/utils/response-handler.ts function responseHandler(jwtHandler, { isProd }) { const handler = async (_, response) => { if (isProd) { await prodHandler2(response, jwtHandler); } else { await devHandler2(response, jwtHandler); } }; return handler; } async function devHandler2(response, jwtHandler) { const header = response == null ? void 0 : response.headers.get(AUTH_HEADER.DEVELOPMENT); if (header) { await jwtHandler.set(header); } else { await jwtHandler.remove(); } } async function prodHandler2(response, jwtHandler) { const header = response == null ? void 0 : response.headers.get(AUTH_HEADER.PRODUCTION); if (header == null ? void 0 : header.startsWith("Bearer")) { const jwt = header.split(" ")[1] || void 0; if (jwt) { await jwtHandler.set(jwt); } else { await jwtHandler.remove(); } } else if (header) { await jwtHandler.set(header); } } var createKey = (...keys) => keys.filter(Boolean).join("|"); var createBrowserStorageCache = (opts = {}) => { const __storageArea = opts.storageArea || "local"; return { createKey, get: (key) => browser2.storage[__storageArea].get(key).then((result) => result[key] || void 0), remove: (key) => browser2.storage[__storageArea].remove(key), set: (key, value) => browser2.storage[__storageArea].set({ [key]: value }) }; }; var BrowserStorageCache = createBrowserStorageCache(); // src/internal/clerk.ts var clerk; Clerk.sdkMetadata = { name: "@clerk/chrome-extension", version: "2.1.12-snapshot.v20250115120857" }; async function createClerkClient({ publishableKey, scope, storageCache = BrowserStorageCache, syncHost }) { if (scope === SCOPE.BACKGROUND) { Clerk.mountComponentRenderer = void 0; } if (clerk && scope !== SCOPE.BACKGROUND) { return clerk; } const sync = Boolean(syncHost); const key = parsePublishableKey(publishableKey); assertPublishableKey(key); const isProd = key.instanceType === "production"; const manifest = browser2.runtime.getManifest(); validateManifest(manifest, { background: scope === SCOPE.BACKGROUND, sync }); const url = syncHost ? syncHost : DEFAULT_LOCAL_HOST_PERMISSION; const jwtOptions = { frontendApi: key.frontendApi, name: isProd ? CLIENT_JWT_KEY : DEV_BROWSER_JWT_KEY, sync, url }; const jwt = JWTHandler(storageCache, jwtOptions); clerk = new Clerk(publishableKey); clerk.__unstable__onAfterResponse(responseHandler(jwt, { isProd })); clerk.__unstable__onBeforeRequest(requestHandler(jwt, { isProd })); return clerk; } export { ClerkRuntimeError, SCOPE, __export, __export2, __privateGet, __privateMethod, __privateSet, __reExport, buildErrorThrower, createClerkClient, createDevOrStagingUrlCache, isClerkAPIResponseError, isClerkRuntimeError, isPublishableKey, noop }; //# sourceMappingURL=chunk-76WEVLXO.js.map //# sourceMappingURL=chunk-76WEVLXO.js.map