@descope/flow-scripts 1.0.11 → 1.0.13
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/.prettierignore +4 -0
- package/.prettierrc +8 -0
- package/dist/arkose.js +1 -0
- package/dist/darwinium.js +1 -1
- package/dist/fingerprint.js +1 -2
- package/dist/fingerprintDescope.js +1 -2
- package/dist/grecaptcha.js +1 -3
- package/dist/hcaptcha.js +1 -1
- package/dist/turnstile.js +1 -3
- package/dist/types.js +1 -0
- package/package.json +7 -7
- package/src/arkose.ts +136 -0
- package/src/darwinium.ts +7 -4
- package/src/fingerprint.ts +3 -1
- package/src/fingerprintDescope.ts +3 -1
- package/src/grecaptcha.ts +6 -3
- package/src/hcaptcha.ts +6 -3
- package/src/index.spec.ts +15 -2
- package/src/turnstile.ts +6 -4
- package/src/types.ts +37 -0
package/.prettierignore
ADDED
package/.prettierrc
ADDED
package/dist/arkose.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.arkose=o())}(this,(function(){"use strict";function e(e,o,n,r){return new(n||(n=Promise))((function(t,s){function d(e){try{a(r.next(e))}catch(e){s(e)}}function i(e){try{a(r.throw(e))}catch(e){s(e)}}function a(e){var o;e.done?t(e.value):(o=e.value,o instanceof n?o:new n((function(e){e(o)}))).then(d,i)}a((r=r.apply(e,o||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;return(o,n,r,t)=>{let s=null,d=!1,i=()=>{};window.onArkoseLoadCallback=e=>{t.debug("Arkose load callback invoked"),(e=>{s=e,s.setConfig({onReady:()=>{t.debug("Arkose ready"),d=!0},onError:e=>{t.warn("Arkose error",e.error),i(new Error("Error loading Arkose enforcement"))},onFailed:e=>{t.warn("Arkose enforcement failed",e),i(!0)},onWarning:e=>{t.warn("Arkose warning",e.warning)},onHide:e=>{e.token&&(t.debug("Arkose hide with token interpreted as cancellation",e),i(!1))},onShow:e=>{t.debug("Arkose show",e)},onShown:e=>{t.debug("Arkose shown",e)},onSuppress:e=>{t.debug("Arkose suppress",e)},onCompleted:e=>{t.debug("Arkose completed",e.token),r(e.token),i(!0)}})})(e)},o.publicKey||t.error("Arkose public key is required");var a;const l=`${(a=o.clientBaseUrl||"https://client-api.arkoselabs.com/v2").endsWith("/")?a:a+"/"}${o.publicKey}/api.js`;return t.debug("Arkose script loading",l),((e,o)=>{const n=document.createElement("script");n.src=e,n.id="arkose-script",n.async=!0,n.defer=!0,n.onload=o,n.setAttribute("data-callback","onArkoseLoadCallback"),document.body.appendChild(n)})(l,(()=>{t.debug("Arkose script loaded"),r(null)})),{id:"arkose",present:()=>e(void 0,void 0,void 0,(function*(){if(!d){t.debug("Arkose module not ready yet");const e=Date.now();for(;!d&&Date.now()-e<5e3;)yield new Promise((e=>setTimeout(e,100)));if(!d)throw t.error("Arkose module failed to become ready in time"),new Error("Arkose module not ready")}t.debug("Arkose module present called");const e=new Promise(((e,o)=>{i=n=>{t.debug("Arkose module finish called"),i=()=>{},"boolean"==typeof n?e(n):o(n)}}));return s.run(),e}))}}}));
|
package/dist/darwinium.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.darwinium=t())}(this,(function(){"use strict";const e={email:"EMAIL",givenName:"FIRST_NAME",familyName:"LAST_NAME",displayName:"FULL_NAME",phone:"TELEPHONE",externalId:"USER_NAME",password:"PASSWORD",newPassword:"PASSWORD",address:"ADDRESS_STREET1"};return(t,n,o)=>{let
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.darwinium=t())}(this,(function(){"use strict";const e={email:"EMAIL",givenName:"FIRST_NAME",familyName:"LAST_NAME",displayName:"FULL_NAME",phone:"TELEPHONE",externalId:"USER_NAME",password:"PASSWORD",newPassword:"PASSWORD",address:"ADDRESS_STREET1"};return(t,n,o,s)=>{let i=null;const r=()=>{let t=[];var o;n.ref.getInputs?t=null==(o=n.ref.getInputs())?void 0:o.flatMap((t=>{const n=t.getAttribute("name")||"";return[{selector:`${t.localName} input`,context:e[n]},{selector:`input[name="${n}"]`,context:e[n]}]})):s.warn("getInputs function is missing, expected the ref to be a Descope Web Component"),i=(e=>{var t;return null===(t=window.dwn)||void 0===t?void 0:t.start({mouse:!0,use_deep_query_selector:!0,key_bm:e})})(t)};return((e,t)=>{const n=document.createElement("script");n.src=e,n.async=!0,n.id="darwinium-script",n.defer=!0,n.onload=t,document.body.appendChild(n)})(t.profilingTagsScriptUrl||"https://cy-began.com/dwnfp.js",(()=>{o(null),r()})),{id:"darwinium",stop:()=>{null==i||i.stop()},start:r,refresh:()=>{const e=null==i?void 0:i.tryCollect();o(e)}}}}));
|
package/dist/fingerprint.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
!function(e,
|
|
2
|
-
/*! Source: (c) FingerprintJS and other contributors | https://dev.fingerprint.com/ */return(e,r,o)=>n(void 0,void 0,void 0,(function*(){try{const{publicApiKey:n,useCloudflareIntegration:r,cloudflareScriptUrl:i,cloudflareEndpointUrl:u}=e;let c=[];c=r&&u?[u,t]:[t];let a=[];if(r&&i){const e=new URL(i);a=[`${e.toString()}?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>`,f]}else a=[f];const s=l({apiKey:n,endpoint:c,scriptUrlPattern:a}),p=yield s,{requestId:d}=yield p.get();o(d)}catch(e){console.warn("Could not load fingerprint",e)}}))}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.fingerprint=t())}(this,(function(){"use strict";function e(e,t,n,r){return new(n||(n=Promise))((function(o,i){function c(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,s)}u((r=r.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const t={default:"endpoint"},n="Blocked by CSP",r="The endpoint parameter is not a valid URL";const o="Failed to load the JS script of the agent",i="9319";function c(e,t){const c=[],[s,u]=function(e){const t=function(e){const t=[...e];return{current:()=>t[0],postpone(){const e=t.shift();void 0!==e&&t.push(e)},exclude(){t.shift()}}}(e),c=function(){let e=0;return()=>Math.random()*Math.min(3e3,100*Math.pow(2,e++))}(),s=new Set;return[t.current(),(e,u)=>{let l;const a=u instanceof Error?u.message:"";if(a===n||a===r)t.exclude(),l=0;else if(a===i)t.exclude();else if(a===o){const n=Date.now()-e.getTime()<50,r=t.current();r&&n&&!s.has(r)&&(s.add(r),l=0),t.postpone()}else t.postpone();const d=t.current();return void 0===d?void 0:[d,null!=l?l:e.getTime()+c()-Date.now()]}]}(e);let l;if(void 0===s)return Promise.reject(new TypeError("The list of script URL patterns is empty"));const a=e=>{const n=new Date,r=t=>c.push({url:e,startedAt:n,finishedAt:new Date,error:t}),o=t(e);return o.then((()=>r()),r),o.catch((e=>{if(null!=l||(l=e),c.length>=5)throw l;const t=u(n,e);if(!t)throw l;const[r,o]=t;return(i=o,new Promise((e=>setTimeout(e,i)))).then((()=>a(r)));var i}))};return a(s).then((e=>[e,c]))}const s="https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js",u=s;function l(e){var t,n;const{picked:r,rest:u}=function(e,t){const n={},r={};for(const[o,i]of Object.entries(e))t.includes(o)?n[o]=i:r[o]=i;return{picked:n,rest:r}}(e,["scriptUrlPattern","token","apiKey"]),l=r.token,d=null!==(t=r.apiKey)&&void 0!==t?t:l,p=null!==(n=function(e,t){return function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}(e,t)?e[t]:void 0}(e,"scriptUrlPattern"))&&void 0!==n?n:s,[f,h]=function(){const e=[],t=()=>{e.push({time:new Date,state:document.visibilityState})},n=function(e,t,n,r){return e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)}(document,"visibilitychange",t);return t(),[e,n]}();return Promise.resolve().then((()=>{if(!d||"string"!=typeof d)throw new Error("API key required");const e=function(e,t){return(Array.isArray(e)?e:[e]).map((e=>function(e,t){const n=encodeURIComponent;return e.replace(/<[^<>]+>/g,(e=>"<version>"===e?"3":"<apiKey>"===e?n(t):"<loaderVersion>"===e?n("3.12.1"):e))}(String(e),t)))}(p,d);return c(e,a)})).catch((e=>{throw h(),function(e){return e instanceof Error&&e.message===i?new Error(o):e}(e)})).then((([e,t])=>(h(),e.load({...u,ldi:{attempts:t,visibilityStates:f}}))))}function a(e){return function(e,t,n){const r=document,o="securitypolicyviolation";let i;const c=t=>{const n=new URL(e,location.href),{blockedURI:r}=t;r!==n.href&&r!==n.protocol.slice(0,-1)&&r!==n.origin||(i=t,s())};r.addEventListener(o,c);const s=()=>r.removeEventListener(o,c);return Promise.resolve().then(t).then((e=>(s(),e)),(e=>new Promise((e=>{const t=new MessageChannel;t.port1.onmessage=()=>e(),t.port2.postMessage(null)})).then((()=>{if(s(),i)return n(i);throw e}))))}(e,(()=>function(e){return new Promise(((t,n)=>{if(function(e){if(URL.prototype)try{return new URL(e,location.href),!1}catch(e){if(e instanceof Error&&"TypeError"===e.name)return!0;throw e}}(e))throw new Error(r);const i=document.createElement("script"),c=()=>{var e;return null===(e=i.parentNode)||void 0===e?void 0:e.removeChild(i)},s=document.head||document.getElementsByTagName("head")[0];i.onload=()=>{c(),t()},i.onerror=()=>{c(),n(new Error(o))},i.async=!0,i.src=e,s.appendChild(i)}))}(e)),(()=>{throw new Error(n)})).then(d)}function d(){const e=window,t="__fpjs_p_l_b",n=e[t];if(function(e,t){var n;const r=null===(n=Object.getOwnPropertyDescriptor)||void 0===n?void 0:n.call(Object,e,t);(null==r?void 0:r.configurable)?delete e[t]:r&&!r.writable||(e[t]=void 0)}(e,t),"function"!=typeof(null==n?void 0:n.load))throw new Error(i);return n}return(n,r,o,i)=>e(void 0,void 0,void 0,(function*(){try{const{publicApiKey:e,useCloudflareIntegration:r,cloudflareScriptUrl:i,cloudflareEndpointUrl:c}=n;let s=[];s=r&&c?[c,t]:[t];let a=[];if(r&&i){const e=new URL(i);a=[`${e.toString()}?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>`,u]}else a=[u];const d=l({apiKey:e,endpoint:s,scriptUrlPattern:a}),p=yield d,{requestId:f}=yield p.get();o(f)}catch(e){i.warn("Could not load fingerprint",e)}}))}));
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
!function(e,
|
|
2
|
-
/*! Source: (c) FingerprintJS and other contributors | https://dev.fingerprint.com/ */return(e,r,o)=>n(void 0,void 0,void 0,(function*(){try{const{customDomain:n,publicApiKey:i,cloudflareEndpointPath:c,cloudflareScriptPath:u}=e,{baseUrl:a}=r;let l;l=n?`https://${n}`:a||"https://api.descope.com";const p=new URL(l);p.pathname=c;const d=new URL(l);d.pathname=u;const v=`${d.toString()}?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>`,h=s({apiKey:i,endpoint:[p.toString(),t],scriptUrlPattern:[v,f]}),y=yield h,{requestId:m}=yield y.get();o(m)}catch(e){console.warn("Could not load descope fingerprint",e)}}))}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.fingerprintDescope=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(r,i){function c(e){try{a(o.next(e))}catch(e){i(e)}}function s(e){try{a(o.throw(e))}catch(e){i(e)}}function a(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,s)}a((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const t={default:"endpoint"},n="Blocked by CSP",o="The endpoint parameter is not a valid URL";const r="Failed to load the JS script of the agent",i="9319";function c(e,t){const c=[],[s,a]=function(e){const t=function(e){const t=[...e];return{current:()=>t[0],postpone(){const e=t.shift();void 0!==e&&t.push(e)},exclude(){t.shift()}}}(e),c=function(){let e=0;return()=>Math.random()*Math.min(3e3,100*Math.pow(2,e++))}(),s=new Set;return[t.current(),(e,a)=>{let u;const l=a instanceof Error?a.message:"";if(l===n||l===o)t.exclude(),u=0;else if(l===i)t.exclude();else if(l===r){const n=Date.now()-e.getTime()<50,o=t.current();o&&n&&!s.has(o)&&(s.add(o),u=0),t.postpone()}else t.postpone();const d=t.current();return void 0===d?void 0:[d,null!=u?u:e.getTime()+c()-Date.now()]}]}(e);let u;if(void 0===s)return Promise.reject(new TypeError("The list of script URL patterns is empty"));const l=e=>{const n=new Date,o=t=>c.push({url:e,startedAt:n,finishedAt:new Date,error:t}),r=t(e);return r.then((()=>o()),o),r.catch((e=>{if(null!=u||(u=e),c.length>=5)throw u;const t=a(n,e);if(!t)throw u;const[o,r]=t;return(i=r,new Promise((e=>setTimeout(e,i)))).then((()=>l(o)));var i}))};return l(s).then((e=>[e,c]))}const s="https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js",a=s;function u(e){var t,n;const{picked:o,rest:a}=function(e,t){const n={},o={};for(const[r,i]of Object.entries(e))t.includes(r)?n[r]=i:o[r]=i;return{picked:n,rest:o}}(e,["scriptUrlPattern","token","apiKey"]),u=o.token,d=null!==(t=o.apiKey)&&void 0!==t?t:u,p=null!==(n=function(e,t){return function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}(e,t)?e[t]:void 0}(e,"scriptUrlPattern"))&&void 0!==n?n:s,[f,h]=function(){const e=[],t=()=>{e.push({time:new Date,state:document.visibilityState})},n=function(e,t,n,o){return e.addEventListener(t,n,o),()=>e.removeEventListener(t,n,o)}(document,"visibilitychange",t);return t(),[e,n]}();return Promise.resolve().then((()=>{if(!d||"string"!=typeof d)throw new Error("API key required");const e=function(e,t){return(Array.isArray(e)?e:[e]).map((e=>function(e,t){const n=encodeURIComponent;return e.replace(/<[^<>]+>/g,(e=>"<version>"===e?"3":"<apiKey>"===e?n(t):"<loaderVersion>"===e?n("3.12.1"):e))}(String(e),t)))}(p,d);return c(e,l)})).catch((e=>{throw h(),function(e){return e instanceof Error&&e.message===i?new Error(r):e}(e)})).then((([e,t])=>(h(),e.load({...a,ldi:{attempts:t,visibilityStates:f}}))))}function l(e){return function(e,t,n){const o=document,r="securitypolicyviolation";let i;const c=t=>{const n=new URL(e,location.href),{blockedURI:o}=t;o!==n.href&&o!==n.protocol.slice(0,-1)&&o!==n.origin||(i=t,s())};o.addEventListener(r,c);const s=()=>o.removeEventListener(r,c);return Promise.resolve().then(t).then((e=>(s(),e)),(e=>new Promise((e=>{const t=new MessageChannel;t.port1.onmessage=()=>e(),t.port2.postMessage(null)})).then((()=>{if(s(),i)return n(i);throw e}))))}(e,(()=>function(e){return new Promise(((t,n)=>{if(function(e){if(URL.prototype)try{return new URL(e,location.href),!1}catch(e){if(e instanceof Error&&"TypeError"===e.name)return!0;throw e}}(e))throw new Error(o);const i=document.createElement("script"),c=()=>{var e;return null===(e=i.parentNode)||void 0===e?void 0:e.removeChild(i)},s=document.head||document.getElementsByTagName("head")[0];i.onload=()=>{c(),t()},i.onerror=()=>{c(),n(new Error(r))},i.async=!0,i.src=e,s.appendChild(i)}))}(e)),(()=>{throw new Error(n)})).then(d)}function d(){const e=window,t="__fpjs_p_l_b",n=e[t];if(function(e,t){var n;const o=null===(n=Object.getOwnPropertyDescriptor)||void 0===n?void 0:n.call(Object,e,t);(null==o?void 0:o.configurable)?delete e[t]:o&&!o.writable||(e[t]=void 0)}(e,t),"function"!=typeof(null==n?void 0:n.load))throw new Error(i);return n}return(n,o,r,i)=>e(void 0,void 0,void 0,(function*(){try{const{customDomain:e,publicApiKey:i,cloudflareEndpointPath:c,cloudflareScriptPath:s}=n,{baseUrl:l}=o;let d;d=e?`https://${e}`:l||"https://api.descope.com";const p=new URL(d);p.pathname=c;const f=new URL(d);f.pathname=s;const h=`${f.toString()}?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>`,v=u({apiKey:i,endpoint:[p.toString(),t],scriptUrlPattern:[h,a]}),m=yield v,{requestId:w}=yield m.get();r(w)}catch(e){i.warn("Could not load descope fingerprint",e)}}))}));
|
package/dist/grecaptcha.js
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.grecaptcha=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(r,c){function i(e){try{s(o.next(e))}catch(e){c(e)}}function a(e){try{s(o.throw(e))}catch(e){c(e)}}function s(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,a)}s((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;
|
|
2
|
-
/*! Source: (c) google and other contributors | https://developers.google.com/recaptcha/docs/v3 */
|
|
3
|
-
const t=105e3;return(n,o,r)=>{let c=(new Date).getTime();const i=()=>{var e;return n.enterprise?null===(e=window.grecaptcha)||void 0===e?void 0:e.enterprise:window.grecaptcha};let a,s;const d=(e,o)=>{e.ready((()=>{n.siteKey&&(null==e||e.execute(s,{action:"load"}).then(((n,o)=>{o?console.warn("could not execute recaptcha",o):(r(n),c=(new Date).getTime(),a=setTimeout((()=>{d(e)}),t))})))}))},p=()=>{clearTimeout(a)},u=(()=>{const e=document.createElement("div");return e.style.display="none",e.id="recaptcha",document.body.appendChild(e)})(),l=()=>{const e=i();e&&d(e)};return window.onRecaptchaLoadCallback=()=>{const e=u;if(e.hasChildNodes())return;const t=i();t&&setTimeout((()=>{s=t.render(e,{sitekey:n.siteKey,badge:"inline",size:"invisible"}),d(t)}),0)},(()=>{const e=document.createElement("script");e.src=(()=>{const e=new URL(`${n.baseUrl||"https://www.google.com"}/recaptcha/`);return e.pathname+=(n.enterprise?"enterprise":"api")+".js",e.searchParams.append("onload","onRecaptchaLoadCallback"),e.searchParams.append("render","explicit"),e.toString()})(),e.async=!0,e.id="recaptcha-script",e.defer=!0,document.body.appendChild(e)})(),{stop:p,start:l,refresh:()=>e(void 0,void 0,void 0,(function*(){if(Date.now()-c>t){p();const e=c;return l(),new Promise((t=>{const n=setTimeout((()=>{console.warn("reCAPTCHA token refresh timed out"),t()}),5e3),o=()=>{c!==e?(clearTimeout(n),t()):setTimeout(o,150)};o()}))}return Promise.resolve()}))}}}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.grecaptcha=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(r,c){function i(e){try{s(o.next(e))}catch(e){c(e)}}function a(e){try{s(o.throw(e))}catch(e){c(e)}}function s(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,a)}s((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const t=105e3;return(n,o,r,c)=>{let i=(new Date).getTime();const a=()=>{var e;return n.enterprise?null===(e=window.grecaptcha)||void 0===e?void 0:e.enterprise:window.grecaptcha};let s,d;const p=(e,o)=>{e.ready((()=>{n.siteKey&&(null==e||e.execute(d,{action:"load"}).then(((n,o)=>{o?c.warn("could not execute recaptcha",o):(r(n),i=(new Date).getTime(),s=setTimeout((()=>{p(e)}),t))})))}))},u=()=>{clearTimeout(s)},l=(()=>{const e=document.createElement("div");return e.style.display="none",e.id="recaptcha",document.body.appendChild(e)})(),f=()=>{const e=a();e&&p(e)};return window.onRecaptchaLoadCallback=()=>{const e=l;if(e.hasChildNodes())return;const t=a();t&&setTimeout((()=>{d=t.render(e,{sitekey:n.siteKey,badge:"inline",size:"invisible"}),p(t)}),0)},(()=>{const e=document.createElement("script");e.src=(()=>{const e=new URL(`${n.baseUrl||"https://www.google.com"}/recaptcha/`);return e.pathname+=(n.enterprise?"enterprise":"api")+".js",e.searchParams.append("onload","onRecaptchaLoadCallback"),e.searchParams.append("render","explicit"),e.toString()})(),e.async=!0,e.id="recaptcha-script",e.defer=!0,document.body.appendChild(e)})(),{id:"grecaptcha",stop:u,start:f,refresh:()=>e(void 0,void 0,void 0,(function*(){if(Date.now()-i>t){u();const e=i;return f(),new Promise((t=>{const n=setTimeout((()=>{c.warn("reCAPTCHA token refresh timed out"),t()}),5e3),o=()=>{i!==e?(clearTimeout(n),t()):setTimeout(o,150)};o()}))}return Promise.resolve()}))}}}));
|
package/dist/hcaptcha.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.hcaptcha=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(c,
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.hcaptcha=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(c,a){function r(e){try{i(o.next(e))}catch(e){a(e)}}function s(e){try{i(o.throw(e))}catch(e){a(e)}}function i(e){var t;e.done?c(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,s)}i((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;return(t,n,o,c)=>{let a=null;const r=()=>window.hcaptcha;const s=()=>{clearTimeout(undefined)},i=()=>{const e=document.querySelector("descope-wc");if(!e)return null;const t=e.shadowRoot;if(!t)return null;const n=t.querySelector("descope-hcaptcha");if(!n)return null;const o=n.shadowRoot;return o?o.getElementById("hcaptcha-input"):null},u=()=>{r()&&d()};window.descopeHcaptchaCallback=e=>{const t=i();null==t||t.setAttribute("value",e),a=(new Date).getTime(),o(e)},window.descopeHcaptchaExpiredCallback=()=>{const e=i();null==e||e.setAttribute("value",""),o("")};const d=()=>{const e=(()=>{const e=document.querySelector("descope-wc");if(!e)return null;const t=e.shadowRoot;if(!t)return null;const n=t.querySelector("descope-hcaptcha");if(!n)return null;const o=n.shadowRoot;return o?o.getElementById("hcaptcha"):null})();if(!e)return void setTimeout((()=>{d()}),100);if(null==e?void 0:e.hasChildNodes())return;const n=r();n&&(e.setAttribute("data-sitekey",t.siteKey),e.setAttribute("data-callback","descopeHcaptchaCallback"),e.setAttribute("data-expired-callback","descopeHcaptchaExpiredCallback"),setTimeout((()=>{n.render(e,{sitekey:t.siteKey})}),0))};return window.onHcaptchaLoadCallback=()=>{d()},(()=>{const e=document.createElement("script");e.src=(()=>{const e=new URL("https://js.hcaptcha.com/1/api.js");return e.searchParams.append("onload","onHcaptchaLoadCallback"),e.searchParams.append("render","explicit"),e.toString()})(),e.async=!0,e.id="hcaptcha-script",e.defer=!0,document.body.appendChild(e)})(),{id:"hcaptcha",stop:s,start:u,refresh:()=>e(void 0,void 0,void 0,(function*(){const e=Date.now();if(!a)return;if(e-a>105e3){s();const e=a;return u(),new Promise((t=>{const n=setTimeout((()=>{c.warn("hCaptcha token refresh timed out"),t()}),5e3),o=()=>{a!==e?(clearTimeout(n),t()):setTimeout(o,150)};o()}))}return Promise.resolve()}))}}}));
|
package/dist/turnstile.js
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.turnstile=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(r,s){function
|
|
2
|
-
/*! Source: (c) Descope and Cloudflare | https://developers.cloudflare.com/turnstile/ */
|
|
3
|
-
const t=105e3;return(n,o,r)=>{let s=(new Date).getTime();const c=()=>globalThis.turnstile;let i,a;const l=(e,t)=>{n.siteKey&&(null==e||e.execute(a,{action:"load"}),s=(new Date).getTime())},u=(e,n)=>{try{e.ready((()=>{l(e)}))}catch(t){try{l(e)}catch(e){console.warn("could not execute turnstile",e)}}finally{i=setTimeout((()=>{u(e,n)}),t)}},d=(()=>{const e=document.createElement("div");return e.style.display="none",e.id="descope-turnstile",e.className="cf-turnstile",document.body.appendChild(e)})(),p=()=>{const e=c();e&&(e.reset(a),u(e,d))};return window.onloadTurnstileCallback=()=>{const e=d;if(e.hasChildNodes())return;const t=c();t&&setTimeout((()=>{a=t.render(e,{sitekey:n.siteKey,execution:"execute",appearance:n.appearance||"execute",callback:e=>r(e)}),u(t,e)}),0)},(()=>{const e=document.createElement("script");e.src=(()=>{const e=new URL("https://challenges.cloudflare.com");return e.pathname+="turnstile/v0/api.js",e.searchParams.append("onload","onloadTurnstileCallback"),e.searchParams.append("render","explicit"),e.toString()})(),e.async=!0,e.id="turnstile-script",e.defer=!1,document.body.appendChild(e)})(),{stop:()=>{clearTimeout(i)},start:p,refresh:()=>e(void 0,void 0,void 0,(function*(){if(Date.now()-s>t){const e=s;return p(),new Promise((t=>{const n=setTimeout((()=>{console.warn("Turnstile token refresh timed out"),t()}),5e3),o=()=>{s!==e?(clearTimeout(n),t()):setTimeout(o,150)};o()}))}return Promise.resolve()}))}}}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.turnstile=t())}(this,(function(){"use strict";function e(e,t,n,o){return new(n||(n=Promise))((function(r,s){function i(e){try{a(o.next(e))}catch(e){s(e)}}function c(e){try{a(o.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,c)}a((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const t=105e3;return(n,o,r,s)=>{let i=(new Date).getTime();const c=()=>globalThis.turnstile;let a,u;const l=(e,t)=>{n.siteKey&&(null==e||e.execute(u,{action:"load"}),i=(new Date).getTime())},d=(e,n)=>{try{e.ready((()=>{l(e)}))}catch(t){try{l(e)}catch(e){s.warn("could not execute turnstile",e)}}finally{a=setTimeout((()=>{d(e,n)}),t)}},p=(()=>{const e=document.createElement("div");return e.style.display="none",e.id="descope-turnstile",e.className="cf-turnstile",document.body.appendChild(e)})(),f=()=>{const e=c();e&&(e.reset(u),d(e,p))};return window.onloadTurnstileCallback=()=>{const e=p;if(e.hasChildNodes())return;const t=c();t&&setTimeout((()=>{u=t.render(e,{sitekey:n.siteKey,execution:"execute",appearance:n.appearance||"execute",callback:e=>r(e)}),d(t,e)}),0)},(()=>{const e=document.createElement("script");e.src=(()=>{const e=new URL("https://challenges.cloudflare.com");return e.pathname+="turnstile/v0/api.js",e.searchParams.append("onload","onloadTurnstileCallback"),e.searchParams.append("render","explicit"),e.toString()})(),e.async=!0,e.id="turnstile-script",e.defer=!1,document.body.appendChild(e)})(),{id:"turnstile",stop:()=>{clearTimeout(a)},start:f,refresh:()=>e(void 0,void 0,void 0,(function*(){if(Date.now()-i>t){const e=i;return f(),new Promise((t=>{const n=setTimeout((()=>{s.warn("Turnstile token refresh timed out"),t()}),5e3),o=()=>{i!==e?(clearTimeout(n),t()):setTimeout(o,150)};o()}))}return Promise.resolve()}))}}}));
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(n){"function"==typeof define&&define.amd?define(n):n()}((function(){}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descope/flow-scripts",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.13",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/descope/content"
|
|
@@ -18,19 +18,19 @@
|
|
|
18
18
|
"@rollup/plugin-node-resolve": "16.0.1",
|
|
19
19
|
"@rollup/plugin-terser": "0.4.4",
|
|
20
20
|
"@rollup/plugin-typescript": "12.1.4",
|
|
21
|
-
"@testing-library/dom": "10.4.
|
|
21
|
+
"@testing-library/dom": "10.4.1",
|
|
22
22
|
"@testing-library/react": "16.3.0",
|
|
23
23
|
"@types/jest": "29.5.14",
|
|
24
|
-
"eslint": "9.
|
|
24
|
+
"eslint": "9.35.0",
|
|
25
25
|
"eslint-plugin-import": "2.32.0",
|
|
26
26
|
"jest": "29.7.0",
|
|
27
27
|
"jest-environment-jsdom": "29.7.0",
|
|
28
|
-
"rollup": "4.
|
|
29
|
-
"ts-jest": "29.4.
|
|
28
|
+
"rollup": "4.52.4",
|
|
29
|
+
"ts-jest": "29.4.4",
|
|
30
30
|
"ts-node": "10.9.2",
|
|
31
|
-
"typescript": "5.
|
|
31
|
+
"typescript": "5.9.2"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@fingerprintjs/fingerprintjs-pro": "3.
|
|
34
|
+
"@fingerprintjs/fingerprintjs-pro": "3.12.1"
|
|
35
35
|
}
|
|
36
36
|
}
|
package/src/arkose.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { LoggerWrapper, ScriptModule } from './types';
|
|
2
|
+
|
|
3
|
+
const ARKOSE_MODULE_ID = 'arkose';
|
|
4
|
+
const ARKOSE_DEFAULT_CLIENT_BASE_URL = 'https://client-api.arkoselabs.com/v2';
|
|
5
|
+
const ARKOSE_READY_TIMEOUT_MS = 5000;
|
|
6
|
+
const ARKOSE_READY_WAIT_MS = 100;
|
|
7
|
+
|
|
8
|
+
function ensureTrailingSlash(url: string): string {
|
|
9
|
+
return url.endsWith('/') ? url : url + '/';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const loadScript = (src: string, onLoad: () => void) => {
|
|
13
|
+
const script = document.createElement('script');
|
|
14
|
+
script.src = src;
|
|
15
|
+
script.id = 'arkose-script';
|
|
16
|
+
script.async = true;
|
|
17
|
+
script.defer = true;
|
|
18
|
+
script.onload = onLoad;
|
|
19
|
+
script.setAttribute('data-callback', 'onArkoseLoadCallback');
|
|
20
|
+
document.body.appendChild(script);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const loadArkose = (
|
|
24
|
+
initArgs: { publicKey: string; clientBaseUrl?: string },
|
|
25
|
+
_inputs: { baseUrl?: string; ref: any },
|
|
26
|
+
onTokenReady: (token: string | null) => void,
|
|
27
|
+
logger: LoggerWrapper,
|
|
28
|
+
): ScriptModule => {
|
|
29
|
+
let enforcement: any = null;
|
|
30
|
+
let ready = false;
|
|
31
|
+
let finish: (result: boolean | Error) => void = () => {};
|
|
32
|
+
|
|
33
|
+
const setup = (instance: any) => {
|
|
34
|
+
enforcement = instance;
|
|
35
|
+
enforcement.setConfig({
|
|
36
|
+
onReady: () => {
|
|
37
|
+
logger.debug('Arkose ready');
|
|
38
|
+
ready = true;
|
|
39
|
+
},
|
|
40
|
+
onError: (response) => {
|
|
41
|
+
logger.warn('Arkose error', response.error);
|
|
42
|
+
finish(new Error('Error loading Arkose enforcement'));
|
|
43
|
+
},
|
|
44
|
+
onFailed: (response) => {
|
|
45
|
+
logger.warn('Arkose enforcement failed', response);
|
|
46
|
+
finish(true);
|
|
47
|
+
},
|
|
48
|
+
onWarning: (response) => {
|
|
49
|
+
logger.warn('Arkose warning', response.warning);
|
|
50
|
+
},
|
|
51
|
+
onHide: (response) => {
|
|
52
|
+
if (response.token) {
|
|
53
|
+
logger.debug('Arkose hide with token interpreted as cancellation', response);
|
|
54
|
+
finish(false);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
onShow: (response) => {
|
|
58
|
+
logger.debug('Arkose show', response);
|
|
59
|
+
},
|
|
60
|
+
onShown: (response) => {
|
|
61
|
+
logger.debug('Arkose shown', response);
|
|
62
|
+
},
|
|
63
|
+
onSuppress: (response) => {
|
|
64
|
+
logger.debug('Arkose suppress', response);
|
|
65
|
+
},
|
|
66
|
+
onCompleted: (response) => {
|
|
67
|
+
logger.debug('Arkose completed', response.token);
|
|
68
|
+
onTokenReady(response.token);
|
|
69
|
+
finish(true);
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// the enforcement is presented before submitting the form in screens
|
|
75
|
+
// that use the Arkose connector
|
|
76
|
+
const present = async () => {
|
|
77
|
+
// wait for up to 5 seconds for the module to be ready
|
|
78
|
+
if (!ready) {
|
|
79
|
+
logger.debug('Arkose module not ready yet');
|
|
80
|
+
const startedAt = Date.now();
|
|
81
|
+
while (!ready && Date.now() - startedAt < ARKOSE_READY_TIMEOUT_MS) {
|
|
82
|
+
await new Promise((resolve) => setTimeout(resolve, ARKOSE_READY_WAIT_MS));
|
|
83
|
+
}
|
|
84
|
+
if (!ready) {
|
|
85
|
+
logger.error('Arkose module failed to become ready in time');
|
|
86
|
+
throw new Error('Arkose module not ready');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
logger.debug('Arkose module present called');
|
|
91
|
+
|
|
92
|
+
// create a promise that will be resolved when the enforcement finishes
|
|
93
|
+
const promise = new Promise<boolean>((resolve, reject) => {
|
|
94
|
+
finish = (result) => {
|
|
95
|
+
logger.debug('Arkose module finish called');
|
|
96
|
+
finish = () => {};
|
|
97
|
+
if (typeof result === 'boolean') {
|
|
98
|
+
resolve(result);
|
|
99
|
+
} else {
|
|
100
|
+
reject(result);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// run the enforcement and return the promise
|
|
106
|
+
enforcement.run();
|
|
107
|
+
return promise;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// a custom callback that's invoked by the Arkose script when it's loaded
|
|
111
|
+
(window as any).onArkoseLoadCallback = (instance) => {
|
|
112
|
+
logger.debug('Arkose load callback invoked');
|
|
113
|
+
setup(instance);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (!initArgs.publicKey) {
|
|
117
|
+
logger.error('Arkose public key is required');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// compose the Arkose script URL from the base URL and the public key
|
|
121
|
+
const scriptBaseUrl = ensureTrailingSlash(
|
|
122
|
+
initArgs.clientBaseUrl || ARKOSE_DEFAULT_CLIENT_BASE_URL,
|
|
123
|
+
);
|
|
124
|
+
const scriptUrl = `${scriptBaseUrl}${initArgs.publicKey}/api.js`;
|
|
125
|
+
|
|
126
|
+
// load the Arkose script, and reset the token to null as an initial state
|
|
127
|
+
logger.debug('Arkose script loading', scriptUrl);
|
|
128
|
+
loadScript(scriptUrl, () => {
|
|
129
|
+
logger.debug('Arkose script loaded');
|
|
130
|
+
onTokenReady(null);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return { id: ARKOSE_MODULE_ID, present };
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export default loadArkose;
|
package/src/darwinium.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LoggerWrapper, ScriptModule } from 'types';
|
|
2
|
+
|
|
1
3
|
// A mapping of input names to Darwinium context names
|
|
2
4
|
// https://dahibthxi6hbt.cloudfront.net/dwn-api-docs/javascript/docs/global.html#Contexts
|
|
3
5
|
const CONTEXT_MAPPING = {
|
|
@@ -43,8 +45,9 @@ const createSelectors = (inputs: HTMLInputElement[]) => {
|
|
|
43
45
|
const loadDarwinium = (
|
|
44
46
|
initArgs: { profilingTagsScriptUrl?: string; geoLocationEnabled?: boolean },
|
|
45
47
|
_inputs: { baseUrl?: string; ref: any },
|
|
46
|
-
onTokenReady: (token: string | null) => void
|
|
47
|
-
|
|
48
|
+
onTokenReady: (token: string | null) => void,
|
|
49
|
+
logger: LoggerWrapper,
|
|
50
|
+
): ScriptModule => {
|
|
48
51
|
let profilingInstance: any = null;
|
|
49
52
|
|
|
50
53
|
// on flow state update, start profiling
|
|
@@ -53,7 +56,7 @@ const loadDarwinium = (
|
|
|
53
56
|
if (_inputs.ref.getInputs) {
|
|
54
57
|
selectors = createSelectors(_inputs.ref.getInputs());
|
|
55
58
|
} else {
|
|
56
|
-
|
|
59
|
+
logger.warn("getInputs function is missing, expected the ref to be a Descope Web Component");
|
|
57
60
|
}
|
|
58
61
|
profilingInstance = createProfilingInstance(selectors);
|
|
59
62
|
};
|
|
@@ -76,7 +79,7 @@ const loadDarwinium = (
|
|
|
76
79
|
start();
|
|
77
80
|
});
|
|
78
81
|
|
|
79
|
-
return { stop, start, refresh };
|
|
82
|
+
return { id: 'darwinium', stop, start, refresh };
|
|
80
83
|
};
|
|
81
84
|
|
|
82
85
|
export default loadDarwinium;
|
package/src/fingerprint.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*! Source: (c) FingerprintJS and other contributors | https://dev.fingerprint.com/ */
|
|
2
|
+
import { LoggerWrapper } from 'types';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
load,
|
|
@@ -15,6 +16,7 @@ const loadFingerprint = async (
|
|
|
15
16
|
},
|
|
16
17
|
_: { baseUrl?: string },
|
|
17
18
|
onTokenReady: (token: string) => void,
|
|
19
|
+
logger: LoggerWrapper,
|
|
18
20
|
) => {
|
|
19
21
|
try {
|
|
20
22
|
const {
|
|
@@ -51,7 +53,7 @@ const loadFingerprint = async (
|
|
|
51
53
|
const { requestId } = await agent.get();
|
|
52
54
|
onTokenReady(requestId);
|
|
53
55
|
} catch (ex) {
|
|
54
|
-
|
|
56
|
+
logger.warn('Could not load fingerprint', ex);
|
|
55
57
|
}
|
|
56
58
|
};
|
|
57
59
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*! Source: (c) FingerprintJS and other contributors | https://dev.fingerprint.com/ */
|
|
2
|
+
import { LoggerWrapper } from 'types';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
load,
|
|
@@ -15,6 +16,7 @@ const loadFingerprint = async (
|
|
|
15
16
|
},
|
|
16
17
|
inputs: { baseUrl?: string },
|
|
17
18
|
onTokenReady: (token: string) => void,
|
|
19
|
+
logger: LoggerWrapper,
|
|
18
20
|
) => {
|
|
19
21
|
try {
|
|
20
22
|
const {
|
|
@@ -57,7 +59,7 @@ const loadFingerprint = async (
|
|
|
57
59
|
const { requestId } = await agent.get();
|
|
58
60
|
onTokenReady(requestId);
|
|
59
61
|
} catch (ex) {
|
|
60
|
-
|
|
62
|
+
logger.warn('Could not load descope fingerprint', ex);
|
|
61
63
|
}
|
|
62
64
|
};
|
|
63
65
|
|
package/src/grecaptcha.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*! Source: (c) google and other contributors | https://developers.google.com/recaptcha/docs/v3 */
|
|
2
|
+
import { LoggerWrapper, ScriptModule } from 'types';
|
|
2
3
|
|
|
3
4
|
declare global {
|
|
4
5
|
interface Window {
|
|
@@ -25,7 +26,8 @@ const loadGRecaptcha = (
|
|
|
25
26
|
},
|
|
26
27
|
_inputs: { baseUrl?: string },
|
|
27
28
|
onTokenReady: (token: string) => void,
|
|
28
|
-
|
|
29
|
+
logger: LoggerWrapper,
|
|
30
|
+
): ScriptModule => {
|
|
29
31
|
let lastTokenFetchTime = new Date().getTime();
|
|
30
32
|
|
|
31
33
|
const getScriptURL = () => {
|
|
@@ -60,7 +62,7 @@ const loadGRecaptcha = (
|
|
|
60
62
|
?.execute(recaptchaWidgetId, { action: 'load' })
|
|
61
63
|
.then((token: string, e: any) => {
|
|
62
64
|
if (e) {
|
|
63
|
-
|
|
65
|
+
logger.warn('could not execute recaptcha', e);
|
|
64
66
|
} else {
|
|
65
67
|
onTokenReady(token);
|
|
66
68
|
lastTokenFetchTime = new Date().getTime();
|
|
@@ -112,7 +114,7 @@ const loadGRecaptcha = (
|
|
|
112
114
|
return new Promise<void>((resolve) => {
|
|
113
115
|
// Set a timeout to prevent indefinite waiting
|
|
114
116
|
const timeout = setTimeout(() => {
|
|
115
|
-
|
|
117
|
+
logger.warn('reCAPTCHA token refresh timed out');
|
|
116
118
|
resolve(); // Resolve anyway to prevent blocking form submission
|
|
117
119
|
}, 5000); // 5 second timeout for token refresh
|
|
118
120
|
|
|
@@ -163,6 +165,7 @@ const loadGRecaptcha = (
|
|
|
163
165
|
loadRecaptchaScript();
|
|
164
166
|
|
|
165
167
|
return {
|
|
168
|
+
id: 'grecaptcha',
|
|
166
169
|
stop: stopTimer,
|
|
167
170
|
start: resumeScriptExecution,
|
|
168
171
|
refresh: refreshIfTokenExpired,
|
package/src/hcaptcha.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*! Source: (c) hCaptcha and other contributors | https://docs.hcaptcha.com */
|
|
2
|
+
import { LoggerWrapper, ScriptModule } from 'types';
|
|
2
3
|
|
|
3
4
|
declare global {
|
|
4
5
|
interface Window {
|
|
@@ -24,7 +25,8 @@ const loadHcaptcha = (
|
|
|
24
25
|
},
|
|
25
26
|
_inputs: { baseUrl?: string },
|
|
26
27
|
onTokenReady: (token: string) => void,
|
|
27
|
-
|
|
28
|
+
logger: LoggerWrapper,
|
|
29
|
+
): ScriptModule => {
|
|
28
30
|
let lastTokenFetchTime: number | null = null;
|
|
29
31
|
|
|
30
32
|
const getScriptURL = () => {
|
|
@@ -56,7 +58,7 @@ const loadHcaptcha = (
|
|
|
56
58
|
?.execute(hcaptchaWidgetId, { action: 'load', async: true })
|
|
57
59
|
.then((token: string, e: any) => {
|
|
58
60
|
if (e) {
|
|
59
|
-
|
|
61
|
+
logger.warn('could not execute recaptcha', e);
|
|
60
62
|
} else {
|
|
61
63
|
onTokenReady(token);
|
|
62
64
|
lastTokenFetchTime = new Date().getTime();
|
|
@@ -126,7 +128,7 @@ const loadHcaptcha = (
|
|
|
126
128
|
return new Promise<void>((resolve) => {
|
|
127
129
|
// Set a timeout to prevent indefinite waiting
|
|
128
130
|
const timeout = setTimeout(() => {
|
|
129
|
-
|
|
131
|
+
logger.warn('hCaptcha token refresh timed out');
|
|
130
132
|
resolve(); // Resolve anyway to prevent blocking form submission
|
|
131
133
|
}, 5000); // 5 second timeout for token refresh
|
|
132
134
|
|
|
@@ -204,6 +206,7 @@ const loadHcaptcha = (
|
|
|
204
206
|
loadHcaptchaScript();
|
|
205
207
|
|
|
206
208
|
return {
|
|
209
|
+
id: 'hcaptcha',
|
|
207
210
|
stop: stopTimer,
|
|
208
211
|
start: resumeScriptExecution,
|
|
209
212
|
refresh: refreshIfTokenExpired,
|
package/src/index.spec.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { waitFor } from '@testing-library/dom';
|
|
2
2
|
import * as fp from '@fingerprintjs/fingerprintjs-pro';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
+
import { LoggerWrapper } from 'types';
|
|
4
5
|
|
|
5
6
|
const urlPattern =
|
|
6
7
|
'?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>';
|
|
@@ -11,13 +12,20 @@ async function loadSdkScript(scriptId: string) {
|
|
|
11
12
|
return res.default;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
const logger: LoggerWrapper = {
|
|
16
|
+
debug: console.debug,
|
|
17
|
+
info: console.info,
|
|
18
|
+
warn: console.warn,
|
|
19
|
+
error: console.error,
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
global.fetch = mockFetch;
|
|
15
23
|
|
|
16
24
|
describe('scripts', () => {
|
|
17
25
|
describe('all', () => {
|
|
18
26
|
test('should load all scripts and ensure only one export', async () => {
|
|
19
27
|
fs.readdirSync('./src').forEach(async (file) => {
|
|
20
|
-
if (file.endsWith('.ts') && !file.includes('spec')) {
|
|
28
|
+
if (file.endsWith('.ts') && !file.includes('spec') && file !== 'types.ts') {
|
|
21
29
|
const scriptId = file.replace('.ts', '');
|
|
22
30
|
|
|
23
31
|
const m = await import(`./${scriptId}`);
|
|
@@ -32,7 +40,7 @@ describe('scripts', () => {
|
|
|
32
40
|
const forterModule = await loadSdkScript('forter');
|
|
33
41
|
const tokenChangedFn = jest.fn();
|
|
34
42
|
|
|
35
|
-
await forterModule({ siteId: 'some-site-id' }, {}, tokenChangedFn);
|
|
43
|
+
await forterModule({ siteId: 'some-site-id' }, {}, tokenChangedFn, logger);
|
|
36
44
|
|
|
37
45
|
// get script from document and ensure it has id attribute
|
|
38
46
|
const script = document.querySelector('script');
|
|
@@ -72,6 +80,7 @@ describe('scripts', () => {
|
|
|
72
80
|
},
|
|
73
81
|
{},
|
|
74
82
|
mockOnTokenReady,
|
|
83
|
+
logger,
|
|
75
84
|
);
|
|
76
85
|
|
|
77
86
|
expect(agent).toHaveBeenCalledWith({
|
|
@@ -101,6 +110,7 @@ describe('scripts', () => {
|
|
|
101
110
|
},
|
|
102
111
|
{},
|
|
103
112
|
mockOnTokenReady,
|
|
113
|
+
logger,
|
|
104
114
|
);
|
|
105
115
|
|
|
106
116
|
expect(agent).toHaveBeenCalledWith({
|
|
@@ -134,6 +144,7 @@ describe('scripts', () => {
|
|
|
134
144
|
},
|
|
135
145
|
{},
|
|
136
146
|
mockOnTokenReady,
|
|
147
|
+
logger,
|
|
137
148
|
);
|
|
138
149
|
|
|
139
150
|
expect(agent).toHaveBeenCalledWith({
|
|
@@ -169,6 +180,7 @@ describe('scripts', () => {
|
|
|
169
180
|
},
|
|
170
181
|
{ baseUrl },
|
|
171
182
|
mockOnTokenReady,
|
|
183
|
+
logger,
|
|
172
184
|
);
|
|
173
185
|
|
|
174
186
|
expect(agent).toHaveBeenCalledWith({
|
|
@@ -203,6 +215,7 @@ describe('scripts', () => {
|
|
|
203
215
|
},
|
|
204
216
|
{ baseUrl },
|
|
205
217
|
mockOnTokenReady,
|
|
218
|
+
logger,
|
|
206
219
|
);
|
|
207
220
|
|
|
208
221
|
expect(agent).toHaveBeenCalledWith({
|
package/src/turnstile.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*! Source: (c) Descope and Cloudflare | https://developers.cloudflare.com/turnstile/ */
|
|
2
|
+
import { LoggerWrapper, ScriptModule } from 'types';
|
|
2
3
|
|
|
3
4
|
// define the global interface for the turnstile object
|
|
4
5
|
declare global {
|
|
@@ -22,11 +23,11 @@ const loadTurnstile = (
|
|
|
22
23
|
initArgs: {
|
|
23
24
|
appearance: boolean;
|
|
24
25
|
siteKey: string;
|
|
25
|
-
|
|
26
26
|
},
|
|
27
27
|
_inputs: { baseUrl?: string },
|
|
28
28
|
onTokenReady: (token: string) => void,
|
|
29
|
-
|
|
29
|
+
logger: LoggerWrapper,
|
|
30
|
+
): ScriptModule => {
|
|
30
31
|
let lastTokenFetchTime = new Date().getTime();
|
|
31
32
|
|
|
32
33
|
const getScriptURL = () => {
|
|
@@ -70,7 +71,7 @@ const loadTurnstile = (
|
|
|
70
71
|
try {
|
|
71
72
|
executeNewToken(turnstileInstance, currentNode);
|
|
72
73
|
} catch (e) {
|
|
73
|
-
|
|
74
|
+
logger.warn('could not execute turnstile', e);
|
|
74
75
|
}
|
|
75
76
|
} finally {
|
|
76
77
|
// Set a timeout to refresh the token before it expires
|
|
@@ -120,7 +121,7 @@ const loadTurnstile = (
|
|
|
120
121
|
return new Promise<void>((resolve) => {
|
|
121
122
|
// Set a timeout to prevent indefinite waiting
|
|
122
123
|
const timeout = setTimeout(() => {
|
|
123
|
-
|
|
124
|
+
logger.warn('Turnstile token refresh timed out');
|
|
124
125
|
resolve(); // Resolve anyway to prevent blocking form submission
|
|
125
126
|
}, 5000); // 5 second timeout for token refresh
|
|
126
127
|
|
|
@@ -171,6 +172,7 @@ const loadTurnstile = (
|
|
|
171
172
|
loadScript();
|
|
172
173
|
|
|
173
174
|
return {
|
|
175
|
+
id: 'turnstile',
|
|
174
176
|
stop: stopTimer,
|
|
175
177
|
start: resumeScriptExecution,
|
|
176
178
|
refresh: refreshIfTokenExpired,
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type LoggerWrapper = {
|
|
2
|
+
error: (message: string, description?: any) => void;
|
|
3
|
+
warn: (message: string, description?: any) => void;
|
|
4
|
+
info: (message: string, description?: any) => void;
|
|
5
|
+
debug: (message: string, description?: any) => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type ScriptModule = {
|
|
9
|
+
/**
|
|
10
|
+
* Unique identifier of the module.
|
|
11
|
+
*/
|
|
12
|
+
id: string;
|
|
13
|
+
/**
|
|
14
|
+
* Notifies the module that it should start any profiling or monitoring.
|
|
15
|
+
*/
|
|
16
|
+
start?: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Notifies the module that it should stop any profiling or monitoring.
|
|
19
|
+
*/
|
|
20
|
+
stop?: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Presents the user with any required interaction to get a refreshed token or state,
|
|
23
|
+
* e.g., a challenge or captcha.
|
|
24
|
+
*
|
|
25
|
+
* Modules should return a value of true if the presentation completed successfully,
|
|
26
|
+
* false if it was cancelled by the user, and throw an error in case of failure.
|
|
27
|
+
*
|
|
28
|
+
* This is called before form submission (via a next call) after a button click.
|
|
29
|
+
*/
|
|
30
|
+
present?: () => Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Refreshes any tokens or state that might be needed before form submission.
|
|
33
|
+
*
|
|
34
|
+
* Modules should throw an error in case of failure.
|
|
35
|
+
*/
|
|
36
|
+
refresh?: () => Promise<void> | void;
|
|
37
|
+
};
|