@sesamy/sesamy-js 1.114.0 → 1.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap.iife.js +1 -0
- package/dist/bootstrap.mjs +37 -0
- package/dist/capsule-plugin.iife.js +1 -1
- package/dist/capsule-plugin.mjs +33 -19
- package/dist/sesamy-js.cjs +7 -7
- package/dist/sesamy-js.d.ts +14 -0
- package/dist/sesamy-js.iife.js +7 -7
- package/dist/sesamy-js.mjs +1208 -1110
- package/package.json +7 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var sesamyBootstrap=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){let t=e.namespace||`sesamy`,n=e.fallbackSrc,r=e.src||`https://scripts.sesamy.com/s/`+e.clientId+`/sesamy-js/`+(e.version||`stable`),i=window;if(!e.skipAuthPrefetch&&!i.__sesamyBoot){let t=null;try{let e=sessionStorage.getItem(`sesamy:userinfo`);if(e){let n=JSON.parse(e),r=n._cachedAt;r&&Date.now()-r<=36e5&&(t=n)}}catch{}t?i.__sesamyBoot=Promise.resolve(t):(`; `+document.cookie).indexOf(`; sesamy_is_authenticated=true`)>=0&&(i.__sesamyBoot=fetch((e.apiBaseUrl||``)+`/auth/userinfo`,{credentials:`include`,headers:{Accept:`application/json`}}).then(e=>e.ok?e.json():null).catch(()=>null))}let a=!1,o=()=>{if(a||!n||i[t])return;a=!0;let e=document.createElement(`script`);e.src=n,e.async=!0,document.head.appendChild(e)},s=document.createElement(`script`);s.src=r,s.async=!0,s.onerror=o,document.head.appendChild(s),n&&setTimeout(o,e.fallbackTimeoutMs||3e3)}function n(e){return`(`+t.toString()+`)(`+JSON.stringify(e)+`);`}if(typeof window<`u`){window.sesamyBootstrap=t;try{let e=document.getElementById(`sesamy-js`),n=e&&e.textContent?JSON.parse(e.textContent):null;n&&n.clientId&&t({clientId:n.clientId})}catch{}}return e.renderBootstrapScript=n,e.sesamyBootstrap=t,e})({});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/bootstrap.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
let t = e.namespace || "sesamy", n = e.fallbackSrc, r = e.src || "https://scripts.sesamy.com/s/" + e.clientId + "/sesamy-js/" + (e.version || "stable"), i = window;
|
|
4
|
+
if (!e.skipAuthPrefetch && !i.__sesamyBoot) {
|
|
5
|
+
let t = null;
|
|
6
|
+
try {
|
|
7
|
+
let e = sessionStorage.getItem("sesamy:userinfo");
|
|
8
|
+
if (e) {
|
|
9
|
+
let n = JSON.parse(e), r = n._cachedAt;
|
|
10
|
+
r && Date.now() - r <= 36e5 && (t = n);
|
|
11
|
+
}
|
|
12
|
+
} catch {}
|
|
13
|
+
t ? i.__sesamyBoot = Promise.resolve(t) : ("; " + document.cookie).indexOf("; sesamy_is_authenticated=true") >= 0 && (i.__sesamyBoot = fetch((e.apiBaseUrl || "") + "/auth/userinfo", {
|
|
14
|
+
credentials: "include",
|
|
15
|
+
headers: { Accept: "application/json" }
|
|
16
|
+
}).then((e) => e.ok ? e.json() : null).catch(() => null));
|
|
17
|
+
}
|
|
18
|
+
let a = !1, o = () => {
|
|
19
|
+
if (a || !n || i[t]) return;
|
|
20
|
+
a = !0;
|
|
21
|
+
let e = document.createElement("script");
|
|
22
|
+
e.src = n, e.async = !0, document.head.appendChild(e);
|
|
23
|
+
}, s = document.createElement("script");
|
|
24
|
+
s.src = r, s.async = !0, s.onerror = o, document.head.appendChild(s), n && setTimeout(o, e.fallbackTimeoutMs || 3e3);
|
|
25
|
+
}
|
|
26
|
+
function t(t) {
|
|
27
|
+
return "(" + e.toString() + ")(" + JSON.stringify(t) + ");";
|
|
28
|
+
}
|
|
29
|
+
if (typeof window < "u") {
|
|
30
|
+
window.sesamyBootstrap = e;
|
|
31
|
+
try {
|
|
32
|
+
let t = document.getElementById("sesamy-js"), n = t && t.textContent ? JSON.parse(t.textContent) : null;
|
|
33
|
+
n && n.clientId && e({ clientId: n.clientId });
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { t as renderBootstrapScript, e as sesamyBootstrap };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var capsulePlugin=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){let t=e.length%4,n=(t?e+`=`.repeat(4-t):e).replace(/-/g,`+`).replace(/_/g,`/`),r=atob(n),i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function n(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``)}var r=new Uint8Array([1,0,1]),i=`dca-keys`,a=`keypair`,o=`default`,s=`dca-wrap-keys`,c=`wrap-keys`;function l(){let e=null;function t(){return e||=new Promise((e,t)=>{let n=indexedDB.open(s,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(c)||e.createObjectStore(c)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),e}return{async get(e){if(typeof indexedDB>`u`)return null;try{let n=await t();return await new Promise(t=>{let r=n.transaction(c,`readonly`).objectStore(c).get(e);r.onsuccess=()=>t(r.result??null),r.onerror=()=>t(null)})}catch{return null}},async set(e,n){if(!(typeof indexedDB>`u`))try{let r=await t();await new Promise((t,i)=>{let a=r.transaction(c,`readwrite`);a.objectStore(c).put(n,e),a.oncomplete=()=>t(),a.onerror=()=>i(a.error)})}catch{}}}}var u=class e{fetchFn;unlockFn;wrapKeyCache;clientBound;rsaKeySize;keyDbName;keyPairPromise=null;accessCheck;paywallFn;constructor(e={}){this.fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this.unlockFn=e.unlockFn,this.wrapKeyCache=e.wrapKeyCache===!1?void 0:e.wrapKeyCache??l(),this.clientBound=e.clientBound??!1,this.rsaKeySize=e.rsaKeySize??2048,this.keyDbName=e.keyDbName??i,this.accessCheck=e.accessCheck,this.paywallFn=e.paywallFn}parsePage(e){let t=(e??document).querySelector(`script.dca-manifest`);if(!t)throw Error(`DCA: <script class="dca-manifest"> not found`);return{manifest:JSON.parse(t.textContent??``)}}parseJsonResponse(e){return{manifest:e}}static hasDcaContent(e){return(e??document).querySelector(`script.dca-manifest`)!==null}async unlock(e,t,n){let r=e.manifest.issuers[t];if(!r)throw Error(`DCA: issuer "${t}" not found in manifest.issuers`);let i={resourceJWT:e.manifest.resourceJWT,keys:r.keys,...n};if(this.clientBound&&(i.clientPublicKey=await this.getPublicKey()),this.unlockFn)return this.unlockFn(r.unlockUrl,i);let a=await this.fetchFn(r.unlockUrl,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)});if(!a.ok)throw Error(`DCA unlock failed: ${a.status} ${a.statusText}`);return a.json()}async unlockWithShareToken(e,t,n,r){return this.unlock(e,t,{...r,shareToken:n})}static getShareTokenFromUrl(e=`share`){if(typeof window>`u`||typeof URL>`u`)return null;try{return new URL(window.location.href).searchParams.get(e)}catch{return null}}async decrypt(e,n,r,i){let a=e.manifest.content[n];if(!a)throw Error(`DCA: content entry not found for "${n}"`);let o=i??r.keys.find(e=>(e.contentName??`default`)===n);if(!o)throw Error(`DCA: no key provided for "${n}"`);let s=r.transport===`client-bound`,c=o.wrapKeys?Object.fromEntries(o.wrapKeys.map(e=>[e.kid,e.key])):void 0,l;if(o.contentKey)l=s?await this.rsaUnwrapKey(o.contentKey):t(o.contentKey);else if(c){let t=s?await this.unwrapWrapKeyMap(c):c;if(l=await this.unwrapContentKey(a.wrappedContentKey,t),this.wrapKeyCache){let r=this.resolveScope(e,n,o.scope)??n;await this.cacheWrapKeys(r,t)}}else{let t=this.resolveScope(e,n,o.scope)??n,r=await this.getCachedWrapKeys(t,a.wrappedContentKey);if(r)l=await this.unwrapContentKey(a.wrappedContentKey,r);else throw Error(`DCA: no contentKey or wrapKeys available for "${n}"`)}return this.decryptContentBody(a,l)}async decryptContentBody(e,n){let r=t(e.ciphertext),i=t(e.iv),a=new TextEncoder().encode(e.aad),o=await crypto.subtle.importKey(`raw`,n,{name:`AES-GCM`},!1,[`decrypt`]),s=await crypto.subtle.decrypt({name:`AES-GCM`,iv:i,additionalData:a,tagLength:128},o,r);return new TextDecoder().decode(s)}async tryDecryptFromCache(e,t){let n=e.manifest.content[t];if(!n||n.wrappedContentKey.length===0)return null;let r=this.resolveScope(e,t)??t,i=await this.getCachedWrapKeys(r,n.wrappedContentKey);if(!i)return null;try{let e=await this.unwrapContentKey(n.wrappedContentKey,i);return await this.decryptContentBody(n,e)}catch{return null}}async decryptAll(e,t){let n={},r=new Map(t.keys.map(e=>[e.contentName??`default`,e]));for(let[i,a]of r)n[i]=await this.decrypt(e,i,t,a);return n}async processPage(t={}){let n=t.root??document;if(this.accessCheck){let t=e.getPublisherContentId(n);if(!t)return console.warn(`DCA: accessCheck is configured but no publisher-content-id attribute was found on the page. Treating as denied.`),this.paywallFn&&this.paywallFn(t,n),{};let r=await this.accessCheck(t);if(!r||!r.hasAccess)return this.paywallFn&&this.paywallFn(t,n),{}}let r=this.parsePage(n),i=t.issuerName??Object.keys(r.manifest.issuers)[0];if(!i)throw Error(`DCA: no issuers found in manifest.issuers`);let a={},o=[];for(let e of Object.keys(r.manifest.content)){let t=await this.tryDecryptFromCache(r,e);t===null?o.push(e):a[e]=t}if(o.length===0)return a;let s=t.shareToken===void 0?e.getShareTokenFromUrl(t.shareTokenParam):t.shareToken,c=s?await this.unlockWithShareToken(r,i,s,t.additionalBody):await this.unlock(r,i,t.additionalBody);for(let e of o)a[e]=await this.decrypt(r,e,c);return a}renderToPage(e,t){let n=t??document,r=new Set;for(let[t,i]of Object.entries(e)){let e=n.querySelector(`[data-dca-content-name="${CSS.escape(t)}"]`);e&&(e.innerHTML=i,r.add(t))}return r}static getPublisherContentId(e){let t=e??document;if(t instanceof Element){let e=t.closest(`[publisher-content-id]`);if(e)return e.getAttribute(`publisher-content-id`)}let n=t.querySelector(`script.dca-manifest`);if(n){let e=n.closest(`[publisher-content-id]`);if(e)return e.getAttribute(`publisher-content-id`)}return null}observe(e,t){let n=e??document.body,r=new MutationObserver(e=>{for(let n of e)for(let e of Array.from(n.addedNodes)){if(!(e instanceof HTMLElement))continue;let n=[];if(e.matches(`script.dca-manifest`)){let t=e.parentElement??e;n.includes(t)||n.push(t)}let r=e.querySelectorAll(`script.dca-manifest`);for(let t of Array.from(r)){let r=t.parentElement??e;n.includes(r)||n.push(r)}for(let e of n)this.processPage({...t,root:e}).then(t=>{Object.keys(t).length>0&&this.renderToPage(t,e)}).catch(e=>console.error(`DCA auto-process failed:`,e))}});return r.observe(n,{childList:!0,subtree:!0}),r}resolveScope(e,t,n){if(n)return n;for(let n of Object.values(e.manifest.issuers)){let e=n.keys.find(e=>(e.contentName??`default`)===t);if(e)return e.scope}}async unwrapContentKey(e,n){for(let r of e){let e=n[r.kid];if(!e)continue;let i=t(e),a=t(r.iv),o=t(r.ciphertext),s=await crypto.subtle.importKey(`raw`,i,{name:`AES-GCM`},!1,[`decrypt`]);try{let e=await crypto.subtle.decrypt({name:`AES-GCM`,iv:a,tagLength:128},s,o);return new Uint8Array(e)}catch{continue}}throw Error(`DCA: could not unwrap contentKey — no matching wrapKey`)}async cacheWrapKeys(e,t){if(this.wrapKeyCache)for(let[n,r]of Object.entries(t))await this.wrapKeyCache.set(`dca:wk:${e}:${n}`,r)}async getCachedWrapKeys(e,t){if(!this.wrapKeyCache)return null;let n={},r=!1;for(let i of t){let t=await this.wrapKeyCache.get(`dca:wk:${e}:${i.kid}`);t&&(n[i.kid]=t,r=!0)}return r?n:null}async getPublicKey(){let e=await this.ensureKeyPair(),t=await crypto.subtle.exportKey(`spki`,e.publicKey);return n(new Uint8Array(t))}async hasKeyPair(){try{let e=await this.openKeyDb();return await this.idbGet(e,o)!==void 0}catch{return!1}}ensureKeyPair(){return this.keyPairPromise||=this.loadOrCreateKeyPair(),this.keyPairPromise}async loadOrCreateKeyPair(){try{let e=await this.openKeyDb(),t=await this.idbGet(e,o);if(t?.publicKey&&t?.privateKey)return{publicKey:t.publicKey,privateKey:t.privateKey}}catch{}let e=await crypto.subtle.generateKey({name:`RSA-OAEP`,modulusLength:this.rsaKeySize,publicExponent:r,hash:`SHA-256`},!0,[`encrypt`,`decrypt`]),t=await crypto.subtle.exportKey(`jwk`,e.privateKey),n=await crypto.subtle.importKey(`jwk`,t,{name:`RSA-OAEP`,hash:`SHA-256`},!1,[`decrypt`]),i={publicKey:e.publicKey,privateKey:n};try{let t=await this.openKeyDb();await this.idbPut(t,o,{id:o,publicKey:e.publicKey,privateKey:n,createdAt:Date.now(),keySize:this.rsaKeySize})}catch{}return i}async rsaUnwrapKey(e){let n=await this.ensureKeyPair(),r=t(e),i=await crypto.subtle.decrypt({name:`RSA-OAEP`},n.privateKey,r);return new Uint8Array(i)}async unwrapWrapKeyMap(e){let t={};for(let[r,i]of Object.entries(e))t[r]=n(await this.rsaUnwrapKey(i));return t}keyDbPromise=null;openKeyDb(){return this.keyDbPromise||=new Promise((e,t)=>{let n=indexedDB.open(this.keyDbName,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(a)||e.createObjectStore(a,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),this.keyDbPromise}idbGet(e,t){return new Promise((n,r)=>{let i=e.transaction(a,`readonly`).objectStore(a).get(t);i.onsuccess=()=>n(i.result),i.onerror=()=>r(i.error)})}idbPut(e,t,n){return new Promise((t,r)=>{let i=e.transaction(a,`readwrite`).objectStore(a).put(n);i.onsuccess=()=>t(),i.onerror=()=>r(i.error)})}};function d(e){return u.hasDcaContent(e)}var f=function(e){return e.AUTH_INITIALIZED=`sesamyJsAuthInitialized`,e.READY=`sesamyJsReady`,e.AUTHENTICATED=`sesamyJsAuthenticated`,e.LOGOUT=`sesamyJsLogout`,e.CLEAR_CACHE=`sesamyJsClearCache`,e.USER_ATTRIBUTE_CHANGED=`sesamyUserAttributeChanged`,e.PURCHASE=`sesamyJsPurchase`,e.CONSENT_CHANGED=`sesamyJsConsentChanged`,e}({}),p=3600*1e3,m=`dca:`,h=`${m}unlock:`,g=`${m}wk:`,_=!1;function v(){try{let e=[];for(let t=0;t<sessionStorage.length;t++){let n=sessionStorage.key(t);n?.startsWith(m)&&e.push(n)}e.forEach(e=>sessionStorage.removeItem(e))}catch{}}var y=class{async get(e){try{return sessionStorage.getItem(`${g}${e}`)}catch{return null}}async set(e,t){try{sessionStorage.setItem(`${g}${e}`,t)}catch{}}};function b(){let e=null;return{init(t,n){let r=async(e,t)=>{let r=await n.getToken(!1),i=new Headers(t?.headers);return r&&i.set(`Authorization`,`Bearer ${r}`),globalThis.fetch(e,{...t,headers:i,credentials:t?.credentials??`same-origin`})};_||=(window.addEventListener(f.LOGOUT,v),!0),e=new u({fetch:r,clientBound:t.clientBound??!1,rsaKeySize:t.rsaKeySize??2048,unlockFn:async(e,t)=>{let n=JSON.stringify(t),i=`${h}${e}:${n}`;try{let e=sessionStorage.getItem(i);if(e){let{ts:t,data:n}=JSON.parse(e);if(Date.now()-t<p)return n;sessionStorage.removeItem(i)}}catch{}let a=await r(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:n});if(!a.ok)throw Error(`DCA unlock failed: ${a.status} ${a.statusText}`);let o=await a.json();try{sessionStorage.setItem(i,JSON.stringify({ts:Date.now(),data:o}))}catch{}return o},wrapKeyCache:new y})},getDcaClient(){return e},async processPage(){if(!e||!d())return null;let t=await e.processPage();return e.renderToPage(t),t}}}return e.createCapsulePlugin=b,e})({});
|
|
1
|
+
var capsulePlugin=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){let t=e.length%4,n=(t?e+`=`.repeat(4-t):e).replace(/-/g,`+`).replace(/_/g,`/`),r=atob(n),i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function n(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``)}var r=new Uint8Array([1,0,1]),i=`dca-keys`,a=`keypair`,o=`default`,s=`dca-wrap-keys`,c=`wrap-keys`;function l(){let e=null;function t(){return e||=new Promise((e,t)=>{let n=indexedDB.open(s,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(c)||e.createObjectStore(c)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),e}return{async get(e){if(typeof indexedDB>`u`)return null;try{let n=await t();return await new Promise(t=>{let r=n.transaction(c,`readonly`).objectStore(c).get(e);r.onsuccess=()=>t(r.result??null),r.onerror=()=>t(null)})}catch{return null}},async set(e,n){if(!(typeof indexedDB>`u`))try{let r=await t();await new Promise((t,i)=>{let a=r.transaction(c,`readwrite`);a.objectStore(c).put(n,e),a.oncomplete=()=>t(),a.onerror=()=>i(a.error)})}catch{}}}}var u=class e{fetchFn;unlockFn;wrapKeyCache;clientBound;rsaKeySize;keyDbName;keyPairPromise=null;accessCheck;paywallFn;constructor(e={}){this.fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this.unlockFn=e.unlockFn,this.wrapKeyCache=e.wrapKeyCache===!1?void 0:e.wrapKeyCache??l(),this.clientBound=e.clientBound??!1,this.rsaKeySize=e.rsaKeySize??2048,this.keyDbName=e.keyDbName??i,this.accessCheck=e.accessCheck,this.paywallFn=e.paywallFn}parsePage(e){let t=(e??document).querySelector(`script.dca-manifest`);if(!t)throw Error(`DCA: <script class="dca-manifest"> not found`);return{manifest:JSON.parse(t.textContent??``)}}parseJsonResponse(e){return{manifest:e}}static hasDcaContent(e){return(e??document).querySelector(`script.dca-manifest`)!==null}async unlock(e,t,n){let r=e.manifest.issuers[t];if(!r)throw Error(`DCA: issuer "${t}" not found in manifest.issuers`);let i={resourceJWT:e.manifest.resourceJWT,keys:r.keys,...n};if(this.clientBound&&(i.clientPublicKey=await this.getPublicKey()),this.unlockFn)return this.unlockFn(r.unlockUrl,i);let a=await this.fetchFn(r.unlockUrl,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)});if(!a.ok)throw Error(`DCA unlock failed: ${a.status} ${a.statusText}`);return a.json()}async unlockWithShareToken(e,t,n,r){return this.unlock(e,t,{...r,shareToken:n})}static getShareTokenFromUrl(e=`share`){if(typeof window>`u`||typeof URL>`u`)return null;try{return new URL(window.location.href).searchParams.get(e)}catch{return null}}async decrypt(e,n,r,i){let a=e.manifest.content[n];if(!a)throw Error(`DCA: content entry not found for "${n}"`);let o=i??r.keys.find(e=>(e.contentName??`default`)===n);if(!o)throw Error(`DCA: no key provided for "${n}"`);let s=r.transport===`client-bound`,c=o.wrapKeys?Object.fromEntries(o.wrapKeys.map(e=>[e.kid,e.key])):void 0,l;if(o.contentKey)l=s?await this.rsaUnwrapKey(o.contentKey):t(o.contentKey);else if(c){let t=s?await this.unwrapWrapKeyMap(c):c;if(l=await this.unwrapContentKey(a.wrappedContentKey,t),this.wrapKeyCache){let r=this.resolveScope(e,n,o.scope)??n;await this.cacheWrapKeys(r,t)}}else{let t=this.resolveScope(e,n,o.scope)??n,r=await this.getCachedWrapKeys(t,a.wrappedContentKey);if(r)l=await this.unwrapContentKey(a.wrappedContentKey,r);else throw Error(`DCA: no contentKey or wrapKeys available for "${n}"`)}return this.decryptContentBody(a,l)}async decryptContentBody(e,n){let r=t(e.ciphertext),i=t(e.iv),a=new TextEncoder().encode(e.aad),o=await crypto.subtle.importKey(`raw`,n,{name:`AES-GCM`},!1,[`decrypt`]),s=await crypto.subtle.decrypt({name:`AES-GCM`,iv:i,additionalData:a,tagLength:128},o,r);return new TextDecoder().decode(s)}async tryDecryptFromCache(e,t){let n=e.manifest.content[t];if(!n||n.wrappedContentKey.length===0)return null;let r=this.resolveScope(e,t)??t,i=await this.getCachedWrapKeys(r,n.wrappedContentKey);if(!i)return null;try{let e=await this.unwrapContentKey(n.wrappedContentKey,i);return await this.decryptContentBody(n,e)}catch{return null}}async decryptAll(e,t){let n={},r=new Map(t.keys.map(e=>[e.contentName??`default`,e]));for(let[i,a]of r)n[i]=await this.decrypt(e,i,t,a);return n}async processPage(t={}){let n=t.root??document;if(this.accessCheck){let t=e.getPublisherContentId(n);if(!t)return console.warn(`DCA: accessCheck is configured but no publisher-content-id attribute was found on the page. Treating as denied.`),this.paywallFn&&this.paywallFn(t,n),{};let r=await this.accessCheck(t);if(!r||!r.hasAccess)return this.paywallFn&&this.paywallFn(t,n),{}}let r=this.parsePage(n),i=t.issuerName??Object.keys(r.manifest.issuers)[0];if(!i)throw Error(`DCA: no issuers found in manifest.issuers`);let a={},o=[];for(let e of Object.keys(r.manifest.content)){let t=await this.tryDecryptFromCache(r,e);t===null?o.push(e):a[e]=t}if(o.length===0)return a;let s=t.shareToken===void 0?e.getShareTokenFromUrl(t.shareTokenParam):t.shareToken,c=s?await this.unlockWithShareToken(r,i,s,t.additionalBody):await this.unlock(r,i,t.additionalBody);for(let e of o)a[e]=await this.decrypt(r,e,c);return a}renderToPage(e,t){let n=t??document,r=new Set;for(let[t,i]of Object.entries(e)){let e=n.querySelector(`[data-dca-content-name="${CSS.escape(t)}"]`);e&&(e.innerHTML=i,r.add(t))}return r}static getPublisherContentId(e){let t=e??document;if(t instanceof Element){let e=t.closest(`[publisher-content-id]`);if(e)return e.getAttribute(`publisher-content-id`)}let n=t.querySelector(`script.dca-manifest`);if(n){let e=n.closest(`[publisher-content-id]`);if(e)return e.getAttribute(`publisher-content-id`)}return null}observe(e,t){let n=e??document.body,r=new MutationObserver(e=>{for(let n of e)for(let e of Array.from(n.addedNodes)){if(!(e instanceof HTMLElement))continue;let n=[];if(e.matches(`script.dca-manifest`)){let t=e.parentElement??e;n.includes(t)||n.push(t)}let r=e.querySelectorAll(`script.dca-manifest`);for(let t of Array.from(r)){let r=t.parentElement??e;n.includes(r)||n.push(r)}for(let e of n)this.processPage({...t,root:e}).then(t=>{Object.keys(t).length>0&&this.renderToPage(t,e)}).catch(e=>console.error(`DCA auto-process failed:`,e))}});return r.observe(n,{childList:!0,subtree:!0}),r}resolveScope(e,t,n){if(n)return n;for(let n of Object.values(e.manifest.issuers)){let e=n.keys.find(e=>(e.contentName??`default`)===t);if(e)return e.scope}}async unwrapContentKey(e,n){for(let r of e){let e=n[r.kid];if(!e)continue;let i=t(e),a=t(r.iv),o=t(r.ciphertext),s=await crypto.subtle.importKey(`raw`,i,{name:`AES-GCM`},!1,[`decrypt`]);try{let e=await crypto.subtle.decrypt({name:`AES-GCM`,iv:a,tagLength:128},s,o);return new Uint8Array(e)}catch{continue}}throw Error(`DCA: could not unwrap contentKey — no matching wrapKey`)}async cacheWrapKeys(e,t){if(this.wrapKeyCache)for(let[n,r]of Object.entries(t))await this.wrapKeyCache.set(`dca:wk:${e}:${n}`,r)}async getCachedWrapKeys(e,t){if(!this.wrapKeyCache)return null;let n={},r=!1;for(let i of t){let t=await this.wrapKeyCache.get(`dca:wk:${e}:${i.kid}`);t&&(n[i.kid]=t,r=!0)}return r?n:null}async getPublicKey(){let e=await this.ensureKeyPair(),t=await crypto.subtle.exportKey(`spki`,e.publicKey);return n(new Uint8Array(t))}async hasKeyPair(){try{let e=await this.openKeyDb();return await this.idbGet(e,o)!==void 0}catch{return!1}}ensureKeyPair(){return this.keyPairPromise||=this.loadOrCreateKeyPair(),this.keyPairPromise}async loadOrCreateKeyPair(){try{let e=await this.openKeyDb(),t=await this.idbGet(e,o);if(t?.publicKey&&t?.privateKey)return{publicKey:t.publicKey,privateKey:t.privateKey}}catch{}let e=await crypto.subtle.generateKey({name:`RSA-OAEP`,modulusLength:this.rsaKeySize,publicExponent:r,hash:`SHA-256`},!0,[`encrypt`,`decrypt`]),t=await crypto.subtle.exportKey(`jwk`,e.privateKey),n=await crypto.subtle.importKey(`jwk`,t,{name:`RSA-OAEP`,hash:`SHA-256`},!1,[`decrypt`]),i={publicKey:e.publicKey,privateKey:n};try{let t=await this.openKeyDb();await this.idbPut(t,o,{id:o,publicKey:e.publicKey,privateKey:n,createdAt:Date.now(),keySize:this.rsaKeySize})}catch{}return i}async rsaUnwrapKey(e){let n=await this.ensureKeyPair(),r=t(e),i=await crypto.subtle.decrypt({name:`RSA-OAEP`},n.privateKey,r);return new Uint8Array(i)}async unwrapWrapKeyMap(e){let t={};for(let[r,i]of Object.entries(e))t[r]=n(await this.rsaUnwrapKey(i));return t}keyDbPromise=null;openKeyDb(){return this.keyDbPromise||=new Promise((e,t)=>{let n=indexedDB.open(this.keyDbName,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(a)||e.createObjectStore(a,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),this.keyDbPromise}idbGet(e,t){return new Promise((n,r)=>{let i=e.transaction(a,`readonly`).objectStore(a).get(t);i.onsuccess=()=>n(i.result),i.onerror=()=>r(i.error)})}idbPut(e,t,n){return new Promise((t,r)=>{let i=e.transaction(a,`readwrite`).objectStore(a).put(n);i.onsuccess=()=>t(),i.onerror=()=>r(i.error)})}};function d(e){return u.hasDcaContent(e)}var f=function(e){return e.AUTH_INITIALIZED=`sesamyJsAuthInitialized`,e.READY=`sesamyJsReady`,e.AUTHENTICATED=`sesamyJsAuthenticated`,e.LOGOUT=`sesamyJsLogout`,e.CLEAR_CACHE=`sesamyJsClearCache`,e.USER_ATTRIBUTE_CHANGED=`sesamyUserAttributeChanged`,e.PURCHASE=`sesamyJsPurchase`,e.CONSENT_CHANGED=`sesamyJsConsentChanged`,e}({}),p=3600*1e3,m=`dca:`,h=`${m}unlock:`,g=`${m}wk:`,_=[`api2.sesamy.com`,`api.sesamy.com`,`api2.sesamy.dev`,`api.sesamy.dev`],v=!1;function y(){try{let e=[];for(let t=0;t<sessionStorage.length;t++){let n=sessionStorage.key(t);n?.startsWith(m)&&e.push(n)}e.forEach(e=>sessionStorage.removeItem(e))}catch{}}var b=class{async get(e){try{return sessionStorage.getItem(`${g}${e}`)}catch{return null}}async set(e,t){try{sessionStorage.setItem(`${g}${e}`,t)}catch{}}};function x(e,t){if(!t)return e;try{let n=new URL(e);return _.includes(n.hostname)?`${t.replace(/\/$/,``)}${n.pathname}${n.search}`:e}catch{return e}}function S(){let e=null;return{init(t,n){let r=n.apiEndpoint,i=async(e,t)=>{let r=await n.getToken(!1),i=new Headers(t?.headers);return r&&i.set(`Authorization`,`Bearer ${r}`),globalThis.fetch(e,{...t,headers:i,credentials:t?.credentials??`same-origin`})};v||=(window.addEventListener(f.LOGOUT,y),!0),e=new u({fetch:i,clientBound:t.clientBound??!1,rsaKeySize:t.rsaKeySize??2048,unlockFn:async(e,t)=>{let n=x(e,r),a=JSON.stringify(t),o=`${h}${n}:${a}`;try{let e=sessionStorage.getItem(o);if(e){let{ts:t,data:n}=JSON.parse(e);if(Date.now()-t<p)return n;sessionStorage.removeItem(o)}}catch{}let s=await i(n,{method:`POST`,headers:{"Content-Type":`application/json`},body:a});if(!s.ok)throw Error(`DCA unlock failed: ${s.status} ${s.statusText}`);let c=await s.json();try{sessionStorage.setItem(o,JSON.stringify({ts:Date.now(),data:c}))}catch{}return c},wrapKeyCache:new b})},getDcaClient(){return e},async processPage(){if(!e||!d())return null;let t=await e.processPage();return e.renderToPage(t),t}}}return e.createCapsulePlugin=S,e})({});
|
package/dist/capsule-plugin.mjs
CHANGED
|
@@ -341,8 +341,13 @@ function u(e) {
|
|
|
341
341
|
//#region src/types/Events.ts
|
|
342
342
|
var d = /* @__PURE__ */ function(e) {
|
|
343
343
|
return e.AUTH_INITIALIZED = "sesamyJsAuthInitialized", e.READY = "sesamyJsReady", e.AUTHENTICATED = "sesamyJsAuthenticated", e.LOGOUT = "sesamyJsLogout", e.CLEAR_CACHE = "sesamyJsClearCache", e.USER_ATTRIBUTE_CHANGED = "sesamyUserAttributeChanged", e.PURCHASE = "sesamyJsPurchase", e.CONSENT_CHANGED = "sesamyJsConsentChanged", e;
|
|
344
|
-
}({}), f = 3600 * 1e3, p = "dca:", m = `${p}unlock:`, h = `${p}wk:`, g =
|
|
345
|
-
|
|
344
|
+
}({}), f = 3600 * 1e3, p = "dca:", m = `${p}unlock:`, h = `${p}wk:`, g = [
|
|
345
|
+
"api2.sesamy.com",
|
|
346
|
+
"api.sesamy.com",
|
|
347
|
+
"api2.sesamy.dev",
|
|
348
|
+
"api.sesamy.dev"
|
|
349
|
+
], _ = !1;
|
|
350
|
+
function v() {
|
|
346
351
|
try {
|
|
347
352
|
let e = [];
|
|
348
353
|
for (let t = 0; t < sessionStorage.length; t++) {
|
|
@@ -352,7 +357,7 @@ function _() {
|
|
|
352
357
|
e.forEach((e) => sessionStorage.removeItem(e));
|
|
353
358
|
} catch {}
|
|
354
359
|
}
|
|
355
|
-
var
|
|
360
|
+
var y = class {
|
|
356
361
|
async get(e) {
|
|
357
362
|
try {
|
|
358
363
|
return sessionStorage.getItem(`${h}${e}`);
|
|
@@ -366,11 +371,20 @@ var v = class {
|
|
|
366
371
|
} catch {}
|
|
367
372
|
}
|
|
368
373
|
};
|
|
369
|
-
function
|
|
374
|
+
function b(e, t) {
|
|
375
|
+
if (!t) return e;
|
|
376
|
+
try {
|
|
377
|
+
let n = new URL(e);
|
|
378
|
+
return g.includes(n.hostname) ? `${t.replace(/\/$/, "")}${n.pathname}${n.search}` : e;
|
|
379
|
+
} catch {
|
|
380
|
+
return e;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function x() {
|
|
370
384
|
let e = null;
|
|
371
385
|
return {
|
|
372
386
|
init(t, n) {
|
|
373
|
-
let r = async (e, t) => {
|
|
387
|
+
let r = n.apiEndpoint, i = async (e, t) => {
|
|
374
388
|
let r = await n.getToken(!1), i = new Headers(t?.headers);
|
|
375
389
|
return r && i.set("Authorization", `Bearer ${r}`), globalThis.fetch(e, {
|
|
376
390
|
...t,
|
|
@@ -378,36 +392,36 @@ function y() {
|
|
|
378
392
|
credentials: t?.credentials ?? "same-origin"
|
|
379
393
|
});
|
|
380
394
|
};
|
|
381
|
-
|
|
382
|
-
fetch:
|
|
395
|
+
_ ||= (window.addEventListener(d.LOGOUT, v), !0), e = new l({
|
|
396
|
+
fetch: i,
|
|
383
397
|
clientBound: t.clientBound ?? !1,
|
|
384
398
|
rsaKeySize: t.rsaKeySize ?? 2048,
|
|
385
399
|
unlockFn: async (e, t) => {
|
|
386
|
-
let n = JSON.stringify(t),
|
|
400
|
+
let n = b(e, r), a = JSON.stringify(t), o = `${m}${n}:${a}`;
|
|
387
401
|
try {
|
|
388
|
-
let e = sessionStorage.getItem(
|
|
402
|
+
let e = sessionStorage.getItem(o);
|
|
389
403
|
if (e) {
|
|
390
404
|
let { ts: t, data: n } = JSON.parse(e);
|
|
391
405
|
if (Date.now() - t < f) return n;
|
|
392
|
-
sessionStorage.removeItem(
|
|
406
|
+
sessionStorage.removeItem(o);
|
|
393
407
|
}
|
|
394
408
|
} catch {}
|
|
395
|
-
let
|
|
409
|
+
let s = await i(n, {
|
|
396
410
|
method: "POST",
|
|
397
411
|
headers: { "Content-Type": "application/json" },
|
|
398
|
-
body:
|
|
412
|
+
body: a
|
|
399
413
|
});
|
|
400
|
-
if (!
|
|
401
|
-
let
|
|
414
|
+
if (!s.ok) throw Error(`DCA unlock failed: ${s.status} ${s.statusText}`);
|
|
415
|
+
let c = await s.json();
|
|
402
416
|
try {
|
|
403
|
-
sessionStorage.setItem(
|
|
417
|
+
sessionStorage.setItem(o, JSON.stringify({
|
|
404
418
|
ts: Date.now(),
|
|
405
|
-
data:
|
|
419
|
+
data: c
|
|
406
420
|
}));
|
|
407
421
|
} catch {}
|
|
408
|
-
return
|
|
422
|
+
return c;
|
|
409
423
|
},
|
|
410
|
-
wrapKeyCache: new
|
|
424
|
+
wrapKeyCache: new y()
|
|
411
425
|
});
|
|
412
426
|
},
|
|
413
427
|
getDcaClient() {
|
|
@@ -421,4 +435,4 @@ function y() {
|
|
|
421
435
|
};
|
|
422
436
|
}
|
|
423
437
|
//#endregion
|
|
424
|
-
export {
|
|
438
|
+
export { x as createCapsulePlugin };
|