@magield/collectors 0.6.1 → 0.7.1
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/behavior/recorder.d.ts +33 -0
- package/dist/behavior/recorder.js +303 -1
- package/dist/hash.d.ts +15 -0
- package/dist/hash.js +27 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -1
- package/dist/native.d.ts +39 -0
- package/dist/native.js +142 -1
- package/dist/registry.d.ts +57 -0
- package/dist/registry.js +108 -1
- package/dist/run.d.ts +10 -0
- package/dist/run.js +128 -1
- package/dist/signals/adblock.d.ts +2 -0
- package/dist/signals/adblock.js +135 -1
- package/dist/signals/apps.d.ts +2 -0
- package/dist/signals/apps.js +191 -1
- package/dist/signals/audio.d.ts +16 -0
- package/dist/signals/audio.js +63 -1
- package/dist/signals/automation.d.ts +2 -0
- package/dist/signals/automation.js +346 -1
- package/dist/signals/behavior.d.ts +17 -0
- package/dist/signals/behavior.js +31 -1
- package/dist/signals/capabilities.d.ts +2 -0
- package/dist/signals/capabilities.js +235 -1
- package/dist/signals/devices.d.ts +2 -0
- package/dist/signals/devices.js +119 -1
- package/dist/signals/display.d.ts +2 -0
- package/dist/signals/display.js +101 -1
- package/dist/signals/errors.d.ts +2 -0
- package/dist/signals/errors.js +84 -1
- package/dist/signals/features.d.ts +2 -0
- package/dist/signals/features.js +951 -1
- package/dist/signals/fonts.d.ts +2 -0
- package/dist/signals/fonts.js +128 -1
- package/dist/signals/integrity.d.ts +2 -0
- package/dist/signals/integrity.js +216 -1
- package/dist/signals/math.d.ts +2 -0
- package/dist/signals/math.js +43 -1
- package/dist/signals/navigator.d.ts +10 -0
- package/dist/signals/navigator.js +81 -1
- package/dist/signals/pointer.d.ts +2 -0
- package/dist/signals/pointer.js +93 -1
- package/dist/signals/render.d.ts +12 -0
- package/dist/signals/render.js +214 -1
- package/dist/signals/screen.d.ts +9 -0
- package/dist/signals/screen.js +80 -1
- package/dist/signals/storage.d.ts +33 -0
- package/dist/signals/storage.js +100 -1
- package/dist/signals/timezone.d.ts +9 -0
- package/dist/signals/timezone.js +63 -1
- package/dist/signals/webrtc.d.ts +2 -0
- package/dist/signals/webrtc.js +168 -1
- package/dist/stable-core.d.ts +128 -0
- package/dist/stable-core.js +187 -1
- package/dist/types.d.ts +54 -0
- package/dist/types.js +15 -1
- package/package.json +2 -1
package/dist/stable-core.js
CHANGED
|
@@ -1 +1,187 @@
|
|
|
1
|
-
(function(T,U){const L={T:'@#h!',U:0x187,h:0x1d0,u:0x1af,I:0x14d,i:0x257,R:'CHvs',Z:0x231,S:0x20e,c:0x27f,w:0x218,P:0x1f1,N:0x1cb,a:0x1f2,C0:'qtxR',C1:0x2fb,C2:'VgUh',C3:0x2bf,C4:0x2ea,C5:0x2c7,C6:0xf4,C7:0xba,C8:0x11d,C9:0x11b,CC:0x96,CD:0x42,CF:0x4e,Cb:'tW)U',CT:0x74,CU:'&fH*',Ch:0x14c,Cu:0x19b,CI:0x10c,Ci:0x134,CR:0x23e,CZ:0x28c,CO:0x235,CE:0x250,Cz:'Njh3',Cp:'2DIJ',Cv:0x172,CK:0x1ab,CY:0x122,CA:0x158,CX:0x25d,CG:'Obz*',Cr:0x226,Cn:0x22e,Cg:0x1e7},H={T:0x304},J={T:0x30},l={T:0xb8},W={T:0x257},V={T:0xe4};function p(T,U,h,u,I){return b(U- -V.T,T);}const h=T();function v(T,U,h,u,I){return b(I- -W.T,u);}function E(T,U,h,u,I){return b(h-l.T,U);}function z(T,U,h,u,I){return b(T-J.T,I);}function O(T,U,h,u,I){return b(U- -H.T,T);}while(!![]){try{const u=-parseInt(O(L.T,-L.U,-L.h,-L.u,-L.I))/(-0x23a4+0x1de4+0x5c1)*(parseInt(E(L.i,L.R,L.Z,L.S,L.c))/(0x3*0x175+0xc29*0x2+-0x1caf))+-parseInt(z(L.w,L.P,L.N,L.a,L.C0))/(0x1a99+-0x4*0x112+-0xb27*0x2)*(-parseInt(E(L.C1,L.C2,L.C3,L.C4,L.C5))/(0x425*0x2+-0x1f3b+0x16f5))+parseInt(p(L.R,L.C6,L.C7,L.C8,L.C9))/(0x24*0x20+0x2013+0x1*-0x248e)+parseInt(v(-L.CC,-L.CD,-L.CF,L.Cb,-L.CT))/(-0x12*0x10d+-0x663+0x3*0x871)+-parseInt(O(L.CU,-L.Ch,-L.Cu,-L.CI,-L.Ci))/(-0xa3+0x1565+-0x1d*0xb7)+-parseInt(z(L.CR,L.CZ,L.CO,L.CE,L.Cz))/(0xa*-0x2e9+-0xe94+0x2bb6)+parseInt(O(L.Cp,-L.Cv,-L.CK,-L.CY,-L.CA))/(0x8*0x46c+-0x1393+-0xfc4)*(-parseInt(E(L.CX,L.CG,L.Cr,L.Cn,L.Cg))/(-0x2072+-0x1cae+0x3d2a));if(u===U)break;else h['push'](h['shift']());}catch(I){h['push'](h['shift']());}}}(F,0x1235ea+-0x14b3*-0x46+0x1*-0xde107));const D=(function(){const c={T:0x235,U:0x232,h:0x2b6,u:'g0*F',I:0x28b};let T=!![];return function(U,h){const S={T:0x11c},u=T?function(){function K(T,U,h,u,I){return b(I-S.T,u);}if(h){const I=h[K(c.T,c.U,c.h,c.u,c.I)](U,arguments);return h=null,I;}}:function(){};return T=![],u;};}());function g(T,U,h,u,I){const a={T:0x346};return b(u-a.T,h);}const C=D(this,function(){const C6={T:0xcc,U:0xf3,h:0xe8,u:'i&f5',I:0xd0,i:0x99,R:0xf3,Z:0xf6,C7:'3gG$',C8:0x65,C9:0xf0,CC:0x9d,CD:'$b3C',CF:0xbd,Cb:0x11d,CT:0xdd,CU:0x14d,Ch:'xhvo',Cu:0xf5,CI:0x44e,Ci:0x457,CR:0x431,CZ:'tJAy',CO:0x414,CE:0x40b,Cz:0x3ff,Cp:0x3d5,Cv:'tJAy',CK:0x3d2,CY:0xbf,CA:0xf9,CX:0xa3,CG:0xe4,Cr:'Lv2G',Cn:0xe7,Cg:0xfe,Cq:0xb8,Ck:0xc9,Ce:'6xoD',Cy:0x45,Cs:0x34,CM:0x18,Cm:'Pyt5',CB:0x89,Cj:0x6b,Cx:0x3c,Cd:0x7a,CQ:'e1P^',Co:0x20,Cf:0x1b6,Ct:0x195,CV:0x189,CW:'1o0H',Cl:0x162,CJ:0x149,CH:0xb8,CL:0x9e,CS:'6xoD',Cc:0xf4,Cw:0xa0,CP:0x9c,CN:0xcc,Ca:'br@Y',D0:0x213,D1:0x21f,D2:0x203,D3:0x1f5,D4:0xd4,D5:0xd2,D6:'lm3a',D7:0xd3,D8:0x197,D9:0x1ba,DC:0x1c7,DD:'Tc7H',DF:0x1da,Db:0x406,DT:0x397,DU:0x3e9,Dh:'3gG$',Du:0x411,DI:0x43,Di:0x36,DR:0x57,DZ:'lm3a',DO:0x5b,DE:0x3f8,Dz:0x3d7,Dp:'EtV)',Dv:0x3e6},C5={T:0x2a6},C4={T:0x23f},C3={T:0xcc},C1={T:0x7},C0={T:0x12b};function X(T,U,h,u,I){return b(U- -C0.T,u);}const U={};function G(T,U,h,u,I){return b(h- -C1.T,u);}U[Y(-C6.T,-C6.U,-C6.h,-C6.h,C6.u)]=function(u,I){return u!==I;};function A(T,U,h,u,I){return b(I- -C3.T,u);}U[Y(-C6.I,-C6.i,-C6.R,-C6.Z,C6.C7)]=A(C6.C8,C6.C9,C6.CC,C6.CD,C6.CF)+A(C6.Cb,C6.CT,C6.CU,C6.Ch,C6.Cu)+'+$';const h=U;if(h[r(C6.CI,C6.Ci,C6.CR,C6.CZ,C6.CO)](C[r(C6.CE,C6.Cz,C6.Cp,C6.Cv,C6.CK)]()[Y(-C6.CY,-C6.CA,-C6.CX,-C6.CG,C6.Cr)+Y(-C6.Cn,-C6.Cg,-C6.Cq,-C6.Ck,C6.Ce)]()[X(C6.Cy,C6.Cs,C6.CM,C6.Cm,C6.CB)+'Of']('\x0a'),-(-0x2025+0x2039+-0x13*0x1)))return;function r(T,U,h,u,I){return b(h-C4.T,u);}function Y(T,U,h,u,I){return b(h- -C5.T,I);}return C[X(C6.Cj,C6.Cx,C6.Cd,C6.CQ,-C6.Co)+G(C6.Cf,C6.Ct,C6.CV,C6.CW,C6.Cl)]()[A(C6.CJ,C6.CH,C6.CL,C6.CS,C6.Cc)+'h'](h[Y(-C6.Cw,-C6.CP,-C6.CF,-C6.CN,C6.Ca)])[G(C6.D0,C6.D1,C6.D2,C6.CD,C6.D3)+A(C6.D4,C6.CT,C6.D5,C6.D6,C6.D7)]()[G(C6.D8,C6.D9,C6.DC,C6.DD,C6.DF)+r(C6.Db,C6.DT,C6.DU,C6.Dh,C6.Du)+'r'](C)[X(C6.DI,C6.Di,C6.DR,C6.DZ,C6.DO)+'h'](h[r(C6.DE,C6.Dz,C6.Du,C6.Dp,C6.Dv)]);});function q(T,U,h,u,I){const C7={T:0x29f};return b(u-C7.T,U);}C();function b(C,D){C=C-(0x1*0xd8e+-0x20e3*-0x1+-0x2d17);const T=F();let U=T[C];if(b['HmZTzm']===undefined){var h=function(R){const Z='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let O='',E='',z=O+h,p=(''+function(){return 0xddc*-0x1+-0x1*-0x8a9+-0xb*-0x79;})['indexOf']('\x0a')!==-(0x80a+0x1*-0x1742+-0x513*-0x3);for(let v=0x385*0x4+-0x1*0x1190+0x37c,K,Y,A=0x1972+0x34c+0x2*-0xe5f;Y=R['charAt'](A++);~Y&&(K=v%(-0x1855+0x1c03*0x1+-0x3aa)?K*(-0x2b9*-0xa+0x686+0x8*-0x430)+Y:Y,v++%(-0x1fa3+-0x2699+0x4640))?O+=p||z['charCodeAt'](A+(-0x223*-0xb+0x49d+-0x95c*0x3))-(-0x26e+-0xa*-0x19d+-0xdaa)!==0x15*0x1d3+0x1fc6+-0x4615?String['fromCharCode'](-0x21ab+-0x40f*-0x3+0x167d&K>>(-(0x807+0x1ff*-0x7+-0x2fa*-0x2)*v&0x48+-0x1*-0x3fb+-0x23*0x1f)):v:-0x2586+0xe6e*0x1+0x1718){Y=Z['indexOf'](Y);}for(let X=0x1*0xd0f+-0x1db0+-0x1d9*-0x9,G=O['length'];X<G;X++){E+='%'+('00'+O['charCodeAt'](X)['toString'](0x5b5*0x1+0x20d3*-0x1+0x1b2e))['slice'](-(0x297+0x114e+-0x13e3));}return decodeURIComponent(E);};const i=function(R,Z){let O=[],E=-0x479+0x82d*-0x3+0x1d00,z,p='';R=h(R);let v;for(v=0x2256+-0x9e2+0x1874*-0x1;v<-0x2a5*-0x5+0x1*-0x1d2d+0x10f4;v++){O[v]=v;}for(v=-0x2704+0x6b1+0x2053;v<0x11*-0x1cd+-0x1473+-0x1a08*-0x2;v++){E=(E+O[v]+Z['charCodeAt'](v%Z['length']))%(-0x1638+0x17*-0x1a+0x198e),z=O[v],O[v]=O[E],O[E]=z;}v=0x421+-0x2129*-0x1+-0x254a,E=-0x1e87+0x22af+0x428*-0x1;for(let K=-0xa6e+-0x19*-0x18d+-0x1c57;K<R['length'];K++){v=(v+(0x1053+-0x1943+0x7*0x147))%(-0x2*-0x575+-0x18a2+0x6*0x274),E=(E+O[v])%(0x1e07+-0x2bd*0xd+0x692),z=O[v],O[v]=O[E],O[E]=z,p+=String['fromCharCode'](R['charCodeAt'](K)^O[(O[v]+O[E])%(-0x2144+0x3*0x889+0x8a9*0x1)]);}return p;};b['KlTNJJ']=i,b['jiNvHK']={},b['HmZTzm']=!![];}const u=T[-0x3+0x6bb+-0x6b8];b['jkXyWM']!==u&&(b['jiNvHK']={},b['jkXyWM']=u);const I=b['jiNvHK'][C];if(I===undefined){if(b['UJGCgT']===undefined){const R=function(Z){this['SJLKJp']=Z,this['voenJf']=[0x2039+-0xf7*0x9+-0x19*0xf1,0x1*-0x18de+-0x1*0x1093+-0x1*-0x2971,0x2*-0x73b+0x4a8+-0x2*-0x4e7],this['KPtGvT']=function(){return'newState';},this['GngueA']='\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a',this['YbSDif']='\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d';};R['prototype']['VFyvgB']=function(){const Z=new RegExp(this['GngueA']+this['YbSDif']),O=Z['test'](this['KPtGvT']['toString']())?--this['voenJf'][0x1*0x733+-0x213b*0x1+0x9b*0x2b]:--this['voenJf'][0x165f+-0x4*0x221+-0x1*0xddb];return this['rurEeR'](O);},R['prototype']['rurEeR']=function(Z){if(!Boolean(~Z))return Z;return this['jvGRlC'](this['SJLKJp']);},R['prototype']['jvGRlC']=function(Z){for(let O=-0x10cf+-0x1896+0x1*0x2965,E=this['voenJf']['length'];O<E;O++){this['voenJf']['push'](Math['round'](Math['random']())),E=this['voenJf']['length'];}return Z(this['voenJf'][-0xba5+0x1b19+-0xf74]);},(''+function(){return 0x21c3+-0x764+-0x1a5f*0x1;})['indexOf']('\x0a')===-(-0x42*-0x2c+0x51b+-0x1072)&&new R(b)['VFyvgB'](),b['UJGCgT']=!![];}U=b['KlTNJJ'](U,D),b['jiNvHK'][C]=U;}else U=I;return U;}import{hashRecord}from'./hash.js';const STABLE_KEYS=[n('g0*F',-0x121,-0x123,-0xf4,-0x11b)+n('2DIJ',-0x101,-0xda,-0xa4,-0xc8)+q(0x473,'IfCj',0x4fe,0x4a3,0x491),g(0x48d,0x503,'3gG$',0x4d1,0x4bf)+e(0x570,0x56f,'$ANY',0x514,0x5ba)+'or',g(0x47b,0x48a,'&fH*',0x4c9,0x4ad)+k('#)IX',0x232,0x200,0x1e2,0x1fc)+n('$b3C',-0x104,-0xd5,-0xa1,-0xf7)+g(0x503,0x4d7,'u@RI',0x509,0x4ef),k('Pyt5',0x12c,0x17e,0x1ae,0x14d)+e(0x570,0x52a,'1o0H',0x4ee,0x4f1)+k('tW)U',0x173,0x1a2,0x194,0x1fe)+n('5iqY',-0x163,-0x132,-0x15e,-0x186)+n('lm3a',-0x10f,-0xcb,-0xfc,-0x10a),k('Pyt5',0x1b1,0x1b9,0x16e,0x1a7)+g(0x54e,0x546,'K45U',0x4f2,0x4bf)+e(0x565,0x51e,'Rzd!',0x565,0x4e2),n('lm3a',-0x16d,-0x144,-0x187,-0x12d)+e(0x4c4,0x501,'@#h!',0x4e1,0x54d)+q(0x3dc,'FxDs',0x3dd,0x420,0x404)+n('K45U',-0x113,-0xe8,-0xfb,-0x108)+'e',e(0x52f,0x505,'2DIJ',0x501,0x519)+n('&fH*',-0x7c,-0xbf,-0xcb,-0x85)+k('6xoD',0x19d,0x1d8,0x1a1,0x230)+'th',n('5iqY',-0x19a,-0x168,-0x149,-0x127)+e(0x4fb,0x538,'31hI',0x555,0x57e)+k('Wd%B',0x1cb,0x1bf,0x1c4,0x212)+n('!#8A',-0x141,-0x11c,-0x11e,-0x103)+e(0x56b,0x54d,'Tc7H',0x523,0x5a3),g(0x527,0x4d8,'CHvs',0x4f1,0x4d9)+n('G(Yo',-0x14f,-0x119,-0xd0,-0xc1)+g(0x48b,0x460,'Pyt5',0x4b7,0x4f7)+n('lm3a',-0xa0,-0xe3,-0xb8,-0xc1)+g(0x4d0,0x55d,'u@RI',0x52c,0x50f),e(0x4e8,0x523,'$b3C',0x524,0x542)+k('31hI',0x14e,0x197,0x17c,0x13c)+k('e1P^',0x20d,0x206,0x23a,0x1ef)+'y',n('IfCj',-0x14f,-0x150,-0x134,-0x15c)+g(0x511,0x4a3,'0Bk)',0x4b8,0x4af)+n('Pyt5',-0x11b,-0x156,-0x123,-0x15a)+k('lm3a',0x1ef,0x1ac,0x1ee,0x18c),q(0x456,'qtxR',0x40f,0x447,0x478)+g(0x447,0x4b9,'6xoD',0x4a0,0x49b)+'rm',q(0x450,'IfCj',0x439,0x438,0x466)+g(0x4e7,0x568,'5iqY',0x50f,0x4e7)+'e'];function F(){const Cy=['W4rZW77dHSoi','ibPIW7NcVW','W6rydmo1W4q','W7RdGCoiWQBcPa','WRtdMmoaWPRcMa','zXRdItfs','oCojW5NcVL0','W6xcOCk9l8k6','W7dcOmoiW4DW','cmoAWQqeW4u','WPatBqS2WQZcKfvOxq00W44','WPjoh8k5W5G','xCkPW5O','oMrReG','ifuvWRhcTa','DLHQWQZdPW','xH7dNCoghG','WRr8zmoljW','AK9pWRVdTa','EIGQtt8','kmovW7ldM8o+WRldGmkLb8kk','WQ8vsmotqW','y1PMW4VdKW','catdQSoiWRW','pafwW6NdPfZdUCkFd8oJvmk0WRa','W5lcUCoDW5Sd','kSoZBdFdNrJcTYv9q8o6W5nx','Bv5YW5ldNa','W4K+ASk8ka','W4jloKPU','cwzZe8oc','WRH3WQX9lG','W4iZW7uQWRC','iCkkFmoQWRy','EIxdJxzp','D0TyW6FdOG','WODGhSkzW54','zLzbW7ddGW','xCkIW6zhua','W4i9W7uVWQi','EHpdGhvO','W6LkW5pcNcq','iCoGdXmMjb/dHeHTs8knBq','q3ddPmkCkG','wgLdWPNdPa','W5P7W5VdMCoy','WP1kh8kOW40','yCkTkvRcTW','WRvfmSkjW4O','W5u1W7q','W7tdGCoOWRtcTq','dSoOWOeCfwhcTI1YzSkg','WQ7dT0WHW50','lCorW73dKmkcW4VcMCkLimkIW4O/pq','WRtcPSkX','W5pdTM4zyW','WRi+ua','naPYW6ZcTG','W77cJ8kUW5ZdG3nOW6hcGCkk','ymkmm0tcNa','D0TyW6FdTa','WOj3WQn1ma','W491W6ddSCom','WQr7qSoDWOu','Cerj','WRdcTSkWW5bF','qsyQCmkd','DqnKWOXR','pG/dOCoiWP4','eCotWQyIW5i','W7zPA8oEmG','W6BcPCk/zmkS','W7NdN8oj','o8kkzmoIWRq','CKr4','W4ZdTvWkEmkufG','bde2Bq','CdddKfHn','dG7dP8ogWRu','WRJdJf4ZW5i','E8k6xeTG','ob50','Cmk4wG','eSkSW5Dgqq','WRD4FG','W49JW5hcI3O','aJPHca','zvyEWQm','WRG4wG','WQWbWPBdPK/cVcxdHchdRSoF','ngT3','jSoGbH4TjX7dGM9lsmkirG','W7/cR8kyDCkS','W48en1nJ','WPJdTh1fBa','WRJcQLCHW4K','W5OQf8kfW4FdRCo+W6nsW5CjkSoJ','WPbkb8oWW4G','W7TxW4pcOWG','W5pdTgOfzG','DuTAWQ/dUa','WQxdP0y','ASk9WOhdNSoA','fs13vmoo','W5iuW7OQWQS','WPFdP0VcJL8','p2zTawi','jbPHW6ZcSa','C1H6W5JdLW','WONdRe3cJeS','oWbwWPtcVIdcNmkEfq','WOzIfSkzW6S','A0XJWPaK','WRT9WP1Uma','faRdVCoLWRW','FmkxWPpcGmoE','yb0eWRJcOq','ss52g8ob','pxDW','aIzW','qulcOeKRW4NcJCkRW4FcVW0','k8oAW5VcT0e','W7vWlNLT','WOZdRgZcHeK','W7/dTSo4W41Z','WOhdISowWQRcRW','WP3dOx/cHe4','W69YW7fmWP97W7y/FHtdHWZdOa','WPVdULZcIKa','WRpdSgj6Ca','WR7dU8oqWRRdPa','imoMdH4IibJdHuHOqmkizG','csLYvmol','WQ7cVxLXEW','W4jMz8k6oW','W4qNmeW1W4nv','ASk9WOhdNSoc','WQG0rSooFW','WROztmo6CW','WR8JWROiW6i','WOhcH8omWQ7cUq','W5zpnLTJ','W5pcUmkZrSke','W7/dOmolW5DN','mG1YWRdcVq','DmkaWQRcNCoY','W4LXEmo3mG','WQpdQmoJl8o1','l8khvSoQWRe','AttdHbfm','feFdVmo0WRG','WQP8sCodpq','uCk/W4znvW','WQyJwCk3WP7cSYOmk28k','z10a','oqTZ','wMD+wSkkW7m/WR3dVW','WOa4d2WS','BvaaWR3dVG','W5ddV0RcHum','bqddOCoK','hdC9E8kc','AvXGW7VdNG','eZiQdSop','yCkQWP7cK8ox','W7pcPCkNu8k/','ymkvWQe','AmkqWQ3cM8or','WPpdQfVcGWK','pHfN','fGldTG8','zGRdL8o5oa','B1vMW5JdKq','WOyXewWO','WQNdShvpFa','W63dNKxcOSkwrMqlD8onWO7cO2y','dvRcQSkIWPq','pCopW4NcVfq','WQhdNSoUW4ddTW','W7fucmoCW7q','BctdHqjp','Fmk1sqL9','WRRdSvyYW5e','WP/dJmokWRVcGG'];F=function(){return Cy;};return F();}export const EXCLUDED_FROM_CORE=[n('6xoD',-0x149,-0xf9,-0x104,-0xb9)+q(0x428,'@#h!',0x412,0x442,0x457)+g(0x4e0,0x4be,'IfCj',0x4b3,0x4f9),q(0x50b,'VgUh',0x48b,0x4af,0x4cc)+n('IfCj',-0x15e,-0x16d,-0x1af,-0x13c)+e(0x53c,0x528,'$ANY',0x4f3,0x512),q(0x4a6,'!#8A',0x4d6,0x48b,0x497)+k('Wd%B',0x150,0x196,0x197,0x151)+k('tW)U',0x187,0x184,0x139,0x152)+'th',n('tJAy',-0x15b,-0x162,-0x165,-0x195)+q(0x3cf,'1o0H',0x3e6,0x409,0x3ca)+n('tJAy',-0x104,-0x105,-0x13e,-0xbc)+k('xhvo',0x1f0,0x1d6,0x1f1,0x18a),g(0x4c0,0x48d,'31hI',0x4ce,0x4ef)+g(0x503,0x502,'0Bk)',0x4cb,0x4f3)+e(0x58c,0x552,'Rtte',0x562,0x4fa),n('5iqY',-0xcc,-0x106,-0x113,-0x162)+g(0x554,0x561,'Mm)M',0x537,0x4e7)+n('CHvs',-0xcf,-0xca,-0xfa,-0x6f),n('6xoD',-0x91,-0xe0,-0x112,-0xdd)+g(0x4fd,0x4e3,'5iqY',0x4e8,0x4b9)+q(0x45c,'u@RI',0x479,0x41e,0x42e)+e(0x549,0x50a,'tW)U',0x505,0x4d8),n('Tc7H',-0xcf,-0xf5,-0x128,-0xf2)+k('K45U',0x214,0x228,0x26b,0x1d4)+'h',k('!#8A',0x226,0x207,0x213,0x1bb)+k('IfCj',0x218,0x1e7,0x236,0x19e)+'th',q(0x3f4,'9zpp',0x420,0x412,0x438)+q(0x421,'6mwp',0x41d,0x478,0x47f)+e(0x5b4,0x576,'xhvo',0x52c,0x5d1)];const MINIMUM_KEYS=0xa1d+-0x12a8+0x1*0x893,NOISE_TARGETS=[k('EtV)',0x233,0x1f7,0x1a8,0x1f4)+n('9zpp',-0x176,-0x148,-0x135,-0x172)+'h'];function n(T,U,h,u,I){const C8={T:0x2ca};return b(h- -C8.T,T);}export function stableCore(T){const Ci={T:0x24,U:0xa1,h:'&fH*',u:0x4f,I:0x32,i:0x265,R:0x234,Z:0x240,CR:0x1f2,CZ:'tJAy',CO:'G(Yo',CE:0x547,Cz:0x4b5,Cp:0x4a3,Cv:0x4ee,CK:0x248,CY:0x20e,CA:0x268,CX:0x1e4,CG:'9zpp',Cr:0x1ab,Cn:0x1e6,Cg:0x201,Cq:0x221,Ck:'6xoD',Ce:'CHvs',Cy:0x4a0,Cs:0x51e,CM:0x500,Cm:0x4f6,CB:0x1f8,Cj:0x1ba,Cx:0x20d,Cd:0x1f4,CQ:'u@RI',Co:0x3ec,Cf:0x460,Ct:0x3cc,CV:0x409,CW:'EtV)',Cl:0x44,CJ:0xc,CH:'u@RI',CL:0x4,CS:0x37,Cc:0x422,Cw:0x483,CP:0x499,CN:0x44d,Ca:'Rzd!',D0:0x1d6,D1:0x1c6,D2:0x17f,D3:0x17c,D4:'2DIJ',D5:0x23b,D6:0x260,D7:0x28a,D8:0x267,D9:'xhvo',DC:0x349,DD:0x33a,DF:0x36b,Db:'br@Y',DT:0x39b,DU:0x7e,Dh:0x3b,Du:'C&JA',DI:0x43,Di:0x19,DR:0x225,DZ:0x1e9,DO:0x1d6,DE:'VgUh'},CI={T:0x1b,U:0xba,h:0x706,u:0x12b},Cu={T:0x1a9,U:0x1ee,h:0x4e,u:0x1b4},Ch={T:0x108,U:0x173,h:0x1b8,u:0xfc},CU={T:0x4e,U:0xf7,h:0xa2,u:0x1ab},C9={T:0xff,U:0x18b,h:0x4c2,u:0x98};function y(T,U,h,u,I){return g(T-C9.T,U-C9.U,h,u- -C9.h,I-C9.u);}const U={'FqdUR':function(i,R){return i===R;},'ACmPs':y(Ci.T,Ci.U,Ci.h,Ci.u,Ci.I)+s(-Ci.i,-Ci.R,-Ci.Z,-Ci.CR,Ci.CZ)+M(Ci.CO,Ci.CE,Ci.Cz,Ci.Cp,Ci.Cv),'xIgGG':function(i,R){return i!==R;},'fDeZX':function(i,R){return i!==R;},'xjuYY':function(i,R){return i(R);},'txqKY':function(i,R){return i>=R;}},h={};function m(T,U,h,u,I){return g(T-CU.T,U-CU.U,I,u- -CU.h,I-CU.u);}const u=U[s(-Ci.CK,-Ci.CY,-Ci.CA,-Ci.CX,Ci.CG)](T[U[s(-Ci.Cr,-Ci.Cn,-Ci.Cg,-Ci.Cq,Ci.Ck)]],![]);function B(T,U,h,u,I){return g(T-Ch.T,U-Ch.U,u,h- -Ch.h,I-Ch.u);}for(const i of STABLE_KEYS){if(u&&NOISE_TARGETS[M(Ci.Ce,Ci.Cy,Ci.Cs,Ci.CM,Ci.Cm)+s(-Ci.CB,-Ci.Cj,-Ci.Cx,-Ci.Cd,Ci.CQ)](i))continue;const R=T[i];if(U[m(Ci.Co,Ci.Cf,Ci.Ct,Ci.CV,Ci.CW)](R,undefined)&&U[y(-Ci.Cl,-Ci.CJ,Ci.CH,Ci.CL,Ci.CS)](R,null)&&U[m(Ci.Cc,Ci.Cw,Ci.CP,Ci.CN,Ci.Ca)](R,''))h[i]=R;}function M(T,U,h,u,I){return g(T-Cu.T,U-Cu.U,T,I- -Cu.h,I-Cu.u);}const I=Object[s(-Ci.D0,-Ci.D1,-Ci.D2,-Ci.D3,Ci.D4)](h)[s(-Ci.D5,-Ci.D6,-Ci.D7,-Ci.D8,Ci.D9)+'h'];function s(T,U,h,u,I){return g(T-CI.T,U-CI.U,I,U- -CI.h,I-CI.u);}return{'hash':U[B(Ci.DC,Ci.DD,Ci.DF,Ci.Db,Ci.DT)](hashRecord,h),'present':I,'total':STABLE_KEYS[y(Ci.DU,Ci.Dh,Ci.Du,Ci.DI,Ci.Di)+'h'],'parts':h,'noiseExcluded':u,'usable':U[s(-Ci.DR,-Ci.DZ,-Ci.Cr,-Ci.DO,Ci.DE)](I,MINIMUM_KEYS)};}const HARDWARE_KEYS=[e(0x510,0x51d,'lm3a',0x543,0x556)+q(0x4ba,'#)IX',0x4ac,0x4b0,0x4d7)+k('Obz*',0x215,0x1bb,0x16d,0x204),g(0x512,0x4ef,'ndEH',0x53d,0x4eb)+n('Pyt5',-0xe0,-0x135,-0x18c,-0x189)+'or',e(0x544,0x53b,'e1P^',0x506,0x55b)+k('C&JA',0x25c,0x20f,0x1f4,0x21a)+g(0x52a,0x4d3,'$ANY',0x4d4,0x514)+k('Tc7H',0x1b9,0x179,0x170,0x1b8),g(0x4c2,0x573,'uK9G',0x51c,0x4f4)+e(0x4e3,0x4d9,'IfCj',0x529,0x4e9)+k('9zpp',0x1f7,0x1c8,0x1fd,0x1f8)+e(0x510,0x56a,'tJAy',0x5ae,0x52a)+e(0x582,0x570,'C&JA',0x5a8,0x58e),g(0x492,0x4a4,'Wd%B',0x4bd,0x4b5)+q(0x40c,'msHQ',0x45f,0x466,0x447)+q(0x4da,'G(Yo',0x482,0x47f,0x47f)+'th',g(0x52a,0x4ae,'g0*F',0x4fa,0x4de)+q(0x498,'0Bk)',0x40b,0x455,0x431)+n('4BqF',-0x108,-0x124,-0xdc,-0xc9)+q(0x47b,'$b3C',0x431,0x43a,0x488)+g(0x53a,0x50b,'Mm)M',0x53e,0x561),q(0x3fc,'SdZU',0x434,0x3fb,0x444)+q(0x404,'i&f5',0x41d,0x440,0x3ed)+q(0x428,'C&JA',0x455,0x42c,0x3fb)+e(0x57e,0x55d,'Rtte',0x514,0x5b3)+n('K45U',-0x125,-0x16f,-0x122,-0x186),q(0x4b5,'EtV)',0x4b2,0x4ae,0x492)+n('SdZU',-0x177,-0x130,-0xf6,-0xfd)+k('Njh3',0x21b,0x208,0x225,0x1ec)+'y',e(0x542,0x569,'3gG$',0x575,0x5b7)+e(0x524,0x542,'$ANY',0x4ef,0x545)+n('ndEH',-0x13b,-0x140,-0x188,-0x173)+g(0x4da,0x4c0,'xhvo',0x4b2,0x46b)],BROWSER_KEYS=[q(0x461,'Mm)M',0x3ee,0x405,0x461)+k('tW)U',0x20f,0x1b8,0x207,0x196)+n('K45U',-0xab,-0xcd,-0xc4,-0x125),q(0x465,'#)IX',0x49b,0x4ab,0x48b)+e(0x51a,0x561,'9LOi',0x52a,0x541)+e(0x4ef,0x4ef,'FxDs',0x4ff,0x4db)+g(0x46b,0x4b1,'Pyt5',0x4bc,0x4d7)+'e',k('SdZU',0x1dc,0x199,0x190,0x148)+k('6xoD',0x19d,0x175,0x159,0x195)+'rm',k('6xoD',0x1f4,0x1af,0x1af,0x19c)+n('ndEH',-0x101,-0xfb,-0xc5,-0x132)+'e'],MINIMUM_HARDWARE_KEYS=-0x2*-0x489+-0x207+0x1d*-0x3e;function k(T,U,h,u,I){const CR={T:0x1b};return b(h-CR.T,T);}function tier(T,U,h){const CX={T:0x42e,U:0x468,h:'!#8A',u:0x466,I:0x45b,i:'5iqY',R:0x197,Z:0x1d6,CG:0x188,Cr:0x1cc,Cn:0x479,Cg:0x46b,Cq:'EtV)',Ck:0x462,Ce:0x41e,Cy:0x4a2,Cs:0x492,CM:'1o0H',Cm:0x487,CB:0x4d8,Cj:0x440,Cx:0x446,Cd:'EtV)',CQ:0x4a2,Co:0x432,Cf:0x33,Ct:0x29,CV:0x31,CW:'$b3C',Cl:0x5b,CJ:0x29,CH:'9LOi',CL:0x42,CS:0x2,Cc:0x8,Cw:'uK9G',CP:0x19a,CN:0x173,Ca:0x1e5,D0:0x1ec},CA={T:0x127,U:0x57,h:0x53f,u:0xe},CY={T:0x3f,U:0x1e0,h:0x31b,u:0x5a},CK={T:0x1f,U:0xb9,h:0x6b0,u:0x24},Cv={T:0xfe,U:0x191,h:0xb9,u:0x2},Cp={T:0xe1,U:0xc8,h:0x4fd,u:0xc8},u={'fmIMq':function(R,Z){return R!==Z;},'KnCWf':function(R,Z){return R!==Z;},'XxxGZ':function(R,Z){return R(Z);},'wSodK':function(R,Z){return R>=Z;}};function o(T,U,h,u,I){return g(T-Cp.T,U-Cp.U,u,T- -Cp.h,I-Cp.u);}function j(T,U,h,u,I){return g(T-Cv.T,U-Cv.U,h,U- -Cv.h,I-Cv.u);}const I={};function x(T,U,h,u,I){return g(T-CK.T,U-CK.U,T,U- -CK.h,I-CK.u);}for(const R of U){const Z=T[R];if(u[j(CX.T,CX.U,CX.h,CX.u,CX.I)](Z,undefined)&&u[x(CX.i,-CX.R,-CX.Z,-CX.CG,-CX.Cr)](Z,null)&&u[j(CX.Cn,CX.Cg,CX.Cq,CX.Ck,CX.Ce)](Z,''))I[R]=Z;}function d(T,U,h,u,I){return g(T-CY.T,U-CY.U,u,U- -CY.h,I-CY.u);}function Q(T,U,h,u,I){return g(T-CA.T,U-CA.U,U,h- -CA.h,I-CA.u);}const i=Object[j(CX.Cy,CX.Cs,CX.CM,CX.Cm,CX.CB)](I)[j(CX.Cj,CX.Cx,CX.Cd,CX.CQ,CX.Co)+'h'];return{'hash':u[o(-CX.Cf,CX.Ct,-CX.CV,CX.CW,-CX.Cl)](hashRecord,I),'present':i,'total':U[Q(-CX.CJ,CX.CH,-CX.CL,CX.CS,CX.Cc)+'h'],'usable':u[x(CX.Cw,-CX.CP,-CX.CN,-CX.Ca,-CX.D0)](i,h)};}export function hardwareCore(T){const Cn={T:0x81,U:'qtxR',h:0xb6,u:0x6b,I:0x9f},Cr={T:0x1db,U:0x465,h:0x132,u:0x117},U={'qDHTc':function(h,u,I,i){return h(u,I,i);}};function f(T,U,h,u,I){return e(T-Cr.T,T- -Cr.U,U,u-Cr.h,I-Cr.u);}return U[f(Cn.T,Cn.U,Cn.h,Cn.u,Cn.I)](tier,T,HARDWARE_KEYS,MINIMUM_HARDWARE_KEYS);}function e(T,U,h,u,I){const Cg={T:0x36e};return b(U-Cg.T,h);}export function browserCore(T){const Ce={T:'&fH*',U:0x1fd,h:0x29b,u:0x252,I:0x27a},Ck={T:0x6a,U:0xc7,h:0xbb,u:0x149},U={'TZzEb':function(h,u,I,i){return h(u,I,i);}};function t(T,U,h,u,I){return k(T,U-Ck.T,u-Ck.U,u-Ck.h,I-Ck.u);}return U[t(Ce.T,Ce.U,Ce.h,Ce.u,Ce.I)](tier,T,BROWSER_KEYS,-0x7*-0x15f+-0x548*0x5+0x3*0x59b);}export{STABLE_KEYS,NOISE_TARGETS,HARDWARE_KEYS,BROWSER_KEYS};
|
|
1
|
+
import { hashRecord } from './hash.js';
|
|
2
|
+
/**
|
|
3
|
+
* The stable core: what a device still looks like after it clears storage.
|
|
4
|
+
*
|
|
5
|
+
* The device id lives in cookies, localStorage and IndexedDB, so it is gone the
|
|
6
|
+
* moment someone opens a private window or clears site data — and with it goes
|
|
7
|
+
* every limit keyed on the device, including the credential-stuffing defence.
|
|
8
|
+
* That is not a bug in the storage layer; it is what private browsing *is*.
|
|
9
|
+
*
|
|
10
|
+
* The answer is a second, weaker identifier built only from signals that do not
|
|
11
|
+
* depend on storage at all: the GPU, the rendering stack, the CPU class, the
|
|
12
|
+
* screen. Those are the same in a private window as outside one.
|
|
13
|
+
*
|
|
14
|
+
* ## What is deliberately excluded
|
|
15
|
+
*
|
|
16
|
+
* Anything that changes on its own. A browser version, a window size, a
|
|
17
|
+
* connection type — include those and the core shifts under a returning user,
|
|
18
|
+
* which is the failure that makes a fingerprint useless: it stops recognising
|
|
19
|
+
* the people it is supposed to recognise.
|
|
20
|
+
*
|
|
21
|
+
* ## The privacy tension, stated plainly
|
|
22
|
+
*
|
|
23
|
+
* This links a private window to ordinary browsing on the same machine. Someone
|
|
24
|
+
* using a private window is often specifically trying to prevent that. There is
|
|
25
|
+
* no version of this that is both effective against storage clearing and
|
|
26
|
+
* respectful of the intent behind it — the two are the same act.
|
|
27
|
+
*
|
|
28
|
+
* So it is: hashed with the tenant salt before it is stored, never shared
|
|
29
|
+
* between tenants, suppressed entirely under `consent: 'deferred'`, and
|
|
30
|
+
* individually disableable. And it is weaker evidence than a real device id by
|
|
31
|
+
* design — enough to notice one device trying forty accounts, not enough to
|
|
32
|
+
* treat as identity.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Signals that survive a storage wipe and do not drift.
|
|
36
|
+
*
|
|
37
|
+
* Ordered for readability; the hash sorts them.
|
|
38
|
+
*/
|
|
39
|
+
const STABLE_KEYS = [
|
|
40
|
+
// Rendering stack. These are strings the driver reports, not rendered output,
|
|
41
|
+
// which is what makes them survive fingerprinting protection.
|
|
42
|
+
'webgl.renderer',
|
|
43
|
+
'webgl.vendor',
|
|
44
|
+
'webgl.parametersHash',
|
|
45
|
+
'webgl.fragmentHighFloat',
|
|
46
|
+
// Engine and libm quirks: constant for a given browser build on given hardware.
|
|
47
|
+
'math.quirksHash',
|
|
48
|
+
'err.nullAccessMessage',
|
|
49
|
+
// Physical machine — the properties privacy modes leave alone.
|
|
50
|
+
'screen.colorDepth',
|
|
51
|
+
'screen.devicePixelRatio',
|
|
52
|
+
'nav.hardwareConcurrency',
|
|
53
|
+
'nav.deviceMemory',
|
|
54
|
+
'nav.maxTouchPoints',
|
|
55
|
+
// Configuration a user rarely changes and never mid-session.
|
|
56
|
+
'nav.platform',
|
|
57
|
+
'tz.timezone',
|
|
58
|
+
];
|
|
59
|
+
/**
|
|
60
|
+
* Keys left out, with the reason — so the next person to add one has to argue
|
|
61
|
+
* with something.
|
|
62
|
+
*
|
|
63
|
+
* nav.userAgent moves on every browser update
|
|
64
|
+
* features.hash moves on every browser update
|
|
65
|
+
* screen.innerWidth moves when the window is resized
|
|
66
|
+
* screen.chromeHeight needs focus, and moves with the toolbar
|
|
67
|
+
* nav.languages a user can change it, and some browsers reorder it
|
|
68
|
+
* canvas.stable a property of the browser's privacy settings, not the device
|
|
69
|
+
* nav.connectionType changes with the network, which is the point of it
|
|
70
|
+
*
|
|
71
|
+
* The next three were in the core until a measurement removed them. Safari 26,
|
|
72
|
+
* same machine, normal versus private browsing:
|
|
73
|
+
*
|
|
74
|
+
* canvas.hash 9cabb395 -> ec0c368d
|
|
75
|
+
* screen.width 1728 -> 1340
|
|
76
|
+
* screen.height 1117 -> 823
|
|
77
|
+
*
|
|
78
|
+
* Everything else was identical, so a core without these three would have
|
|
79
|
+
* matched — and with them it could not.
|
|
80
|
+
*
|
|
81
|
+
* canvas.hash Safari's fingerprinting protection seeds canvas noise **per
|
|
82
|
+
* session**. Two renders inside one session agree, so
|
|
83
|
+
* `canvas.stable` reports true and the noise check below does
|
|
84
|
+
* not fire. There is no in-session test that detects this;
|
|
85
|
+
* the only reliable answer is to keep rendered output out of
|
|
86
|
+
* a core that has to survive privacy modes.
|
|
87
|
+
*
|
|
88
|
+
* screen.width Safari private reports the *viewport* as the screen: 1340x823
|
|
89
|
+
* screen.height were exactly innerWidth and innerHeight. So these are not a
|
|
90
|
+
* different screen, they are a spoof — and one that moves
|
|
91
|
+
* again whenever the window is resized.
|
|
92
|
+
*/
|
|
93
|
+
export const EXCLUDED_FROM_CORE = [
|
|
94
|
+
'nav.userAgent',
|
|
95
|
+
'features.hash',
|
|
96
|
+
'screen.innerWidth',
|
|
97
|
+
'screen.chromeHeight',
|
|
98
|
+
'nav.languages',
|
|
99
|
+
'canvas.stable',
|
|
100
|
+
'nav.connectionType',
|
|
101
|
+
'canvas.hash',
|
|
102
|
+
'screen.width',
|
|
103
|
+
'screen.height',
|
|
104
|
+
];
|
|
105
|
+
const MINIMUM_KEYS = 8;
|
|
106
|
+
/**
|
|
107
|
+
* Signals a browser may randomise between two reads in the same session.
|
|
108
|
+
*
|
|
109
|
+
* Kept as a guard even though canvas is no longer in the core, because the same
|
|
110
|
+
* per-read randomisation could appear on another signal — and because it
|
|
111
|
+
* catches Brave, which farbles per read rather than per session.
|
|
112
|
+
*
|
|
113
|
+
* It does **not** catch Safari, whose noise is seeded once per session: two
|
|
114
|
+
* renders agree, the check passes, and the value still differs the next time
|
|
115
|
+
* the browser is opened. That is why canvas was removed outright rather than
|
|
116
|
+
* guarded. An in-session test cannot detect a per-session seed.
|
|
117
|
+
*/
|
|
118
|
+
const NOISE_TARGETS = ['canvas.hash'];
|
|
119
|
+
export function stableCore(signals) {
|
|
120
|
+
const present = {};
|
|
121
|
+
// `canvas.stable` is the collector rendering twice and comparing. False means
|
|
122
|
+
// the browser is injecting noise, and we already know not to trust it.
|
|
123
|
+
const canvasRandomised = signals['canvas.stable'] === false;
|
|
124
|
+
for (const key of STABLE_KEYS) {
|
|
125
|
+
if (canvasRandomised && NOISE_TARGETS.includes(key))
|
|
126
|
+
continue;
|
|
127
|
+
const value = signals[key];
|
|
128
|
+
if (value !== undefined && value !== null && value !== '')
|
|
129
|
+
present[key] = value;
|
|
130
|
+
}
|
|
131
|
+
const count = Object.keys(present).length;
|
|
132
|
+
return {
|
|
133
|
+
hash: hashRecord(present),
|
|
134
|
+
present: count,
|
|
135
|
+
total: STABLE_KEYS.length,
|
|
136
|
+
parts: present,
|
|
137
|
+
noiseExcluded: canvasRandomised,
|
|
138
|
+
// A core built from three values is not an identifier, it is a coincidence
|
|
139
|
+
// waiting to happen. Saying so is cheaper than explaining a wrong link.
|
|
140
|
+
usable: count >= MINIMUM_KEYS,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The machine, separated from the browser running on it.
|
|
145
|
+
*
|
|
146
|
+
* Two tiers because they decay at different rates, and the difference between
|
|
147
|
+
* them is itself information. A browser update changes the engine tier and
|
|
148
|
+
* leaves the hardware tier alone; a new laptop changes both. Hashing all
|
|
149
|
+
* thirteen keys together means any single change mints a brand-new identity,
|
|
150
|
+
* so a returning customer who updated Chrome looks exactly like a stranger.
|
|
151
|
+
*
|
|
152
|
+
* The hardware tier is what a device-keyed limit should key on: it survives a
|
|
153
|
+
* cleared profile *and* a browser update, which is the combination a
|
|
154
|
+
* credential-stuffing run produces on purpose.
|
|
155
|
+
*/
|
|
156
|
+
const HARDWARE_KEYS = [
|
|
157
|
+
'webgl.renderer',
|
|
158
|
+
'webgl.vendor',
|
|
159
|
+
'webgl.parametersHash',
|
|
160
|
+
'webgl.fragmentHighFloat',
|
|
161
|
+
'screen.colorDepth',
|
|
162
|
+
'screen.devicePixelRatio',
|
|
163
|
+
'nav.hardwareConcurrency',
|
|
164
|
+
'nav.deviceMemory',
|
|
165
|
+
'nav.maxTouchPoints',
|
|
166
|
+
];
|
|
167
|
+
/** The build and its configuration: everything that moves when the browser does. */
|
|
168
|
+
const BROWSER_KEYS = ['math.quirksHash', 'err.nullAccessMessage', 'nav.platform', 'tz.timezone'];
|
|
169
|
+
/** Hardware needs fewer keys to be worth trusting, because each carries more. */
|
|
170
|
+
const MINIMUM_HARDWARE_KEYS = 5;
|
|
171
|
+
function tier(signals, keys, minimum) {
|
|
172
|
+
const present = {};
|
|
173
|
+
for (const key of keys) {
|
|
174
|
+
const value = signals[key];
|
|
175
|
+
if (value !== undefined && value !== null && value !== '')
|
|
176
|
+
present[key] = value;
|
|
177
|
+
}
|
|
178
|
+
const count = Object.keys(present).length;
|
|
179
|
+
return { hash: hashRecord(present), present: count, total: keys.length, usable: count >= minimum };
|
|
180
|
+
}
|
|
181
|
+
export function hardwareCore(signals) {
|
|
182
|
+
return tier(signals, HARDWARE_KEYS, MINIMUM_HARDWARE_KEYS);
|
|
183
|
+
}
|
|
184
|
+
export function browserCore(signals) {
|
|
185
|
+
return tier(signals, BROWSER_KEYS, 2);
|
|
186
|
+
}
|
|
187
|
+
export { STABLE_KEYS, NOISE_TARGETS, HARDWARE_KEYS, BROWSER_KEYS };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collectors run in three budgeted waves so a protected action is never
|
|
3
|
+
* delayed. A wave that exceeds its budget is abandoned and reported, never
|
|
4
|
+
* awaited — a slow fingerprint is worse than a missing one.
|
|
5
|
+
*
|
|
6
|
+
* See docs/signals.md section 1.
|
|
7
|
+
*/
|
|
8
|
+
export type Wave = 'instant' | 'warm' | 'deep';
|
|
9
|
+
/**
|
|
10
|
+
* How long each wave may take before the rest of it is skipped.
|
|
11
|
+
*
|
|
12
|
+
* Generous on purpose. A budget is a ceiling, not a cost: a fast device
|
|
13
|
+
* finishes the instant wave in a few milliseconds and never comes near it. The
|
|
14
|
+
* ceiling exists for the slow device, and the old one (instant 5 ms, warm
|
|
15
|
+
* 60 ms) was set against desktop timings — a mid-range phone runs these several
|
|
16
|
+
* times slower and lost half its signals, bot detection among them. The total a
|
|
17
|
+
* protected action waits is still capped by the SDK's `timeoutMs`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const WAVE_BUDGET_MS: Record<Wave, number>;
|
|
20
|
+
/** Everything a collector is allowed to touch, injected rather than global. */
|
|
21
|
+
export interface CollectorEnv {
|
|
22
|
+
readonly window: Window & typeof globalThis;
|
|
23
|
+
readonly navigator: Navigator;
|
|
24
|
+
readonly document: Document;
|
|
25
|
+
readonly screen: Screen;
|
|
26
|
+
readonly performance: Performance;
|
|
27
|
+
}
|
|
28
|
+
export type SignalValue = string | number | boolean | null;
|
|
29
|
+
export interface Collector {
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly wave: Wave;
|
|
32
|
+
/**
|
|
33
|
+
* The tenant may switch this off without it counting as missing evidence.
|
|
34
|
+
*
|
|
35
|
+
* Disabling a required collector lowers confidence, because the signal is
|
|
36
|
+
* genuinely absent. Disabling an optional one does not: it is a choice the
|
|
37
|
+
* product offered, and charging confidence for taking it means penalising a
|
|
38
|
+
* tenant for using their own privacy control on every request thereafter.
|
|
39
|
+
*
|
|
40
|
+
* Says nothing about a collector that ran and found nothing. That is a real
|
|
41
|
+
* absence and still counts.
|
|
42
|
+
*/
|
|
43
|
+
readonly optional?: boolean;
|
|
44
|
+
collect(env: CollectorEnv): Promise<Record<string, SignalValue>> | Record<string, SignalValue>;
|
|
45
|
+
}
|
|
46
|
+
export interface CollectionResult {
|
|
47
|
+
readonly signals: Record<string, SignalValue>;
|
|
48
|
+
readonly durationMs: number;
|
|
49
|
+
/** Collectors that threw, timed out, or were disabled. */
|
|
50
|
+
readonly skipped: readonly string[];
|
|
51
|
+
readonly errors: readonly string[];
|
|
52
|
+
/** 0..1 — how much of the expected signal set was actually obtained. */
|
|
53
|
+
readonly confidence: number;
|
|
54
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* How long each wave may take before the rest of it is skipped.
|
|
3
|
+
*
|
|
4
|
+
* Generous on purpose. A budget is a ceiling, not a cost: a fast device
|
|
5
|
+
* finishes the instant wave in a few milliseconds and never comes near it. The
|
|
6
|
+
* ceiling exists for the slow device, and the old one (instant 5 ms, warm
|
|
7
|
+
* 60 ms) was set against desktop timings — a mid-range phone runs these several
|
|
8
|
+
* times slower and lost half its signals, bot detection among them. The total a
|
|
9
|
+
* protected action waits is still capped by the SDK's `timeoutMs`.
|
|
10
|
+
*/
|
|
11
|
+
export const WAVE_BUDGET_MS = {
|
|
12
|
+
instant: 60,
|
|
13
|
+
warm: 200,
|
|
14
|
+
deep: 400,
|
|
15
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magield/collectors",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Browser signal collectors used by the Magic Shield web SDK",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"files": [
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
".": "./dist/index.js"
|
|
18
18
|
},
|
|
19
19
|
"main": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
20
21
|
"sideEffects": false,
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@types/node": "^22.10.2",
|