altcha 1.4.1 → 1.4.2

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/altcha.d.ts CHANGED
@@ -75,7 +75,7 @@ declare global {
75
75
  interface AltchaWidget extends AltchaWidgetOptions {
76
76
  }
77
77
 
78
- interface AltchaWidgetCSSProperties extends React.CSSProperties {
78
+ interface AltchaWidgetCSSProperties extends Partial<CSSStyleDeclaration> {
79
79
  '--altcha-border-width'?: string;
80
80
  '--altcha-border-radius'?: string;
81
81
  '--altcha-color-base'?: string;
@@ -87,9 +87,13 @@ declare global {
87
87
  '--altcha-max-width'?: string;
88
88
  }
89
89
 
90
- interface AltchaWidgetReact extends AltchaWidget, React.HTMLAttributes<HTMLElement> {
91
- children?: React.ReactNode;
92
- ref?: React.RefObject<HTMLElement | null>;
90
+ interface AltchaWidgetReactRefObject<T> {
91
+ current: T | null;
92
+ }
93
+
94
+ interface AltchaWidgetReact extends AltchaWidget {
95
+ children?: string | number | Node | DocumentFragment;
96
+ ref?: AltchaWidgetReactRefObject<HTMLElement>;
93
97
  style?: AltchaWidgetCSSProperties;
94
98
  }
95
99
 
package/dist/altcha.js CHANGED
@@ -1945,7 +1945,7 @@ function sa(e, t) {
1945
1945
  Zn(), w && (w.removeEventListener("submit", _r), w.removeEventListener("reset", mr), w.removeEventListener("focusin", gr), w = null), fe && (clearTimeout(fe), fe = null), document.removeEventListener("click", vr), document.removeEventListener("scroll", hr), window.removeEventListener("resize", pr);
1946
1946
  }), qn(() => {
1947
1947
  var n;
1948
- I("mounted", "1.4.1"), I("workers", Ue()), Qn(), I("plugins", xe.length ? xe.map((u) => u.constructor.pluginName).join(", ") : "none"), Q() && I("using test mode"), c() && zt(c()), r() !== void 0 && I("auto", r()), v() !== void 0 && yr(v()), w = (n = d(j)) == null ? void 0 : n.closest("form"), w && (w.addEventListener("submit", _r, { capture: !0 }), w.addEventListener("reset", mr), (r() === "onfocus" || m() === "focus") && w.addEventListener("focusin", gr)), r() === "onload" && (H() ? lt() : $e()), d(Pt) && (p() || T()) && I("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."), requestAnimationFrame(() => {
1948
+ I("mounted", "1.4.2"), I("workers", Ue()), Qn(), I("plugins", xe.length ? xe.map((u) => u.constructor.pluginName).join(", ") : "none"), Q() && I("using test mode"), c() && zt(c()), r() !== void 0 && I("auto", r()), v() !== void 0 && yr(v()), w = (n = d(j)) == null ? void 0 : n.closest("form"), w && (w.addEventListener("submit", _r, { capture: !0 }), w.addEventListener("reset", mr), (r() === "onfocus" || m() === "focus") && w.addEventListener("focusin", gr)), r() === "onload" && (H() ? lt() : $e()), d(Pt) && (p() || T()) && I("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."), requestAnimationFrame(() => {
1949
1949
  nt("load");
1950
1950
  });
1951
1951
  });
@@ -7,5 +7,5 @@
7
7
  100% {
8
8
  transform: rotate(360deg);
9
9
  }
10
- }`};function vn(e,t){var Wn,Yn;Yr(t,!0),ol(e,Fl);let r=R(t,"auto",7,void 0),l=R(t,"blockspam",7,void 0),i=R(t,"challengeurl",7,void 0),o=R(t,"challengejson",7,void 0),a=R(t,"customfetch",7,void 0),f=R(t,"debug",7,!1),s=R(t,"delay",7,0),c=R(t,"expire",7,void 0),v=R(t,"floating",7,void 0),h=R(t,"floatinganchor",7,void 0),g=R(t,"floatingoffset",7,void 0),m=R(t,"floatingpersist",7,!1),b=R(t,"hidefooter",7,!1),L=R(t,"hidelogo",7,!1),F=R(t,"id",7,void 0),Z=R(t,"name",7,"altcha"),j=R(t,"maxnumber",7,1e6),V=R(t,"mockerror",7,!1),G=R(t,"obfuscated",7,void 0),Ue=R(t,"plugins",7,void 0),M=R(t,"refetchonexpire",7,!0),B=R(t,"spamfilter",7,!1),$e=R(t,"strings",7,void 0),le=R(t,"test",7,!1),Ne=R(t,"verifyurl",7,void 0),Qe=R(t,"workers",23,()=>Math.min(16,navigator.hardwareConcurrency||8)),ct=R(t,"workerurl",7,void 0);const gn=["SHA-256","SHA-384","SHA-512"],_n="Visit Altcha.org",mn="https://altcha.org/",dt=(n,u)=>{t.$$host.dispatchEvent(new CustomEvent(n,{detail:u}))},pn=(Yn=(Wn=document.documentElement.lang)==null?void 0:Wn.split("-"))==null?void 0:Yn[0],tr=ze(()=>{var n;return i()&&new URL(i(),location.origin).host.endsWith(".altcha.org")&&!!((n=i())!=null&&n.includes("apiKey=ckey_"))}),rr=ze(()=>o()?Sn(o()):void 0),wn=ze(()=>$e()?Sn($e()):{}),oe=ze(()=>{var n;return{ariaLinkLabel:_n,error:"Verification failed. Try again later.",expired:"Verification expired. Try again.",footer:`Protected by <a href="${mn}" target="_blank" aria-label="${((n=d(wn))==null?void 0:n.ariaLinkLabel)||_n}">ALTCHA</a>`,label:"I'm not a robot",verified:"Verified",verifying:"Verifying...",waitAlert:"Verifying... please wait.",...d(wn)}}),bn=ze(()=>F()||`${Z()}_checkbox`);let et=We(!1),I=We(se(w.UNVERIFIED)),W=We(void 0),vt=We(null),tt=null,p=null,rt=We(null),_e=null,Le=[],je=We(null);Yt(()=>{Wl(d(rt))}),Yt(()=>{Yl(d(I))}),hl(()=>{Ml(),p&&(p.removeEventListener("submit",Cn),p.removeEventListener("reset",An),p.removeEventListener("focusin",kn),p=null),_e&&(clearTimeout(_e),_e=null),document.removeEventListener("click",xn),document.removeEventListener("scroll",$n),window.removeEventListener("resize",In)}),fn(()=>{var n;T("mounted","1.4.1"),T("workers",Qe()),ql(),T("plugins",Le.length?Le.map(u=>u.constructor.pluginName).join(", "):"none"),le()&&T("using test mode"),c()&&nr(c()),r()!==void 0&&T("auto",r()),v()!==void 0&&Tn(v()),p=(n=d(W))==null?void 0:n.closest("form"),p&&(p.addEventListener("submit",Cn,{capture:!0}),p.addEventListener("reset",An),(r()==="onfocus"||m()==="focus")&&p.addEventListener("focusin",kn)),r()==="onload"&&(G()?ht():De()),d(tr)&&(b()||L())&&T("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."),requestAnimationFrame(()=>{dt("load")})});function yn(n,u){return btoa(JSON.stringify({algorithm:n.algorithm,challenge:n.challenge,number:u.number,salt:n.salt,signature:n.signature,test:le()?!0:void 0,took:u.took}))}function Ml(){for(const n of Le)n.destroy()}function En(){i()&&M()&&d(I)===w.VERIFIED?De():_t(w.EXPIRED,d(oe).expired)}async function Ul(){var n;if(V())throw T("mocking error"),new Error("Mocked error.");if(d(rr))return T("using provided json data"),d(rr);if(le())return T("generating test challenge",{test:le()}),yl(typeof le()!="boolean"?+le():void 0);{if(!i()&&p){const P=p.getAttribute("action");P!=null&&P.includes("/form/")&&i(P+"/altcha")}if(!i())throw new Error("Attribute challengeurl not set.");T("fetching challenge from",i());let u=null,_=null;if(a())if(T("using customfetch"),typeof a()=="string"){if(u=globalThis[a()]||null,!u)throw new Error(`Custom fetch function not found: ${a()}`)}else u=a();const E={headers:B()!==!1?{"x-altcha-spam-filter":"1"}:{}};if(u){if(_=await u(i(),E),!_||!(_ instanceof Response))throw new Error("Custom fetch function did not return a response.")}else _=await fetch(i(),E);if(_.status!==200)throw new Error(`Server responded with ${_.status}.`);const N=_.headers.get("X-Altcha-Config"),$=await _.json(),y=new URLSearchParams((n=$.salt.split("?"))==null?void 0:n[1]),J=y.get("expires")||y.get("expire");if(J){const P=new Date(+J*1e3),it=isNaN(P.getTime())?0:P.getTime()-Date.now();it>0&&nr(it)}if(N)try{const P=JSON.parse(N);P&&typeof P=="object"&&(P.verifyurl&&(P.verifyurl=new URL(P.verifyurl,new URL(i())).toString()),Dn(P))}catch(P){T("unable to configure from X-Altcha-Config",P)}return $}}function jl(n){var _;const u=p==null?void 0:p.querySelector(typeof n=="string"?`input[name="${n}"]`:'input[type="email"]:not([data-no-spamfilter])');return((_=u==null?void 0:u.value)==null?void 0:_.slice(u.value.indexOf("@")))||void 0}function Vl(){return B()==="ipAddress"?{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:!1,expectedCountries:void 0,expectedLanguages:void 0,fields:!1,ipAddress:void 0,text:void 0,timeZone:void 0}:typeof B()=="object"?B():{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:void 0,expectedCountries:void 0,expectedLanguages:void 0,fields:void 0,ipAddress:void 0,text:void 0,timeZone:void 0}}function Bl(n){return[...(p==null?void 0:p.querySelectorAll(n!=null&&n.length?n.map(_=>`input[name="${_}"]`).join(", "):'input[type="text"]:not([data-no-spamfilter]), textarea:not([data-no-spamfilter])'))||[]].reduce((_,E)=>{const N=E.name,$=E.value;return N&&$&&(_[N]=/\n/.test($)?$.replace(new RegExp("(?<!\\r)\\n","g"),`\r
10
+ }`};function vn(e,t){var Wn,Yn;Yr(t,!0),ol(e,Fl);let r=R(t,"auto",7,void 0),l=R(t,"blockspam",7,void 0),i=R(t,"challengeurl",7,void 0),o=R(t,"challengejson",7,void 0),a=R(t,"customfetch",7,void 0),f=R(t,"debug",7,!1),s=R(t,"delay",7,0),c=R(t,"expire",7,void 0),v=R(t,"floating",7,void 0),h=R(t,"floatinganchor",7,void 0),g=R(t,"floatingoffset",7,void 0),m=R(t,"floatingpersist",7,!1),b=R(t,"hidefooter",7,!1),L=R(t,"hidelogo",7,!1),F=R(t,"id",7,void 0),Z=R(t,"name",7,"altcha"),j=R(t,"maxnumber",7,1e6),V=R(t,"mockerror",7,!1),G=R(t,"obfuscated",7,void 0),Ue=R(t,"plugins",7,void 0),M=R(t,"refetchonexpire",7,!0),B=R(t,"spamfilter",7,!1),$e=R(t,"strings",7,void 0),le=R(t,"test",7,!1),Ne=R(t,"verifyurl",7,void 0),Qe=R(t,"workers",23,()=>Math.min(16,navigator.hardwareConcurrency||8)),ct=R(t,"workerurl",7,void 0);const gn=["SHA-256","SHA-384","SHA-512"],_n="Visit Altcha.org",mn="https://altcha.org/",dt=(n,u)=>{t.$$host.dispatchEvent(new CustomEvent(n,{detail:u}))},pn=(Yn=(Wn=document.documentElement.lang)==null?void 0:Wn.split("-"))==null?void 0:Yn[0],tr=ze(()=>{var n;return i()&&new URL(i(),location.origin).host.endsWith(".altcha.org")&&!!((n=i())!=null&&n.includes("apiKey=ckey_"))}),rr=ze(()=>o()?Sn(o()):void 0),wn=ze(()=>$e()?Sn($e()):{}),oe=ze(()=>{var n;return{ariaLinkLabel:_n,error:"Verification failed. Try again later.",expired:"Verification expired. Try again.",footer:`Protected by <a href="${mn}" target="_blank" aria-label="${((n=d(wn))==null?void 0:n.ariaLinkLabel)||_n}">ALTCHA</a>`,label:"I'm not a robot",verified:"Verified",verifying:"Verifying...",waitAlert:"Verifying... please wait.",...d(wn)}}),bn=ze(()=>F()||`${Z()}_checkbox`);let et=We(!1),I=We(se(w.UNVERIFIED)),W=We(void 0),vt=We(null),tt=null,p=null,rt=We(null),_e=null,Le=[],je=We(null);Yt(()=>{Wl(d(rt))}),Yt(()=>{Yl(d(I))}),hl(()=>{Ml(),p&&(p.removeEventListener("submit",Cn),p.removeEventListener("reset",An),p.removeEventListener("focusin",kn),p=null),_e&&(clearTimeout(_e),_e=null),document.removeEventListener("click",xn),document.removeEventListener("scroll",$n),window.removeEventListener("resize",In)}),fn(()=>{var n;T("mounted","1.4.2"),T("workers",Qe()),ql(),T("plugins",Le.length?Le.map(u=>u.constructor.pluginName).join(", "):"none"),le()&&T("using test mode"),c()&&nr(c()),r()!==void 0&&T("auto",r()),v()!==void 0&&Tn(v()),p=(n=d(W))==null?void 0:n.closest("form"),p&&(p.addEventListener("submit",Cn,{capture:!0}),p.addEventListener("reset",An),(r()==="onfocus"||m()==="focus")&&p.addEventListener("focusin",kn)),r()==="onload"&&(G()?ht():De()),d(tr)&&(b()||L())&&T("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."),requestAnimationFrame(()=>{dt("load")})});function yn(n,u){return btoa(JSON.stringify({algorithm:n.algorithm,challenge:n.challenge,number:u.number,salt:n.salt,signature:n.signature,test:le()?!0:void 0,took:u.took}))}function Ml(){for(const n of Le)n.destroy()}function En(){i()&&M()&&d(I)===w.VERIFIED?De():_t(w.EXPIRED,d(oe).expired)}async function Ul(){var n;if(V())throw T("mocking error"),new Error("Mocked error.");if(d(rr))return T("using provided json data"),d(rr);if(le())return T("generating test challenge",{test:le()}),yl(typeof le()!="boolean"?+le():void 0);{if(!i()&&p){const P=p.getAttribute("action");P!=null&&P.includes("/form/")&&i(P+"/altcha")}if(!i())throw new Error("Attribute challengeurl not set.");T("fetching challenge from",i());let u=null,_=null;if(a())if(T("using customfetch"),typeof a()=="string"){if(u=globalThis[a()]||null,!u)throw new Error(`Custom fetch function not found: ${a()}`)}else u=a();const E={headers:B()!==!1?{"x-altcha-spam-filter":"1"}:{}};if(u){if(_=await u(i(),E),!_||!(_ instanceof Response))throw new Error("Custom fetch function did not return a response.")}else _=await fetch(i(),E);if(_.status!==200)throw new Error(`Server responded with ${_.status}.`);const N=_.headers.get("X-Altcha-Config"),$=await _.json(),y=new URLSearchParams((n=$.salt.split("?"))==null?void 0:n[1]),J=y.get("expires")||y.get("expire");if(J){const P=new Date(+J*1e3),it=isNaN(P.getTime())?0:P.getTime()-Date.now();it>0&&nr(it)}if(N)try{const P=JSON.parse(N);P&&typeof P=="object"&&(P.verifyurl&&(P.verifyurl=new URL(P.verifyurl,new URL(i())).toString()),Dn(P))}catch(P){T("unable to configure from X-Altcha-Config",P)}return $}}function jl(n){var _;const u=p==null?void 0:p.querySelector(typeof n=="string"?`input[name="${n}"]`:'input[type="email"]:not([data-no-spamfilter])');return((_=u==null?void 0:u.value)==null?void 0:_.slice(u.value.indexOf("@")))||void 0}function Vl(){return B()==="ipAddress"?{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:!1,expectedCountries:void 0,expectedLanguages:void 0,fields:!1,ipAddress:void 0,text:void 0,timeZone:void 0}:typeof B()=="object"?B():{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:void 0,expectedCountries:void 0,expectedLanguages:void 0,fields:void 0,ipAddress:void 0,text:void 0,timeZone:void 0}}function Bl(n){return[...(p==null?void 0:p.querySelectorAll(n!=null&&n.length?n.map(_=>`input[name="${_}"]`).join(", "):'input[type="text"]:not([data-no-spamfilter]), textarea:not([data-no-spamfilter])'))||[]].reduce((_,E)=>{const N=E.name,$=E.value;return N&&$&&(_[N]=/\n/.test($)?$.replace(new RegExp("(?<!\\r)\\n","g"),`\r
11
11
  `):$),_},{})}function ql(){const n=Ue()!==void 0?Ue().split(","):void 0;for(const u of globalThis.altchaPlugins)(!n||n.includes(u.pluginName))&&Le.push(new u({el:d(W),clarify:ht,dispatch:dt,getConfiguration:Pn,getFloatingAnchor:On,getState:zn,log:T,reset:_t,solve:Ln,setState:Ve,setFloatingAnchor:Mn,verify:De}))}function T(...n){(f()||n.some(u=>u instanceof Error))&&console[n[0]instanceof Error?"error":"log"]("ALTCHA",`[name=${Z()}]`,...n)}function Hl(){[w.UNVERIFIED,w.ERROR,w.EXPIRED].includes(d(I))?B()!==!1&&(p==null?void 0:p.reportValidity())===!1?O(et,!1):G()?ht():De():O(et,!0)}function xn(n){const u=n.target;v()&&u&&!d(W).contains(u)&&(d(I)===w.VERIFIED&&m()===!1||d(I)===w.VERIFIED&&m()==="focus"&&!(p!=null&&p.matches(":focus-within"))||r()==="off"&&d(I)===w.UNVERIFIED)&&Fn()}function $n(){v()&&d(I)!==w.UNVERIFIED&&gt()}function Wl(n){for(const u of Le)typeof u.onErrorChange=="function"&&u.onErrorChange(d(rt))}function kn(n){d(I)===w.UNVERIFIED?De():v()&&m()==="focus"&&d(I)===w.VERIFIED&&ir()}function Cn(n){p&&r()==="onsubmit"?d(I)===w.UNVERIFIED?(n.preventDefault(),n.stopPropagation(),De().then(()=>{p==null||p.requestSubmit()})):d(I)!==w.VERIFIED&&(n.preventDefault(),n.stopPropagation(),d(I)===w.VERIFYING&&Rn()):p&&v()&&r()==="off"&&d(I)===w.UNVERIFIED&&(n.preventDefault(),n.stopPropagation(),ir())}function An(){_t()}function Rn(){d(I)===w.VERIFYING&&d(oe).waitAlert&&alert(d(oe).waitAlert)}function Yl(n){for(const u of Le)typeof u.onStateChange=="function"&&u.onStateChange(d(I));v()&&d(I)!==w.UNVERIFIED&&requestAnimationFrame(()=>{gt()}),O(et,d(I)===w.VERIFIED)}function In(){v()&&gt()}function Sn(n){return JSON.parse(n)}async function Zl(n){if(!Ne())throw new Error("Attribute verifyurl not set.");T("requesting server verification from",Ne());const u={payload:n};if(B()!==!1){const{blockedCountries:N,classifier:$,disableRules:y,email:J,expectedLanguages:P,expectedCountries:it,fields:pt,ipAddress:wt,text:ao,timeZone:Zn}=Vl();u.blockedCountries=N,u.classifier=$,u.disableRules=y,u.email=J===!1?void 0:jl(J),u.expectedCountries=it,u.expectedLanguages=P||(pn?[pn]:void 0),u.fields=pt===!1?void 0:Bl(pt),u.ipAddress=wt===!1?void 0:wt||"auto",u.text=ao,u.timeZone=Zn===!1?void 0:Zn||xl()}const _=await fetch(Ne(),{body:JSON.stringify(u),headers:{"content-type":"application/json"},method:"POST"});if(_.status!==200)throw new Error(`Server responded with ${_.status}.`);const E=await _.json();if(E!=null&&E.payload&&O(je,se(E.payload)),dt("serververification",E),l()&&E.classification==="BAD")throw new Error("SpamFilter returned negative classification.")}function nr(n){T("expire",n),_e&&(clearTimeout(_e),_e=null),n<1?En():_e=setTimeout(En,n)}function Tn(n){T("floating",n),v()!==n&&(d(W).style.left="",d(W).style.top=""),v(n===!0||n===""?"auto":n===!1||n==="false"?void 0:v()),v()?(r()||r("onsubmit"),document.addEventListener("scroll",$n),document.addEventListener("click",xn),window.addEventListener("resize",In)):r()==="onsubmit"&&r(void 0)}function Nn(n){if(!n.algorithm)throw new Error("Invalid challenge. Property algorithm is missing.");if(n.signature===void 0)throw new Error("Invalid challenge. Property signature is missing.");if(!gn.includes(n.algorithm.toUpperCase()))throw new Error(`Unknown algorithm value. Allowed values: ${gn.join(", ")}`);if(!n.challenge||n.challenge.length<40)throw new Error("Challenge is too short. Min. 40 chars.");if(!n.salt||n.salt.length<10)throw new Error("Salt is too short. Min. 10 chars.")}async function Ln(n){let u=null;if("Worker"in window){try{u=await Gl(n,n.maxNumber||n.maxnumber||j())}catch(_){T(_)}if((u==null?void 0:u.number)!==void 0||"obfuscated"in n)return{data:n,solution:u}}if("obfuscated"in n){const _=await Cl(n.obfuscated,n.key,n.maxNumber||n.maxnumber);return{data:n,solution:await _.promise}}return{data:n,solution:await El(n.challenge,n.salt,n.algorithm,n.maxNumber||n.maxnumber||j()).promise}}async function Gl(n,u=typeof le()=="number"?le():n.maxNumber||n.maxnumber||j(),_=Math.ceil(Qe())){const E=[];_=Math.min(16,u,Math.max(1,_));for(let y=0;y<_;y++)E.push(altchaCreateWorker(ct()));const N=Math.ceil(u/_),$=await Promise.all(E.map((y,J)=>{const P=J*N;return new Promise(it=>{y.addEventListener("message",pt=>{if(pt.data)for(const wt of E)wt!==y&&wt.postMessage({type:"abort"});it(pt.data)}),y.postMessage({payload:n,max:P+N,start:P,type:"work"})})}));for(const y of E)y.terminate();return $.find(y=>!!y)||null}async function ht(){if(!G()){Ve(w.ERROR);return}const n=Le.find(u=>u.constructor.pluginName==="obfuscation");if(!n||!("clarify"in n)){Ve(w.ERROR),T("Plugin `obfuscation` not found. Import `altcha/plugins/obfuscation` to load it.");return}if("clarify"in n&&typeof n.clarify=="function")return n.clarify()}function Dn(n){n.obfuscated!==void 0&&G(n.obfuscated),n.auto!==void 0&&(r(n.auto),r()==="onload"&&(G()?ht():De())),n.blockspam!==void 0&&l(!!n.blockspam),n.customfetch!==void 0&&a(n.customfetch),n.floatinganchor!==void 0&&h(n.floatinganchor),n.delay!==void 0&&s(n.delay),n.floatingoffset!==void 0&&g(n.floatingoffset),n.floating!==void 0&&Tn(n.floating),n.expire!==void 0&&(nr(n.expire),c(n.expire)),n.challenge&&(o(typeof n.challenge=="string"?n.challenge:JSON.stringify(n.challenge)),Nn(d(rr))),n.challengeurl!==void 0&&i(n.challengeurl),n.debug!==void 0&&f(!!n.debug),n.hidefooter!==void 0&&b(!!n.hidefooter),n.hidelogo!==void 0&&L(!!n.hidelogo),n.maxnumber!==void 0&&j(+n.maxnumber),n.mockerror!==void 0&&V(!!n.mockerror),n.name!==void 0&&Z(n.name),n.refetchonexpire!==void 0&&M(!!n.refetchonexpire),n.spamfilter!==void 0&&B(typeof n.spamfilter=="object"?n.spamfilter:!!n.spamfilter),n.strings&&$e(typeof n.strings=="string"?n.strings:JSON.stringify(n.strings)),n.test!==void 0&&le(typeof n.test=="number"?n.test:!!n.test),n.verifyurl!==void 0&&Ne(n.verifyurl),n.workers!==void 0&&Qe(+n.workers),n.workerurl!==void 0&&ct(n.workerurl)}function Pn(){return{auto:r(),blockspam:l(),challengeurl:i(),debug:f(),delay:s(),expire:c(),floating:v(),floatinganchor:h(),floatingoffset:g(),hidefooter:b(),hidelogo:L(),name:Z(),maxnumber:j(),mockerror:V(),obfuscated:G(),refetchonexpire:M(),spamfilter:B(),strings:d(oe),test:le(),verifyurl:Ne(),workers:Qe(),workerurl:ct()}}function On(){return tt}function Jl(n){return Le.find(u=>u.constructor.pluginName===n)}function zn(){return d(I)}function Fn(){d(W).style.display="none"}function gt(n=20){if(d(W))if(tt||(tt=(h()?document.querySelector(h()):p==null?void 0:p.querySelector('input[type="submit"], button[type="submit"], button:not([type="button"]):not([type="reset"])'))||p),tt){const u=parseInt(g(),10)||12,_=tt.getBoundingClientRect(),E=d(W).getBoundingClientRect(),N=document.documentElement.clientHeight,$=document.documentElement.clientWidth,y=v()==="auto"?_.bottom+E.height+u+n>N:v()==="top",J=Math.max(n,Math.min($-n-E.width,_.left+_.width/2-E.width/2));if(y?d(W).style.top=`${_.top-(E.height+u)}px`:d(W).style.top=`${_.bottom+u}px`,d(W).style.left=`${J}px`,d(W).setAttribute("data-floating",y?"top":"bottom"),d(vt)){const P=d(vt).getBoundingClientRect();d(vt).style.left=_.left-J+_.width/2-P.width/2+"px"}}else T("unable to find floating anchor element")}function _t(n=w.UNVERIFIED,u=null){_e&&(clearTimeout(_e),_e=null),O(et,!1),O(je,null),Ve(n,u)}function Mn(n){tt=n}function Ve(n,u=null){O(I,se(n)),O(rt,se(u)),dt("statechange",{payload:d(je),state:d(I)})}function ir(){d(W).style.display="block",v()&&gt()}async function De(){return _t(w.VERIFYING),await new Promise(n=>setTimeout(n,s()||0)),Ul().then(n=>(Nn(n),T("challenge",n),Ln(n))).then(({data:n,solution:u})=>{if(T("solution",u),!u||n&&"challenge"in n&&!("clearText"in u))if((u==null?void 0:u.number)!==void 0&&"challenge"in n){if(Ne())return Zl(yn(n,u));O(je,se(yn(n,u))),T("payload",d(je))}else throw T("Unable to find a solution. Ensure that the 'maxnumber' attribute is greater than the randomly generated number."),new Error("Unexpected result returned.")}).then(()=>{Ve(w.VERIFIED),T("verified"),ji().then(()=>{dt("verified",{payload:d(je)})})}).catch(n=>{T(n),Ve(w.ERROR,n.message)})}var Un=zl(),jn=Nr(Un);ll(jn,t,"default",{});var mt=be(jn,2),lr=ee(mt),Vn=ee(lr);{var Kl=n=>{var u=Al();ne(n,u)};Te(Vn,n=>{d(I)===w.VERIFYING&&n(Kl)})}var Ft=be(Vn,2);let Bn;var nt=ee(Ft);nn(nt),nt.__change=Hl,Q(Ft);var or=be(Ft,2),Xl=ee(or);{var Ql=n=>{var u=Rl(),_=Nr(u),E=ee(_);Xe(E,()=>d(oe).verified),Q(_);var N=be(_,2);nn(N),Je(()=>{ue(N,"name",Z()),cl(N,d(je))}),ne(n,u)},eo=(n,u)=>{{var _=N=>{var $=Il(),y=ee($);Xe(y,()=>d(oe).verifying),Q($),ne(N,$)},E=N=>{var $=Sl(),y=ee($);Xe(y,()=>d(oe).label),Q($),Je(()=>ue($,"for",d(bn))),ne(N,$)};Te(n,N=>{d(I)===w.VERIFYING?N(_):N(E,!1)},u)}};Te(Xl,n=>{d(I)===w.VERIFIED?n(Ql):n(eo,!1)})}Q(or);var to=be(or,2);{var ro=n=>{var u=Tl(),_=ee(u);ue(_,"href",mn),Q(u),Je(()=>ue(_,"aria-label",d(oe).ariaLinkLabel)),ne(n,u)};Te(to,n=>{(L()!==!0||d(tr))&&n(ro)})}Q(lr);var qn=be(lr,2);{var no=n=>{var u=Dl(),_=be(ee(u),2);{var E=$=>{var y=Nl(),J=ee(y);Xe(J,()=>d(oe).expired),Q(y),Je(()=>ue(y,"title",d(rt))),ne($,y)},N=$=>{var y=Ll(),J=ee(y);Xe(J,()=>d(oe).error),Q(y),Je(()=>ue(y,"title",d(rt))),ne($,y)};Te(_,$=>{d(I)===w.EXPIRED?$(E):$(N,!1)})}Q(u),ne(n,u)};Te(qn,n=>{(d(rt)||d(I)===w.EXPIRED)&&n(no)})}var Hn=be(qn,2);{var io=n=>{var u=Pl(),_=ee(u),E=ee(_);Xe(E,()=>d(oe).footer),Q(_),Q(u),ne(n,u)};Te(Hn,n=>{d(oe).footer&&(b()!==!0||d(tr))&&n(io)})}var lo=be(Hn,2);{var oo=n=>{var u=Ol();sn(u,_=>O(vt,_),()=>d(vt)),ne(n,u)};Te(lo,n=>{v()&&n(oo)})}return Q(mt),sn(mt,n=>O(W,n),()=>d(W)),Je(n=>{ue(mt,"data-state",d(I)),ue(mt,"data-floating",v()),Bn=sl(Ft,1,"altcha-checkbox svelte-ddsc3z",null,Bn,n),ue(nt,"id",d(bn)),nt.required=r()!=="onsubmit"&&(!v()||r()!=="off")},[()=>({"altcha-hidden":d(I)===w.VERIFYING})]),el("invalid",nt,Rn),vl(nt,()=>d(et),n=>O(et,n)),ne(e,Un),Zr({clarify:ht,configure:Dn,getConfiguration:Pn,getFloatingAnchor:On,getPlugin:Jl,getState:zn,hide:Fn,repositionFloating:gt,reset:_t,setFloatingAnchor:Mn,setState:Ve,show:ir,verify:De,get auto(){return r()},set auto(n=void 0){r(n),x()},get blockspam(){return l()},set blockspam(n=void 0){l(n),x()},get challengeurl(){return i()},set challengeurl(n=void 0){i(n),x()},get challengejson(){return o()},set challengejson(n=void 0){o(n),x()},get customfetch(){return a()},set customfetch(n=void 0){a(n),x()},get debug(){return f()},set debug(n=!1){f(n),x()},get delay(){return s()},set delay(n=0){s(n),x()},get expire(){return c()},set expire(n=void 0){c(n),x()},get floating(){return v()},set floating(n=void 0){v(n),x()},get floatinganchor(){return h()},set floatinganchor(n=void 0){h(n),x()},get floatingoffset(){return g()},set floatingoffset(n=void 0){g(n),x()},get floatingpersist(){return m()},set floatingpersist(n=!1){m(n),x()},get hidefooter(){return b()},set hidefooter(n=!1){b(n),x()},get hidelogo(){return L()},set hidelogo(n=!1){L(n),x()},get id(){return F()},set id(n=void 0){F(n),x()},get name(){return Z()},set name(n="altcha"){Z(n),x()},get maxnumber(){return j()},set maxnumber(n=1e6){j(n),x()},get mockerror(){return V()},set mockerror(n=!1){V(n),x()},get obfuscated(){return G()},set obfuscated(n=void 0){G(n),x()},get plugins(){return Ue()},set plugins(n=void 0){Ue(n),x()},get refetchonexpire(){return M()},set refetchonexpire(n=!0){M(n),x()},get spamfilter(){return B()},set spamfilter(n=!1){B(n),x()},get strings(){return $e()},set strings(n=void 0){$e(n),x()},get test(){return le()},set test(n=!1){le(n),x()},get verifyurl(){return Ne()},set verifyurl(n=void 0){Ne(n),x()},get workers(){return Qe()},set workers(n=Math.min(16,navigator.hardwareConcurrency||8)){Qe(n),x()},get workerurl(){return ct()},set workerurl(n=void 0){ct(n),x()}})}tl(["change"]),customElements.define("altcha-widget",wl(vn,{blockspam:{type:"Boolean"},debug:{type:"Boolean"},delay:{type:"Number"},expire:{type:"Number"},floatingoffset:{type:"Number"},hidefooter:{type:"Boolean"},hidelogo:{type:"Boolean"},maxnumber:{type:"Number"},mockerror:{type:"Boolean"},refetchonexpire:{type:"Boolean"},test:{type:"Boolean"},workers:{type:"Number"},auto:{},challengeurl:{},challengejson:{},customfetch:{},floating:{},floatinganchor:{},floatingpersist:{},id:{},name:{},obfuscated:{},plugins:{},spamfilter:{},strings:{},verifyurl:{},workerurl:{}},["default"],["clarify","configure","getConfiguration","getFloatingAnchor","getPlugin","getState","hide","repositionFloating","reset","setFloatingAnchor","setState","show","verify"],!1)),globalThis.altchaCreateWorker=e=>e?new Worker(new URL(e)):new bt,globalThis.altchaPlugins=globalThis.altchaPlugins||[],k.Altcha=vn,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
@@ -75,7 +75,7 @@ declare global {
75
75
  interface AltchaWidget extends AltchaWidgetOptions {
76
76
  }
77
77
 
78
- interface AltchaWidgetCSSProperties extends React.CSSProperties {
78
+ interface AltchaWidgetCSSProperties extends Partial<CSSStyleDeclaration> {
79
79
  '--altcha-border-width'?: string;
80
80
  '--altcha-border-radius'?: string;
81
81
  '--altcha-color-base'?: string;
@@ -87,9 +87,13 @@ declare global {
87
87
  '--altcha-max-width'?: string;
88
88
  }
89
89
 
90
- interface AltchaWidgetReact extends AltchaWidget, React.HTMLAttributes<HTMLElement> {
91
- children?: React.ReactNode;
92
- ref?: React.RefObject<HTMLElement | null>;
90
+ interface AltchaWidgetReactRefObject<T> {
91
+ current: T | null;
92
+ }
93
+
94
+ interface AltchaWidgetReact extends AltchaWidget {
95
+ children?: string | number | Node | DocumentFragment;
96
+ ref?: AltchaWidgetReactRefObject<HTMLElement>;
93
97
  style?: AltchaWidgetCSSProperties;
94
98
  }
95
99
 
@@ -1922,7 +1922,7 @@ function la(e, t) {
1922
1922
  Yn(), p && (p.removeEventListener("submit", _r), p.removeEventListener("reset", mr), p.removeEventListener("focusin", gr), p = null), fe && (clearTimeout(fe), fe = null), document.removeEventListener("click", vr), document.removeEventListener("scroll", hr), window.removeEventListener("resize", wr);
1923
1923
  }), jn(() => {
1924
1924
  var n;
1925
- R("mounted", "1.4.0"), R("workers", Ve()), Kn(), R("plugins", xe.length ? xe.map((u) => u.constructor.pluginName).join(", ") : "none"), Q() && R("using test mode"), c() && Ot(c()), r() !== void 0 && R("auto", r()), v() !== void 0 && yr(v()), p = (n = d(U)) == null ? void 0 : n.closest("form"), p && (p.addEventListener("submit", _r, { capture: !0 }), p.addEventListener("reset", mr), (r() === "onfocus" || m() === "focus") && p.addEventListener("focusin", gr)), r() === "onload" && (H() ? lt() : $e()), d(Pt) && (w() || N()) && R("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."), requestAnimationFrame(() => {
1925
+ R("mounted", "1.4.1"), R("workers", Ve()), Kn(), R("plugins", xe.length ? xe.map((u) => u.constructor.pluginName).join(", ") : "none"), Q() && R("using test mode"), c() && Ot(c()), r() !== void 0 && R("auto", r()), v() !== void 0 && yr(v()), p = (n = d(U)) == null ? void 0 : n.closest("form"), p && (p.addEventListener("submit", _r, { capture: !0 }), p.addEventListener("reset", mr), (r() === "onfocus" || m() === "focus") && p.addEventListener("focusin", gr)), r() === "onload" && (H() ? lt() : $e()), d(Pt) && (w() || N()) && R("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."), requestAnimationFrame(() => {
1926
1926
  nt("load");
1927
1927
  });
1928
1928
  });
@@ -6,5 +6,5 @@
6
6
  100% {
7
7
  transform: rotate(360deg);
8
8
  }
9
- }`};function vn(e,t){var Yn,Wn;Wr(t,!0),il(e,zl);let r=R(t,"auto",7,void 0),l=R(t,"blockspam",7,void 0),i=R(t,"challengeurl",7,void 0),a=R(t,"challengejson",7,void 0),o=R(t,"customfetch",7,void 0),f=R(t,"debug",7,!1),s=R(t,"delay",7,0),c=R(t,"expire",7,void 0),v=R(t,"floating",7,void 0),h=R(t,"floatinganchor",7,void 0),g=R(t,"floatingoffset",7,void 0),m=R(t,"floatingpersist",7,!1),b=R(t,"hidefooter",7,!1),L=R(t,"hidelogo",7,!1),F=R(t,"id",7,void 0),Z=R(t,"name",7,"altcha"),V=R(t,"maxnumber",7,1e6),j=R(t,"mockerror",7,!1),G=R(t,"obfuscated",7,void 0),Ve=R(t,"plugins",7,void 0),M=R(t,"refetchonexpire",7,!0),q=R(t,"spamfilter",7,!1),$e=R(t,"strings",7,void 0),le=R(t,"test",7,!1),Ne=R(t,"verifyurl",7,void 0),Qe=R(t,"workers",23,()=>Math.min(16,navigator.hardwareConcurrency||8)),ct=R(t,"workerurl",7,void 0);const gn=["SHA-256","SHA-384","SHA-512"],_n="Visit Altcha.org",mn="https://altcha.org/",dt=(n,u)=>{t.$$host.dispatchEvent(new CustomEvent(n,{detail:u}))},pn=(Wn=(Yn=document.documentElement.lang)==null?void 0:Yn.split("-"))==null?void 0:Wn[0],tr=Oe(()=>{var n;return i()&&new URL(i(),location.origin).host.endsWith(".altcha.org")&&!!((n=i())!=null&&n.includes("apiKey=ckey_"))}),rr=Oe(()=>a()?Sn(a()):void 0),wn=Oe(()=>$e()?Sn($e()):{}),ae=Oe(()=>{var n;return{ariaLinkLabel:_n,error:"Verification failed. Try again later.",expired:"Verification expired. Try again.",footer:`Protected by <a href="${mn}" target="_blank" aria-label="${((n=d(wn))==null?void 0:n.ariaLinkLabel)||_n}">ALTCHA</a>`,label:"I'm not a robot",verified:"Verified",verifying:"Verifying...",waitAlert:"Verifying... please wait.",...d(wn)}}),bn=Oe(()=>F()||`${Z()}_checkbox`);let et=Ye(!1),I=Ye(se(w.UNVERIFIED)),Y=Ye(void 0),vt=Ye(null),tt=null,p=null,rt=Ye(null),_e=null,Le=[],Ue=Ye(null);Wt(()=>{Bl(d(rt))}),Wt(()=>{Hl(d(I))}),dl(()=>{Ol(),p&&(p.removeEventListener("submit",Cn),p.removeEventListener("reset",An),p.removeEventListener("focusin",kn),p=null),_e&&(clearTimeout(_e),_e=null),document.removeEventListener("click",xn),document.removeEventListener("scroll",$n),window.removeEventListener("resize",In)}),fn(()=>{var n;T("mounted","1.4.0"),T("workers",Qe()),jl(),T("plugins",Le.length?Le.map(u=>u.constructor.pluginName).join(", "):"none"),le()&&T("using test mode"),c()&&nr(c()),r()!==void 0&&T("auto",r()),v()!==void 0&&Tn(v()),p=(n=d(Y))==null?void 0:n.closest("form"),p&&(p.addEventListener("submit",Cn,{capture:!0}),p.addEventListener("reset",An),(r()==="onfocus"||m()==="focus")&&p.addEventListener("focusin",kn)),r()==="onload"&&(G()?ht():De()),d(tr)&&(b()||L())&&T("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."),requestAnimationFrame(()=>{dt("load")})});function yn(n,u){return btoa(JSON.stringify({algorithm:n.algorithm,challenge:n.challenge,number:u.number,salt:n.salt,signature:n.signature,test:le()?!0:void 0,took:u.took}))}function Ol(){for(const n of Le)n.destroy()}function En(){i()&&M()&&d(I)===w.VERIFIED?De():_t(w.EXPIRED,d(ae).expired)}async function Fl(){var n;if(j())throw T("mocking error"),new Error("Mocked error.");if(d(rr))return T("using provided json data"),d(rr);if(le())return T("generating test challenge",{test:le()}),wl(typeof le()!="boolean"?+le():void 0);{if(!i()&&p){const P=p.getAttribute("action");P!=null&&P.includes("/form/")&&i(P+"/altcha")}if(!i())throw new Error("Attribute challengeurl not set.");T("fetching challenge from",i());let u=null,_=null;if(o())if(T("using customfetch"),typeof o()=="string"){if(u=globalThis[o()]||null,!u)throw new Error(`Custom fetch function not found: ${o()}`)}else u=o();const E={headers:q()!==!1?{"x-altcha-spam-filter":"1"}:{}};if(u){if(_=await u(i(),E),!_||!(_ instanceof Response))throw new Error("Custom fetch function did not return a response.")}else _=await fetch(i(),E);if(_.status!==200)throw new Error(`Server responded with ${_.status}.`);const N=_.headers.get("X-Altcha-Config"),$=await _.json(),y=new URLSearchParams((n=$.salt.split("?"))==null?void 0:n[1]),J=y.get("expires")||y.get("expire");if(J){const P=new Date(+J*1e3),it=isNaN(P.getTime())?0:P.getTime()-Date.now();it>0&&nr(it)}if(N)try{const P=JSON.parse(N);P&&typeof P=="object"&&(P.verifyurl&&(P.verifyurl=new URL(P.verifyurl,new URL(i())).toString()),Dn(P))}catch(P){T("unable to configure from X-Altcha-Config",P)}return $}}function Ml(n){var _;const u=p==null?void 0:p.querySelector(typeof n=="string"?`input[name="${n}"]`:'input[type="email"]:not([data-no-spamfilter])');return((_=u==null?void 0:u.value)==null?void 0:_.slice(u.value.indexOf("@")))||void 0}function Vl(){return q()==="ipAddress"?{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:!1,expectedCountries:void 0,expectedLanguages:void 0,fields:!1,ipAddress:void 0,text:void 0,timeZone:void 0}:typeof q()=="object"?q():{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:void 0,expectedCountries:void 0,expectedLanguages:void 0,fields:void 0,ipAddress:void 0,text:void 0,timeZone:void 0}}function Ul(n){return[...(p==null?void 0:p.querySelectorAll(n!=null&&n.length?n.map(_=>`input[name="${_}"]`).join(", "):'input[type="text"]:not([data-no-spamfilter]), textarea:not([data-no-spamfilter])'))||[]].reduce((_,E)=>{const N=E.name,$=E.value;return N&&$&&(_[N]=/\n/.test($)?$.replace(new RegExp("(?<!\\r)\\n","g"),`\r
9
+ }`};function vn(e,t){var Yn,Wn;Wr(t,!0),il(e,zl);let r=R(t,"auto",7,void 0),l=R(t,"blockspam",7,void 0),i=R(t,"challengeurl",7,void 0),a=R(t,"challengejson",7,void 0),o=R(t,"customfetch",7,void 0),f=R(t,"debug",7,!1),s=R(t,"delay",7,0),c=R(t,"expire",7,void 0),v=R(t,"floating",7,void 0),h=R(t,"floatinganchor",7,void 0),g=R(t,"floatingoffset",7,void 0),m=R(t,"floatingpersist",7,!1),b=R(t,"hidefooter",7,!1),L=R(t,"hidelogo",7,!1),F=R(t,"id",7,void 0),Z=R(t,"name",7,"altcha"),V=R(t,"maxnumber",7,1e6),j=R(t,"mockerror",7,!1),G=R(t,"obfuscated",7,void 0),Ve=R(t,"plugins",7,void 0),M=R(t,"refetchonexpire",7,!0),q=R(t,"spamfilter",7,!1),$e=R(t,"strings",7,void 0),le=R(t,"test",7,!1),Ne=R(t,"verifyurl",7,void 0),Qe=R(t,"workers",23,()=>Math.min(16,navigator.hardwareConcurrency||8)),ct=R(t,"workerurl",7,void 0);const gn=["SHA-256","SHA-384","SHA-512"],_n="Visit Altcha.org",mn="https://altcha.org/",dt=(n,u)=>{t.$$host.dispatchEvent(new CustomEvent(n,{detail:u}))},pn=(Wn=(Yn=document.documentElement.lang)==null?void 0:Yn.split("-"))==null?void 0:Wn[0],tr=Oe(()=>{var n;return i()&&new URL(i(),location.origin).host.endsWith(".altcha.org")&&!!((n=i())!=null&&n.includes("apiKey=ckey_"))}),rr=Oe(()=>a()?Sn(a()):void 0),wn=Oe(()=>$e()?Sn($e()):{}),ae=Oe(()=>{var n;return{ariaLinkLabel:_n,error:"Verification failed. Try again later.",expired:"Verification expired. Try again.",footer:`Protected by <a href="${mn}" target="_blank" aria-label="${((n=d(wn))==null?void 0:n.ariaLinkLabel)||_n}">ALTCHA</a>`,label:"I'm not a robot",verified:"Verified",verifying:"Verifying...",waitAlert:"Verifying... please wait.",...d(wn)}}),bn=Oe(()=>F()||`${Z()}_checkbox`);let et=Ye(!1),I=Ye(se(w.UNVERIFIED)),Y=Ye(void 0),vt=Ye(null),tt=null,p=null,rt=Ye(null),_e=null,Le=[],Ue=Ye(null);Wt(()=>{Bl(d(rt))}),Wt(()=>{Hl(d(I))}),dl(()=>{Ol(),p&&(p.removeEventListener("submit",Cn),p.removeEventListener("reset",An),p.removeEventListener("focusin",kn),p=null),_e&&(clearTimeout(_e),_e=null),document.removeEventListener("click",xn),document.removeEventListener("scroll",$n),window.removeEventListener("resize",In)}),fn(()=>{var n;T("mounted","1.4.1"),T("workers",Qe()),jl(),T("plugins",Le.length?Le.map(u=>u.constructor.pluginName).join(", "):"none"),le()&&T("using test mode"),c()&&nr(c()),r()!==void 0&&T("auto",r()),v()!==void 0&&Tn(v()),p=(n=d(Y))==null?void 0:n.closest("form"),p&&(p.addEventListener("submit",Cn,{capture:!0}),p.addEventListener("reset",An),(r()==="onfocus"||m()==="focus")&&p.addEventListener("focusin",kn)),r()==="onload"&&(G()?ht():De()),d(tr)&&(b()||L())&&T("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."),requestAnimationFrame(()=>{dt("load")})});function yn(n,u){return btoa(JSON.stringify({algorithm:n.algorithm,challenge:n.challenge,number:u.number,salt:n.salt,signature:n.signature,test:le()?!0:void 0,took:u.took}))}function Ol(){for(const n of Le)n.destroy()}function En(){i()&&M()&&d(I)===w.VERIFIED?De():_t(w.EXPIRED,d(ae).expired)}async function Fl(){var n;if(j())throw T("mocking error"),new Error("Mocked error.");if(d(rr))return T("using provided json data"),d(rr);if(le())return T("generating test challenge",{test:le()}),wl(typeof le()!="boolean"?+le():void 0);{if(!i()&&p){const P=p.getAttribute("action");P!=null&&P.includes("/form/")&&i(P+"/altcha")}if(!i())throw new Error("Attribute challengeurl not set.");T("fetching challenge from",i());let u=null,_=null;if(o())if(T("using customfetch"),typeof o()=="string"){if(u=globalThis[o()]||null,!u)throw new Error(`Custom fetch function not found: ${o()}`)}else u=o();const E={headers:q()!==!1?{"x-altcha-spam-filter":"1"}:{}};if(u){if(_=await u(i(),E),!_||!(_ instanceof Response))throw new Error("Custom fetch function did not return a response.")}else _=await fetch(i(),E);if(_.status!==200)throw new Error(`Server responded with ${_.status}.`);const N=_.headers.get("X-Altcha-Config"),$=await _.json(),y=new URLSearchParams((n=$.salt.split("?"))==null?void 0:n[1]),J=y.get("expires")||y.get("expire");if(J){const P=new Date(+J*1e3),it=isNaN(P.getTime())?0:P.getTime()-Date.now();it>0&&nr(it)}if(N)try{const P=JSON.parse(N);P&&typeof P=="object"&&(P.verifyurl&&(P.verifyurl=new URL(P.verifyurl,new URL(i())).toString()),Dn(P))}catch(P){T("unable to configure from X-Altcha-Config",P)}return $}}function Ml(n){var _;const u=p==null?void 0:p.querySelector(typeof n=="string"?`input[name="${n}"]`:'input[type="email"]:not([data-no-spamfilter])');return((_=u==null?void 0:u.value)==null?void 0:_.slice(u.value.indexOf("@")))||void 0}function Vl(){return q()==="ipAddress"?{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:!1,expectedCountries:void 0,expectedLanguages:void 0,fields:!1,ipAddress:void 0,text:void 0,timeZone:void 0}:typeof q()=="object"?q():{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:void 0,expectedCountries:void 0,expectedLanguages:void 0,fields:void 0,ipAddress:void 0,text:void 0,timeZone:void 0}}function Ul(n){return[...(p==null?void 0:p.querySelectorAll(n!=null&&n.length?n.map(_=>`input[name="${_}"]`).join(", "):'input[type="text"]:not([data-no-spamfilter]), textarea:not([data-no-spamfilter])'))||[]].reduce((_,E)=>{const N=E.name,$=E.value;return N&&$&&(_[N]=/\n/.test($)?$.replace(new RegExp("(?<!\\r)\\n","g"),`\r
10
10
  `):$),_},{})}function jl(){const n=Ve()!==void 0?Ve().split(","):void 0;for(const u of globalThis.altchaPlugins)(!n||n.includes(u.pluginName))&&Le.push(new u({el:d(Y),clarify:ht,dispatch:dt,getConfiguration:Pn,getFloatingAnchor:zn,getState:On,log:T,reset:_t,solve:Ln,setState:je,setFloatingAnchor:Mn,verify:De}))}function T(...n){(f()||n.some(u=>u instanceof Error))&&console[n[0]instanceof Error?"error":"log"]("ALTCHA",`[name=${Z()}]`,...n)}function ql(){[w.UNVERIFIED,w.ERROR,w.EXPIRED].includes(d(I))?q()!==!1&&(p==null?void 0:p.reportValidity())===!1?z(et,!1):G()?ht():De():z(et,!0)}function xn(n){const u=n.target;v()&&u&&!d(Y).contains(u)&&(d(I)===w.VERIFIED&&m()===!1||d(I)===w.VERIFIED&&m()==="focus"&&!(p!=null&&p.matches(":focus-within"))||r()==="off"&&d(I)===w.UNVERIFIED)&&Fn()}function $n(){v()&&d(I)!==w.UNVERIFIED&&gt()}function Bl(n){for(const u of Le)typeof u.onErrorChange=="function"&&u.onErrorChange(d(rt))}function kn(n){d(I)===w.UNVERIFIED?De():v()&&m()==="focus"&&d(I)===w.VERIFIED&&ir()}function Cn(n){p&&r()==="onsubmit"?d(I)===w.UNVERIFIED?(n.preventDefault(),n.stopPropagation(),De().then(()=>{p==null||p.requestSubmit()})):d(I)!==w.VERIFIED&&(n.preventDefault(),n.stopPropagation(),d(I)===w.VERIFYING&&Rn()):p&&v()&&r()==="off"&&d(I)===w.UNVERIFIED&&(n.preventDefault(),n.stopPropagation(),ir())}function An(){_t()}function Rn(){d(I)===w.VERIFYING&&d(ae).waitAlert&&alert(d(ae).waitAlert)}function Hl(n){for(const u of Le)typeof u.onStateChange=="function"&&u.onStateChange(d(I));v()&&d(I)!==w.UNVERIFIED&&requestAnimationFrame(()=>{gt()}),z(et,d(I)===w.VERIFIED)}function In(){v()&&gt()}function Sn(n){return JSON.parse(n)}async function Yl(n){if(!Ne())throw new Error("Attribute verifyurl not set.");T("requesting server verification from",Ne());const u={payload:n};if(q()!==!1){const{blockedCountries:N,classifier:$,disableRules:y,email:J,expectedLanguages:P,expectedCountries:it,fields:pt,ipAddress:wt,text:la,timeZone:Zn}=Vl();u.blockedCountries=N,u.classifier=$,u.disableRules=y,u.email=J===!1?void 0:Ml(J),u.expectedCountries=it,u.expectedLanguages=P||(pn?[pn]:void 0),u.fields=pt===!1?void 0:Ul(pt),u.ipAddress=wt===!1?void 0:wt||"auto",u.text=la,u.timeZone=Zn===!1?void 0:Zn||yl()}const _=await fetch(Ne(),{body:JSON.stringify(u),headers:{"content-type":"application/json"},method:"POST"});if(_.status!==200)throw new Error(`Server responded with ${_.status}.`);const E=await _.json();if(E!=null&&E.payload&&z(Ue,se(E.payload)),dt("serververification",E),l()&&E.classification==="BAD")throw new Error("SpamFilter returned negative classification.")}function nr(n){T("expire",n),_e&&(clearTimeout(_e),_e=null),n<1?En():_e=setTimeout(En,n)}function Tn(n){T("floating",n),v()!==n&&(d(Y).style.left="",d(Y).style.top=""),v(n===!0||n===""?"auto":n===!1||n==="false"?void 0:v()),v()?(r()||r("onsubmit"),document.addEventListener("scroll",$n),document.addEventListener("click",xn),window.addEventListener("resize",In)):r()==="onsubmit"&&r(void 0)}function Nn(n){if(!n.algorithm)throw new Error("Invalid challenge. Property algorithm is missing.");if(n.signature===void 0)throw new Error("Invalid challenge. Property signature is missing.");if(!gn.includes(n.algorithm.toUpperCase()))throw new Error(`Unknown algorithm value. Allowed values: ${gn.join(", ")}`);if(!n.challenge||n.challenge.length<40)throw new Error("Challenge is too short. Min. 40 chars.");if(!n.salt||n.salt.length<10)throw new Error("Salt is too short. Min. 10 chars.")}async function Ln(n){let u=null;if("Worker"in window){try{u=await Wl(n,n.maxNumber||n.maxnumber||V())}catch(_){T(_)}if((u==null?void 0:u.number)!==void 0||"obfuscated"in n)return{data:n,solution:u}}if("obfuscated"in n){const _=await $l(n.obfuscated,n.key,n.maxNumber||n.maxnumber);return{data:n,solution:await _.promise}}return{data:n,solution:await bl(n.challenge,n.salt,n.algorithm,n.maxNumber||n.maxnumber||V()).promise}}async function Wl(n,u=typeof le()=="number"?le():n.maxNumber||n.maxnumber||V(),_=Math.ceil(Qe())){const E=[];_=Math.min(16,u,Math.max(1,_));for(let y=0;y<_;y++)E.push(altchaCreateWorker(ct()));const N=Math.ceil(u/_),$=await Promise.all(E.map((y,J)=>{const P=J*N;return new Promise(it=>{y.addEventListener("message",pt=>{if(pt.data)for(const wt of E)wt!==y&&wt.postMessage({type:"abort"});it(pt.data)}),y.postMessage({payload:n,max:P+N,start:P,type:"work"})})}));for(const y of E)y.terminate();return $.find(y=>!!y)||null}async function ht(){if(!G()){je(w.ERROR);return}const n=Le.find(u=>u.constructor.pluginName==="obfuscation");if(!n||!("clarify"in n)){je(w.ERROR),T("Plugin `obfuscation` not found. Import `altcha/plugins/obfuscation` to load it.");return}if("clarify"in n&&typeof n.clarify=="function")return n.clarify()}function Dn(n){n.obfuscated!==void 0&&G(n.obfuscated),n.auto!==void 0&&(r(n.auto),r()==="onload"&&(G()?ht():De())),n.blockspam!==void 0&&l(!!n.blockspam),n.customfetch!==void 0&&o(n.customfetch),n.floatinganchor!==void 0&&h(n.floatinganchor),n.delay!==void 0&&s(n.delay),n.floatingoffset!==void 0&&g(n.floatingoffset),n.floating!==void 0&&Tn(n.floating),n.expire!==void 0&&(nr(n.expire),c(n.expire)),n.challenge&&(a(typeof n.challenge=="string"?n.challenge:JSON.stringify(n.challenge)),Nn(d(rr))),n.challengeurl!==void 0&&i(n.challengeurl),n.debug!==void 0&&f(!!n.debug),n.hidefooter!==void 0&&b(!!n.hidefooter),n.hidelogo!==void 0&&L(!!n.hidelogo),n.maxnumber!==void 0&&V(+n.maxnumber),n.mockerror!==void 0&&j(!!n.mockerror),n.name!==void 0&&Z(n.name),n.refetchonexpire!==void 0&&M(!!n.refetchonexpire),n.spamfilter!==void 0&&q(typeof n.spamfilter=="object"?n.spamfilter:!!n.spamfilter),n.strings&&$e(typeof n.strings=="string"?n.strings:JSON.stringify(n.strings)),n.test!==void 0&&le(typeof n.test=="number"?n.test:!!n.test),n.verifyurl!==void 0&&Ne(n.verifyurl),n.workers!==void 0&&Qe(+n.workers),n.workerurl!==void 0&&ct(n.workerurl)}function Pn(){return{auto:r(),blockspam:l(),challengeurl:i(),debug:f(),delay:s(),expire:c(),floating:v(),floatinganchor:h(),floatingoffset:g(),hidefooter:b(),hidelogo:L(),name:Z(),maxnumber:V(),mockerror:j(),obfuscated:G(),refetchonexpire:M(),spamfilter:q(),strings:d(ae),test:le(),verifyurl:Ne(),workers:Qe(),workerurl:ct()}}function zn(){return tt}function Zl(n){return Le.find(u=>u.constructor.pluginName===n)}function On(){return d(I)}function Fn(){d(Y).style.display="none"}function gt(n=20){if(d(Y))if(tt||(tt=(h()?document.querySelector(h()):p==null?void 0:p.querySelector('input[type="submit"], button[type="submit"], button:not([type="button"]):not([type="reset"])'))||p),tt){const u=parseInt(g(),10)||12,_=tt.getBoundingClientRect(),E=d(Y).getBoundingClientRect(),N=document.documentElement.clientHeight,$=document.documentElement.clientWidth,y=v()==="auto"?_.bottom+E.height+u+n>N:v()==="top",J=Math.max(n,Math.min($-n-E.width,_.left+_.width/2-E.width/2));if(y?d(Y).style.top=`${_.top-(E.height+u)}px`:d(Y).style.top=`${_.bottom+u}px`,d(Y).style.left=`${J}px`,d(Y).setAttribute("data-floating",y?"top":"bottom"),d(vt)){const P=d(vt).getBoundingClientRect();d(vt).style.left=_.left-J+_.width/2-P.width/2+"px"}}else T("unable to find floating anchor element")}function _t(n=w.UNVERIFIED,u=null){_e&&(clearTimeout(_e),_e=null),z(et,!1),z(Ue,null),je(n,u)}function Mn(n){tt=n}function je(n,u=null){z(I,se(n)),z(rt,se(u)),dt("statechange",{payload:d(Ue),state:d(I)})}function ir(){d(Y).style.display="block",v()&&gt()}async function De(){return _t(w.VERIFYING),await new Promise(n=>setTimeout(n,s()||0)),Fl().then(n=>(Nn(n),T("challenge",n),Ln(n))).then(({data:n,solution:u})=>{if(T("solution",u),!u||n&&"challenge"in n&&!("clearText"in u))if((u==null?void 0:u.number)!==void 0&&"challenge"in n){if(Ne())return Yl(yn(n,u));z(Ue,se(yn(n,u))),T("payload",d(Ue))}else throw T("Unable to find a solution. Ensure that the 'maxnumber' attribute is greater than the randomly generated number."),new Error("Unexpected result returned.")}).then(()=>{je(w.VERIFIED),T("verified"),Mi().then(()=>{dt("verified",{payload:d(Ue)})})}).catch(n=>{T(n),je(w.ERROR,n.message)})}var Vn=Pl(),Un=Nr(Vn);nl(Un,t,"default",{});var mt=be(Un,2),lr=ee(mt),jn=ee(lr);{var Gl=n=>{var u=kl();ne(n,u)};Te(jn,n=>{d(I)===w.VERIFYING&&n(Gl)})}var Ft=be(jn,2);let qn;var nt=ee(Ft);nn(nt),nt.__change=ql,Q(Ft);var ar=be(Ft,2),Jl=ee(ar);{var Kl=n=>{var u=Cl(),_=Nr(u),E=ee(_);Xe(E,()=>d(ae).verified),Q(_);var N=be(_,2);nn(N),Je(()=>{ue(N,"name",Z()),fl(N,d(Ue))}),ne(n,u)},Xl=(n,u)=>{{var _=N=>{var $=Al(),y=ee($);Xe(y,()=>d(ae).verifying),Q($),ne(N,$)},E=N=>{var $=Rl(),y=ee($);Xe(y,()=>d(ae).label),Q($),Je(()=>ue($,"for",d(bn))),ne(N,$)};Te(n,N=>{d(I)===w.VERIFYING?N(_):N(E,!1)},u)}};Te(Jl,n=>{d(I)===w.VERIFIED?n(Kl):n(Xl,!1)})}Q(ar);var Ql=be(ar,2);{var ea=n=>{var u=Il(),_=ee(u);ue(_,"href",mn),Q(u),Je(()=>ue(_,"aria-label",d(ae).ariaLinkLabel)),ne(n,u)};Te(Ql,n=>{(L()!==!0||d(tr))&&n(ea)})}Q(lr);var Bn=be(lr,2);{var ta=n=>{var u=Nl(),_=be(ee(u),2);{var E=$=>{var y=Sl(),J=ee(y);Xe(J,()=>d(ae).expired),Q(y),Je(()=>ue(y,"title",d(rt))),ne($,y)},N=$=>{var y=Tl(),J=ee(y);Xe(J,()=>d(ae).error),Q(y),Je(()=>ue(y,"title",d(rt))),ne($,y)};Te(_,$=>{d(I)===w.EXPIRED?$(E):$(N,!1)})}Q(u),ne(n,u)};Te(Bn,n=>{(d(rt)||d(I)===w.EXPIRED)&&n(ta)})}var Hn=be(Bn,2);{var ra=n=>{var u=Ll(),_=ee(u),E=ee(_);Xe(E,()=>d(ae).footer),Q(_),Q(u),ne(n,u)};Te(Hn,n=>{d(ae).footer&&(b()!==!0||d(tr))&&n(ra)})}var na=be(Hn,2);{var ia=n=>{var u=Dl();sn(u,_=>z(vt,_),()=>d(vt)),ne(n,u)};Te(na,n=>{v()&&n(ia)})}return Q(mt),sn(mt,n=>z(Y,n),()=>d(Y)),Je(n=>{ue(mt,"data-state",d(I)),ue(mt,"data-floating",v()),qn=al(Ft,1,"altcha-checkbox svelte-ddsc3z",null,qn,n),ue(nt,"id",d(bn)),nt.required=r()!=="onsubmit"&&(!v()||r()!=="off")},[()=>({"altcha-hidden":d(I)===w.VERIFYING})]),Xi("invalid",nt,Rn),cl(nt,()=>d(et),n=>z(et,n)),ne(e,Vn),Zr({clarify:ht,configure:Dn,getConfiguration:Pn,getFloatingAnchor:zn,getPlugin:Zl,getState:On,hide:Fn,repositionFloating:gt,reset:_t,setFloatingAnchor:Mn,setState:je,show:ir,verify:De,get auto(){return r()},set auto(n=void 0){r(n),x()},get blockspam(){return l()},set blockspam(n=void 0){l(n),x()},get challengeurl(){return i()},set challengeurl(n=void 0){i(n),x()},get challengejson(){return a()},set challengejson(n=void 0){a(n),x()},get customfetch(){return o()},set customfetch(n=void 0){o(n),x()},get debug(){return f()},set debug(n=!1){f(n),x()},get delay(){return s()},set delay(n=0){s(n),x()},get expire(){return c()},set expire(n=void 0){c(n),x()},get floating(){return v()},set floating(n=void 0){v(n),x()},get floatinganchor(){return h()},set floatinganchor(n=void 0){h(n),x()},get floatingoffset(){return g()},set floatingoffset(n=void 0){g(n),x()},get floatingpersist(){return m()},set floatingpersist(n=!1){m(n),x()},get hidefooter(){return b()},set hidefooter(n=!1){b(n),x()},get hidelogo(){return L()},set hidelogo(n=!1){L(n),x()},get id(){return F()},set id(n=void 0){F(n),x()},get name(){return Z()},set name(n="altcha"){Z(n),x()},get maxnumber(){return V()},set maxnumber(n=1e6){V(n),x()},get mockerror(){return j()},set mockerror(n=!1){j(n),x()},get obfuscated(){return G()},set obfuscated(n=void 0){G(n),x()},get plugins(){return Ve()},set plugins(n=void 0){Ve(n),x()},get refetchonexpire(){return M()},set refetchonexpire(n=!0){M(n),x()},get spamfilter(){return q()},set spamfilter(n=!1){q(n),x()},get strings(){return $e()},set strings(n=void 0){$e(n),x()},get test(){return le()},set test(n=!1){le(n),x()},get verifyurl(){return Ne()},set verifyurl(n=void 0){Ne(n),x()},get workers(){return Qe()},set workers(n=Math.min(16,navigator.hardwareConcurrency||8)){Qe(n),x()},get workerurl(){return ct()},set workerurl(n=void 0){ct(n),x()}})}Qi(["change"]),customElements.define("altcha-widget",ml(vn,{blockspam:{type:"Boolean"},debug:{type:"Boolean"},delay:{type:"Number"},expire:{type:"Number"},floatingoffset:{type:"Number"},hidefooter:{type:"Boolean"},hidelogo:{type:"Boolean"},maxnumber:{type:"Number"},mockerror:{type:"Boolean"},refetchonexpire:{type:"Boolean"},test:{type:"Boolean"},workers:{type:"Number"},auto:{},challengeurl:{},challengejson:{},customfetch:{},floating:{},floatinganchor:{},floatingpersist:{},id:{},name:{},obfuscated:{},plugins:{},spamfilter:{},strings:{},verifyurl:{},workerurl:{}},["default"],["clarify","configure","getConfiguration","getFloatingAnchor","getPlugin","getState","hide","repositionFloating","reset","setFloatingAnchor","setState","show","verify"],!1)),globalThis.altchaCreateWorker=e=>new Worker(new URL(e||"./worker.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:C&&C.tagName.toUpperCase()==="SCRIPT"&&C.src||new URL("altcha.umd.cjs",document.baseURI).href)),globalThis.altchaPlugins=globalThis.altchaPlugins||[],k.Altcha=vn,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "altcha",
3
3
  "description": "GDPR compliant, self-hosted CAPTCHA alternative.",
4
- "version": "1.4.1",
4
+ "version": "1.4.2",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "Daniel Regeci",
@@ -84,6 +84,7 @@
84
84
  "@sveltejs/vite-plugin-svelte": "^5.0.3",
85
85
  "@tsconfig/svelte": "^5.0.4",
86
86
  "@types/node": "^20.16.3",
87
+ "@types/react": "^19.0.12",
87
88
  "husky": "^9.1.5",
88
89
  "prettier": "3.2.5",
89
90
  "prettier-plugin-svelte": "^3.2.6",