@descope/flow-scripts 1.0.9 → 1.0.10
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/fingerprint.js +1 -1
- package/dist/fingerprintDescope.js +1 -1
- package/dist/hcaptcha.js +1 -0
- package/package.json +8 -8
- package/src/hcaptcha.spec.ts +71 -0
- package/src/hcaptcha.ts +213 -0
package/dist/fingerprint.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.fingerprint=n())}(this,(function(){"use strict";var e=function(){return e=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},e.apply(this,arguments)};function n(e,n,t,r){return new(t||(t=Promise))((function(o,i){function u(e){try{a(r.next(e))}catch(e){i(e)}}function c(e){try{a(r.throw(e))}catch(e){i(e)}}function a(e){var n;e.done?o(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(u,c)}a((r=r.apply(e,n||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;var t={default:"endpoint"},r="Blocked by CSP",o="The endpoint parameter is not a valid URL",i="Failed to load the JS script of the agent",u="9319";function c(e,n){var t,c,a,f,l,s=[],p=(t=function(e){var n=function(e,n,t){if(t||2===arguments.length)for(var r,o=0,i=n.length;o<i;o++)!r&&o in n||(r||(r=Array.prototype.slice.call(n,0,o)),r[o]=n[o]);return e.concat(r||Array.prototype.slice.call(n))}([],e,!0);return{current:function(){return n[0]},postpone:function(){var e=n.shift();void 0!==e&&n.push(e)},exclude:function(){n.shift()}}}(e),f=0,c=function(){return Math.random()*Math.min(3e3,100*Math.pow(2,f++))},a=new Set,[t.current(),function(e,n){var f,l=n instanceof Error?n.message:"";if(l===r||l===o)t.exclude(),f=0;else if(l===u)t.exclude();else if(l===i){var s=Date.now()-e.getTime()<50,p=t.current();p&&s&&!a.has(p)&&(a.add(p),f=0),t.postpone()}else t.postpone();var d=t.current();return void 0===d?void 0:[d,null!=f?f:e.getTime()+c()-Date.now()]}]),d=p[0],v=p[1];if(void 0===d)return Promise.reject(new TypeError("The list of script URL patterns is empty"));var h=function(e){var t=new Date,r=function(n){return s.push({url:e,startedAt:t,finishedAt:new Date,error:n})},o=n(e);return o.then((function(){return r()}),r),o.catch((function(e){if(null!=l||(l=e),s.length>=5)throw l;var n=v(t,e);if(!n)throw l;var r,o=n[0],i=n[1];return(r=i,new Promise((function(e){return setTimeout(e,r)}))).then((function(){return h(o)}))}))};return h(d).then((function(e){return[e,s]}))}var a="https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js",f=a;function l(n){var t;n.scriptUrlPattern;var r=n.token,o=n.apiKey,f=void 0===o?r:o,l=function(e,n){var t={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&n.indexOf(r)<0&&(t[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)n.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(t[r[o]]=e[r[o]])}return t}(n,["scriptUrlPattern","token","apiKey"]),p=null!==(t=function(e,n){return function(e,n){return Object.prototype.hasOwnProperty.call(e,n)}(e,n)?e[n]:void 0}(n,"scriptUrlPattern"))&&void 0!==t?t:a,d=function(){var e=[],n=function(){e.push({time:new Date,state:document.visibilityState})},t=function(e,n,t,r){return e.addEventListener(n,t,r),function(){return e.removeEventListener(n,t,r)}}(document,"visibilitychange",n);return n(),[e,t]}(),v=d[0],h=d[1];return Promise.resolve().then((function(){if(!f||"string"!=typeof f)throw new Error("API key required");return c(function(e,n){return(Array.isArray(e)?e:[e]).map((function(e){return function(e,n){var t=encodeURIComponent;return e.replace(/<[^<>]+>/g,(function(e){return"<version>"===e?"3":"<apiKey>"===e?t(n):"<loaderVersion>"===e?t("3.11.
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.fingerprint=n())}(this,(function(){"use strict";var e=function(){return e=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},e.apply(this,arguments)};function n(e,n,t,r){return new(t||(t=Promise))((function(o,i){function u(e){try{a(r.next(e))}catch(e){i(e)}}function c(e){try{a(r.throw(e))}catch(e){i(e)}}function a(e){var n;e.done?o(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(u,c)}a((r=r.apply(e,n||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;var t={default:"endpoint"},r="Blocked by CSP",o="The endpoint parameter is not a valid URL",i="Failed to load the JS script of the agent",u="9319";function c(e,n){var t,c,a,f,l,s=[],p=(t=function(e){var n=function(e,n,t){if(t||2===arguments.length)for(var r,o=0,i=n.length;o<i;o++)!r&&o in n||(r||(r=Array.prototype.slice.call(n,0,o)),r[o]=n[o]);return e.concat(r||Array.prototype.slice.call(n))}([],e,!0);return{current:function(){return n[0]},postpone:function(){var e=n.shift();void 0!==e&&n.push(e)},exclude:function(){n.shift()}}}(e),f=0,c=function(){return Math.random()*Math.min(3e3,100*Math.pow(2,f++))},a=new Set,[t.current(),function(e,n){var f,l=n instanceof Error?n.message:"";if(l===r||l===o)t.exclude(),f=0;else if(l===u)t.exclude();else if(l===i){var s=Date.now()-e.getTime()<50,p=t.current();p&&s&&!a.has(p)&&(a.add(p),f=0),t.postpone()}else t.postpone();var d=t.current();return void 0===d?void 0:[d,null!=f?f:e.getTime()+c()-Date.now()]}]),d=p[0],v=p[1];if(void 0===d)return Promise.reject(new TypeError("The list of script URL patterns is empty"));var h=function(e){var t=new Date,r=function(n){return s.push({url:e,startedAt:t,finishedAt:new Date,error:n})},o=n(e);return o.then((function(){return r()}),r),o.catch((function(e){if(null!=l||(l=e),s.length>=5)throw l;var n=v(t,e);if(!n)throw l;var r,o=n[0],i=n[1];return(r=i,new Promise((function(e){return setTimeout(e,r)}))).then((function(){return h(o)}))}))};return h(d).then((function(e){return[e,s]}))}var a="https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js",f=a;function l(n){var t;n.scriptUrlPattern;var r=n.token,o=n.apiKey,f=void 0===o?r:o,l=function(e,n){var t={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&n.indexOf(r)<0&&(t[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)n.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(t[r[o]]=e[r[o]])}return t}(n,["scriptUrlPattern","token","apiKey"]),p=null!==(t=function(e,n){return function(e,n){return Object.prototype.hasOwnProperty.call(e,n)}(e,n)?e[n]:void 0}(n,"scriptUrlPattern"))&&void 0!==t?t:a,d=function(){var e=[],n=function(){e.push({time:new Date,state:document.visibilityState})},t=function(e,n,t,r){return e.addEventListener(n,t,r),function(){return e.removeEventListener(n,t,r)}}(document,"visibilitychange",n);return n(),[e,t]}(),v=d[0],h=d[1];return Promise.resolve().then((function(){if(!f||"string"!=typeof f)throw new Error("API key required");return c(function(e,n){return(Array.isArray(e)?e:[e]).map((function(e){return function(e,n){var t=encodeURIComponent;return e.replace(/<[^<>]+>/g,(function(e){return"<version>"===e?"3":"<apiKey>"===e?t(n):"<loaderVersion>"===e?t("3.11.12"):e}))}(String(e),n)}))}(p,f),s)})).catch((function(e){throw h(),function(e){return e instanceof Error&&e.message===u?new Error(i):e}(e)})).then((function(n){var t=n[0],r=n[1];return h(),t.load(e(e({},l),{ldi:{attempts:r,visibilityStates:v}}))}))}function s(e){return function(e,n,t){var r,o=document,i="securitypolicyviolation",u=function(n){var t=new URL(e,location.href),o=n.blockedURI;o!==t.href&&o!==t.protocol.slice(0,-1)&&o!==t.origin||(r=n,c())};o.addEventListener(i,u);var c=function(){return o.removeEventListener(i,u)};return Promise.resolve().then(n).then((function(e){return c(),e}),(function(e){return new Promise((function(e){var n=new MessageChannel;n.port1.onmessage=function(){return e()},n.port2.postMessage(null)})).then((function(){if(c(),r)return t(r);throw e}))}))}(e,(function(){return function(e){return new Promise((function(n,t){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);var r=document.createElement("script"),u=function(){var e;return null===(e=r.parentNode)||void 0===e?void 0:e.removeChild(r)},c=document.head||document.getElementsByTagName("head")[0];r.onload=function(){u(),n()},r.onerror=function(){u(),t(new Error(i))},r.async=!0,r.src=e,c.appendChild(r)}))}(e)}),(function(){throw new Error(r)})).then(p)}function p(){var e=window,n="__fpjs_p_l_b",t=e[n];if(function(e,n){var t,r=null===(t=Object.getOwnPropertyDescriptor)||void 0===t?void 0:t.call(Object,e,n);(null==r?void 0:r.configurable)?delete e[n]:r&&!r.writable||(e[n]=void 0)}(e,n),"function"!=typeof(null==t?void 0:t.load))throw new Error(u);return t}
|
|
2
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,2 +1,2 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.fingerprintDescope=n())}(this,(function(){"use strict";var e=function(){return e=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},e.apply(this,arguments)};function n(e,n,t,r){return new(t||(t=Promise))((function(o,i){function c(e){try{a(r.next(e))}catch(e){i(e)}}function u(e){try{a(r.throw(e))}catch(e){i(e)}}function a(e){var n;e.done?o(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(c,u)}a((r=r.apply(e,n||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;var t={default:"endpoint"},r="Blocked by CSP",o="The endpoint parameter is not a valid URL",i="Failed to load the JS script of the agent",c="9319";function u(e,n){var t,u,a,f,s,l=[],p=(t=function(e){var n=function(e,n,t){if(t||2===arguments.length)for(var r,o=0,i=n.length;o<i;o++)!r&&o in n||(r||(r=Array.prototype.slice.call(n,0,o)),r[o]=n[o]);return e.concat(r||Array.prototype.slice.call(n))}([],e,!0);return{current:function(){return n[0]},postpone:function(){var e=n.shift();void 0!==e&&n.push(e)},exclude:function(){n.shift()}}}(e),f=0,u=function(){return Math.random()*Math.min(3e3,100*Math.pow(2,f++))},a=new Set,[t.current(),function(e,n){var f,s=n instanceof Error?n.message:"";if(s===r||s===o)t.exclude(),f=0;else if(s===c)t.exclude();else if(s===i){var l=Date.now()-e.getTime()<50,p=t.current();p&&l&&!a.has(p)&&(a.add(p),f=0),t.postpone()}else t.postpone();var d=t.current();return void 0===d?void 0:[d,null!=f?f:e.getTime()+u()-Date.now()]}]),d=p[0],v=p[1];if(void 0===d)return Promise.reject(new TypeError("The list of script URL patterns is empty"));var h=function(e){var t=new Date,r=function(n){return l.push({url:e,startedAt:t,finishedAt:new Date,error:n})},o=n(e);return o.then((function(){return r()}),r),o.catch((function(e){if(null!=s||(s=e),l.length>=5)throw s;var n=v(t,e);if(!n)throw s;var r,o=n[0],i=n[1];return(r=i,new Promise((function(e){return setTimeout(e,r)}))).then((function(){return h(o)}))}))};return h(d).then((function(e){return[e,l]}))}var a="https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js",f=a;function s(n){var t;n.scriptUrlPattern;var r=n.token,o=n.apiKey,f=void 0===o?r:o,s=function(e,n){var t={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&n.indexOf(r)<0&&(t[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)n.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(t[r[o]]=e[r[o]])}return t}(n,["scriptUrlPattern","token","apiKey"]),p=null!==(t=function(e,n){return function(e,n){return Object.prototype.hasOwnProperty.call(e,n)}(e,n)?e[n]:void 0}(n,"scriptUrlPattern"))&&void 0!==t?t:a,d=function(){var e=[],n=function(){e.push({time:new Date,state:document.visibilityState})},t=function(e,n,t,r){return e.addEventListener(n,t,r),function(){return e.removeEventListener(n,t,r)}}(document,"visibilitychange",n);return n(),[e,t]}(),v=d[0],h=d[1];return Promise.resolve().then((function(){if(!f||"string"!=typeof f)throw new Error("API key required");return u(function(e,n){return(Array.isArray(e)?e:[e]).map((function(e){return function(e,n){var t=encodeURIComponent;return e.replace(/<[^<>]+>/g,(function(e){return"<version>"===e?"3":"<apiKey>"===e?t(n):"<loaderVersion>"===e?t("3.11.
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((e="undefined"!=typeof globalThis?globalThis:e||self).descope=e.descope||{},e.descope.fingerprintDescope=n())}(this,(function(){"use strict";var e=function(){return e=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},e.apply(this,arguments)};function n(e,n,t,r){return new(t||(t=Promise))((function(o,i){function c(e){try{a(r.next(e))}catch(e){i(e)}}function u(e){try{a(r.throw(e))}catch(e){i(e)}}function a(e){var n;e.done?o(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(c,u)}a((r=r.apply(e,n||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;var t={default:"endpoint"},r="Blocked by CSP",o="The endpoint parameter is not a valid URL",i="Failed to load the JS script of the agent",c="9319";function u(e,n){var t,u,a,f,s,l=[],p=(t=function(e){var n=function(e,n,t){if(t||2===arguments.length)for(var r,o=0,i=n.length;o<i;o++)!r&&o in n||(r||(r=Array.prototype.slice.call(n,0,o)),r[o]=n[o]);return e.concat(r||Array.prototype.slice.call(n))}([],e,!0);return{current:function(){return n[0]},postpone:function(){var e=n.shift();void 0!==e&&n.push(e)},exclude:function(){n.shift()}}}(e),f=0,u=function(){return Math.random()*Math.min(3e3,100*Math.pow(2,f++))},a=new Set,[t.current(),function(e,n){var f,s=n instanceof Error?n.message:"";if(s===r||s===o)t.exclude(),f=0;else if(s===c)t.exclude();else if(s===i){var l=Date.now()-e.getTime()<50,p=t.current();p&&l&&!a.has(p)&&(a.add(p),f=0),t.postpone()}else t.postpone();var d=t.current();return void 0===d?void 0:[d,null!=f?f:e.getTime()+u()-Date.now()]}]),d=p[0],v=p[1];if(void 0===d)return Promise.reject(new TypeError("The list of script URL patterns is empty"));var h=function(e){var t=new Date,r=function(n){return l.push({url:e,startedAt:t,finishedAt:new Date,error:n})},o=n(e);return o.then((function(){return r()}),r),o.catch((function(e){if(null!=s||(s=e),l.length>=5)throw s;var n=v(t,e);if(!n)throw s;var r,o=n[0],i=n[1];return(r=i,new Promise((function(e){return setTimeout(e,r)}))).then((function(){return h(o)}))}))};return h(d).then((function(e){return[e,l]}))}var a="https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js",f=a;function s(n){var t;n.scriptUrlPattern;var r=n.token,o=n.apiKey,f=void 0===o?r:o,s=function(e,n){var t={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&n.indexOf(r)<0&&(t[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)n.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(t[r[o]]=e[r[o]])}return t}(n,["scriptUrlPattern","token","apiKey"]),p=null!==(t=function(e,n){return function(e,n){return Object.prototype.hasOwnProperty.call(e,n)}(e,n)?e[n]:void 0}(n,"scriptUrlPattern"))&&void 0!==t?t:a,d=function(){var e=[],n=function(){e.push({time:new Date,state:document.visibilityState})},t=function(e,n,t,r){return e.addEventListener(n,t,r),function(){return e.removeEventListener(n,t,r)}}(document,"visibilitychange",n);return n(),[e,t]}(),v=d[0],h=d[1];return Promise.resolve().then((function(){if(!f||"string"!=typeof f)throw new Error("API key required");return u(function(e,n){return(Array.isArray(e)?e:[e]).map((function(e){return function(e,n){var t=encodeURIComponent;return e.replace(/<[^<>]+>/g,(function(e){return"<version>"===e?"3":"<apiKey>"===e?t(n):"<loaderVersion>"===e?t("3.11.12"):e}))}(String(e),n)}))}(p,f),l)})).catch((function(e){throw h(),function(e){return e instanceof Error&&e.message===c?new Error(i):e}(e)})).then((function(n){var t=n[0],r=n[1];return h(),t.load(e(e({},s),{ldi:{attempts:r,visibilityStates:v}}))}))}function l(e){return function(e,n,t){var r,o=document,i="securitypolicyviolation",c=function(n){var t=new URL(e,location.href),o=n.blockedURI;o!==t.href&&o!==t.protocol.slice(0,-1)&&o!==t.origin||(r=n,u())};o.addEventListener(i,c);var u=function(){return o.removeEventListener(i,c)};return Promise.resolve().then(n).then((function(e){return u(),e}),(function(e){return new Promise((function(e){var n=new MessageChannel;n.port1.onmessage=function(){return e()},n.port2.postMessage(null)})).then((function(){if(u(),r)return t(r);throw e}))}))}(e,(function(){return function(e){return new Promise((function(n,t){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);var r=document.createElement("script"),c=function(){var e;return null===(e=r.parentNode)||void 0===e?void 0:e.removeChild(r)},u=document.head||document.getElementsByTagName("head")[0];r.onload=function(){c(),n()},r.onerror=function(){c(),t(new Error(i))},r.async=!0,r.src=e,u.appendChild(r)}))}(e)}),(function(){throw new Error(r)})).then(p)}function p(){var e=window,n="__fpjs_p_l_b",t=e[n];if(function(e,n){var t,r=null===(t=Object.getOwnPropertyDescriptor)||void 0===t?void 0:t.call(Object,e,n);(null==r?void 0:r.configurable)?delete e[n]:r&&!r.writable||(e[n]=void 0)}(e,n),"function"!=typeof(null==t?void 0:t.load))throw new Error(c);return t}
|
|
2
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)}}))}));
|
package/dist/hcaptcha.js
ADDED
|
@@ -0,0 +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,r){function a(e){try{i(o.next(e))}catch(e){r(e)}}function s(e){try{i(o.throw(e))}catch(e){r(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(a,s)}i((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;return(t,n,o)=>{let c=null;const r=()=>window.hcaptcha;const a=()=>{clearTimeout(undefined)},s=()=>{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},i=()=>{r()&&u()};window.descopeHcaptchaCallback=e=>{const t=s();null==t||t.setAttribute("value",e),c=(new Date).getTime(),o(e)},window.descopeHcaptchaExpiredCallback=()=>{const e=s();null==e||e.setAttribute("value",""),o("")};const u=()=>{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((()=>{u()}),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=()=>{u()},(()=>{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)})(),{stop:a,start:i,refresh:()=>e(void 0,void 0,void 0,(function*(){const e=Date.now();if(!c)return;if(e-c>105e3){a();const e=c;return i(),new Promise((t=>{const n=setTimeout((()=>{console.warn("hCaptcha token refresh timed out"),t()}),5e3),o=()=>{c!==e?(clearTimeout(n),t()):setTimeout(o,150)};o()}))}return Promise.resolve()}))}}}));
|
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.10",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/descope/content"
|
|
@@ -14,23 +14,23 @@
|
|
|
14
14
|
"test": "jest"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@rollup/plugin-commonjs": "28.0.
|
|
17
|
+
"@rollup/plugin-commonjs": "28.0.6",
|
|
18
18
|
"@rollup/plugin-node-resolve": "16.0.1",
|
|
19
19
|
"@rollup/plugin-terser": "0.4.4",
|
|
20
|
-
"@rollup/plugin-typescript": "12.1.
|
|
20
|
+
"@rollup/plugin-typescript": "12.1.4",
|
|
21
21
|
"@testing-library/dom": "10.4.0",
|
|
22
22
|
"@testing-library/react": "16.3.0",
|
|
23
23
|
"@types/jest": "29.5.14",
|
|
24
|
-
"eslint": "9.
|
|
25
|
-
"eslint-plugin-import": "2.
|
|
24
|
+
"eslint": "9.31.0",
|
|
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.
|
|
28
|
+
"rollup": "4.45.0",
|
|
29
|
+
"ts-jest": "29.4.0",
|
|
30
30
|
"ts-node": "10.9.2",
|
|
31
31
|
"typescript": "5.8.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@fingerprintjs/fingerprintjs-pro": "3.11.
|
|
34
|
+
"@fingerprintjs/fingerprintjs-pro": "3.11.12"
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { default as loadHcaptcha } from './hcaptcha';
|
|
2
|
+
|
|
3
|
+
describe('hCaptcha script', () => {
|
|
4
|
+
let onTokenReady;
|
|
5
|
+
let element;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
// Mock DOM elements
|
|
9
|
+
element = document.createElement('div');
|
|
10
|
+
document.body.appendChild(element);
|
|
11
|
+
|
|
12
|
+
// Mock the token ready callback
|
|
13
|
+
onTokenReady = jest.fn();
|
|
14
|
+
|
|
15
|
+
// Mock the grecaptcha object
|
|
16
|
+
global.hcaptcha = {
|
|
17
|
+
enterprise: {
|
|
18
|
+
execute: jest.fn(() => Promise.resolve('mock-token')),
|
|
19
|
+
ready: jest.fn((callback) => callback()),
|
|
20
|
+
render: jest.fn(() => 'render-id'),
|
|
21
|
+
},
|
|
22
|
+
ready: jest.fn((callback) => callback()),
|
|
23
|
+
execute: jest.fn(() => Promise.resolve('mock-token')),
|
|
24
|
+
render: jest.fn(() => 'render-id'),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
global.onHcaptchaLoadCallback = null;
|
|
28
|
+
|
|
29
|
+
// Mock Date.now
|
|
30
|
+
jest.spyOn(Date, 'now').mockImplementation(() => 1000);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
document.getElementsByTagName('html')[0].innerHTML = '';
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should load reCAPTCHA script and return proper module', () => {
|
|
39
|
+
const initArgs = {
|
|
40
|
+
siteKey: 'test-site-key',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const module = loadHcaptcha(initArgs, {}, onTokenReady);
|
|
44
|
+
|
|
45
|
+
// Check that the module has the expected methods
|
|
46
|
+
expect(module).toHaveProperty('stop');
|
|
47
|
+
expect(module).toHaveProperty('start');
|
|
48
|
+
expect(module).toHaveProperty('refresh');
|
|
49
|
+
|
|
50
|
+
// Verify the methods are functions
|
|
51
|
+
expect(typeof module.stop).toBe('function');
|
|
52
|
+
expect(typeof module.start).toBe('function');
|
|
53
|
+
expect(typeof module.refresh).toBe('function');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should have a refresh method with timeout safety', () => {
|
|
57
|
+
const initArgs = {
|
|
58
|
+
siteKey: 'test-site-key',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Create module
|
|
62
|
+
const module = loadHcaptcha(initArgs, {}, onTokenReady);
|
|
63
|
+
|
|
64
|
+
// Verify refresh method exists and returns a promise
|
|
65
|
+
expect(typeof module.refresh).toBe('function');
|
|
66
|
+
|
|
67
|
+
// Verify the refresh method returns a Promise
|
|
68
|
+
const refreshPromise = module.refresh();
|
|
69
|
+
expect(refreshPromise).toBeInstanceOf(Promise);
|
|
70
|
+
});
|
|
71
|
+
});
|
package/src/hcaptcha.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*! Source: (c) hCaptcha and other contributors | https://docs.hcaptcha.com */
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
hcaptcha?: {
|
|
6
|
+
ready: (callback: () => void) => void;
|
|
7
|
+
execute: (widgetId: any, options: { action: string }) => Promise<string>;
|
|
8
|
+
render: (container: HTMLElement, parameters: any) => any;
|
|
9
|
+
};
|
|
10
|
+
onHcaptchaLoadCallback: () => void;
|
|
11
|
+
descopeHcaptchaCallback: (token: string) => void;
|
|
12
|
+
descopeHcaptchaExpiredCallback: () => void;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Token refresh time: 105 seconds (2 minutes minus 15 seconds)
|
|
17
|
+
// Set to refresh the token shortly before expiration to ensure
|
|
18
|
+
// we always have a valid token when submitting the form
|
|
19
|
+
const TOKEN_REFRESH_TIME_MS = 105000;
|
|
20
|
+
|
|
21
|
+
const loadHcaptcha = (
|
|
22
|
+
initArgs: {
|
|
23
|
+
siteKey: string;
|
|
24
|
+
},
|
|
25
|
+
_inputs: { baseUrl?: string },
|
|
26
|
+
onTokenReady: (token: string) => void,
|
|
27
|
+
) => {
|
|
28
|
+
let lastTokenFetchTime: number | null = null;
|
|
29
|
+
|
|
30
|
+
const getScriptURL = () => {
|
|
31
|
+
const url = new URL('https://js.hcaptcha.com/1/api.js');
|
|
32
|
+
url.searchParams.append('onload', 'onHcaptchaLoadCallback');
|
|
33
|
+
url.searchParams.append('render', 'explicit');
|
|
34
|
+
return url.toString();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const loadHcaptchaScript = () => {
|
|
38
|
+
const script = document.createElement('script');
|
|
39
|
+
script.src = getScriptURL();
|
|
40
|
+
script.async = true;
|
|
41
|
+
script.id = 'hcaptcha-script';
|
|
42
|
+
script.defer = true;
|
|
43
|
+
document.body.appendChild(script);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const getHcaptchaInstance = () => window.hcaptcha;
|
|
47
|
+
|
|
48
|
+
let timer;
|
|
49
|
+
let hcaptchaWidgetId: string;
|
|
50
|
+
|
|
51
|
+
const getNewToken = (hcaptchaInstance, currentNode) => {
|
|
52
|
+
if (!initArgs.siteKey || !currentNode) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
hcaptchaInstance
|
|
56
|
+
?.execute(hcaptchaWidgetId, { action: 'load', async: true })
|
|
57
|
+
.then((token: string, e: any) => {
|
|
58
|
+
if (e) {
|
|
59
|
+
console.warn('could not execute recaptcha', e);
|
|
60
|
+
} else {
|
|
61
|
+
onTokenReady(token);
|
|
62
|
+
lastTokenFetchTime = new Date().getTime();
|
|
63
|
+
// if the component is still connected, we should try to get a new token before the token expires (2 minutes)
|
|
64
|
+
timer = setTimeout(() => {
|
|
65
|
+
getNewToken(hcaptchaInstance, currentNode);
|
|
66
|
+
}, TOKEN_REFRESH_TIME_MS);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const stopTimer = () => {
|
|
72
|
+
clearTimeout(timer);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const getCaptchaElement = () => {
|
|
76
|
+
const wc = document.querySelector('descope-wc');
|
|
77
|
+
if (!wc) return null;
|
|
78
|
+
const wcShadow = wc.shadowRoot;
|
|
79
|
+
if (!wcShadow) return null;
|
|
80
|
+
const hcaptchaElem = wcShadow.querySelector('descope-hcaptcha');
|
|
81
|
+
if (!hcaptchaElem) return null;
|
|
82
|
+
const hcaptchaShadow = hcaptchaElem.shadowRoot;
|
|
83
|
+
if (!hcaptchaShadow) return null;
|
|
84
|
+
return hcaptchaShadow.getElementById('hcaptcha');
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const getCaptchaInput = () => {
|
|
88
|
+
const wc = document.querySelector('descope-wc');
|
|
89
|
+
if (!wc) return null;
|
|
90
|
+
const wcShadow = wc.shadowRoot;
|
|
91
|
+
if (!wcShadow) return null;
|
|
92
|
+
const hcaptchaElem = wcShadow.querySelector('descope-hcaptcha');
|
|
93
|
+
if (!hcaptchaElem) return null;
|
|
94
|
+
const hcaptchaShadow = hcaptchaElem.shadowRoot;
|
|
95
|
+
if (!hcaptchaShadow) return null;
|
|
96
|
+
return hcaptchaShadow.getElementById('hcaptcha-input');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const resumeScriptExecution = () => {
|
|
100
|
+
const hcaptchaInstance = getHcaptchaInstance();
|
|
101
|
+
if (!hcaptchaInstance) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
initializeHcaptcha();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Checks if the hCaptcha token needs refreshing and refreshes it if necessary
|
|
109
|
+
* This is called before form submission to ensure we have a valid token
|
|
110
|
+
* @returns Promise that resolves when token is refreshed or if refresh isn't needed
|
|
111
|
+
*/
|
|
112
|
+
const refreshIfTokenExpired = async (): Promise<void> => {
|
|
113
|
+
const currentTime = Date.now();
|
|
114
|
+
// if the token was never fetched, we don't need to refresh it
|
|
115
|
+
if (!lastTokenFetchTime) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const timeDiff = currentTime - lastTokenFetchTime;
|
|
119
|
+
|
|
120
|
+
if (timeDiff > TOKEN_REFRESH_TIME_MS) {
|
|
121
|
+
stopTimer();
|
|
122
|
+
const prev = lastTokenFetchTime;
|
|
123
|
+
resumeScriptExecution();
|
|
124
|
+
|
|
125
|
+
// Return a promise that resolves once the token is refreshed or times out
|
|
126
|
+
return new Promise<void>((resolve) => {
|
|
127
|
+
// Set a timeout to prevent indefinite waiting
|
|
128
|
+
const timeout = setTimeout(() => {
|
|
129
|
+
console.warn('hCaptcha token refresh timed out');
|
|
130
|
+
resolve(); // Resolve anyway to prevent blocking form submission
|
|
131
|
+
}, 5000); // 5 second timeout for token refresh
|
|
132
|
+
|
|
133
|
+
const checkToken = () => {
|
|
134
|
+
if (lastTokenFetchTime !== prev) {
|
|
135
|
+
clearTimeout(timeout);
|
|
136
|
+
resolve();
|
|
137
|
+
} else {
|
|
138
|
+
setTimeout(checkToken, 150);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
checkToken();
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// If no refresh is needed, return a resolved promise
|
|
147
|
+
return Promise.resolve();
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// Callback for hCaptcha success
|
|
151
|
+
window.descopeHcaptchaCallback = (token: string) => {
|
|
152
|
+
const input = getCaptchaInput();
|
|
153
|
+
input?.setAttribute('value', token)
|
|
154
|
+
lastTokenFetchTime = new Date().getTime();
|
|
155
|
+
onTokenReady(token);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
window.descopeHcaptchaExpiredCallback = () => {
|
|
159
|
+
const input = getCaptchaInput();
|
|
160
|
+
input?.setAttribute('value', '');
|
|
161
|
+
onTokenReady('');
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const initializeHcaptcha = () => {
|
|
165
|
+
const currentNode = getCaptchaElement();
|
|
166
|
+
|
|
167
|
+
// wait for element to load
|
|
168
|
+
if (!currentNode) {
|
|
169
|
+
setTimeout(() => {
|
|
170
|
+
initializeHcaptcha();
|
|
171
|
+
}
|
|
172
|
+
, 100);
|
|
173
|
+
// return to avoid executing the rest of the code
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// if there are child nodes, it means that the recaptcha was already rendered
|
|
178
|
+
if (currentNode?.hasChildNodes()) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const hcaptchaInstance = getHcaptchaInstance();
|
|
183
|
+
if (!hcaptchaInstance) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
currentNode.setAttribute('data-sitekey', initArgs.siteKey);
|
|
188
|
+
currentNode.setAttribute('data-callback', 'descopeHcaptchaCallback');
|
|
189
|
+
currentNode.setAttribute('data-expired-callback', 'descopeHcaptchaExpiredCallback');
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
hcaptchaWidgetId = hcaptchaInstance.render(currentNode, {
|
|
192
|
+
sitekey: initArgs.siteKey,
|
|
193
|
+
});
|
|
194
|
+
}, 0);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const createOnLoadScript = () => {
|
|
198
|
+
window.onHcaptchaLoadCallback = () => {
|
|
199
|
+
initializeHcaptcha();
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
createOnLoadScript();
|
|
204
|
+
loadHcaptchaScript();
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
stop: stopTimer,
|
|
208
|
+
start: resumeScriptExecution,
|
|
209
|
+
refresh: refreshIfTokenExpired,
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export default loadHcaptcha;
|