UNPKG

userdnajs

Version:

Community edition of UserDNA JS. A fingerprint generator library for creating unique user identifiers

3 lines (2 loc) 7.16 kB
function n(n){return function(n){let t=0;if(0===n.length)return t.toString(16);for(let e=0;e<n.length;e++)t=(t<<5)-t+n.charCodeAt(e),t|=0;return Math.abs(t).toString(16)}(n.map((n=>null==n?"null":"object"==typeof n?JSON.stringify(n):String(n))).join("|"))}function t(){try{const n="__test__";return localStorage.setItem(n,n),localStorage.removeItem(n),!0}catch(n){return!1}}function e(){try{const n="__test__";return sessionStorage.setItem(n,n),sessionStorage.removeItem(n),!0}catch(n){return!1}}const o={getKey:(n="userdna")=>`${n}_userdna_fingerprint`,save:(n,i={})=>{const{storageType:s="localStorage",storagePrefix:r="userdna"}=i,a=o.getKey(r),u=JSON.stringify(n);switch(s){case"localStorage":return function(n,e){if(!t())return!1;try{return localStorage.setItem(n,e),!0}catch(n){return!1}}(a,u);case"sessionStorage":return function(n,t){if(!e())return!1;try{return sessionStorage.setItem(n,t),!0}catch(n){return!1}}(a,u);default:return!1}},get:(n={})=>{const{storageType:i="localStorage",storagePrefix:s="userdna"}=n,r=o.getKey(s);switch(i){case"localStorage":return function(n){if(!t())return null;try{const t=localStorage.getItem(n);return t?JSON.parse(t):null}catch(n){return null}}(r);case"sessionStorage":return function(n){if(!e())return null;try{const t=sessionStorage.getItem(n);return t?JSON.parse(t):null}catch(n){return null}}(r);default:return null}}};function i(){return"undefined"==typeof navigator?null:navigator.doNotTrack?navigator.doNotTrack:"doNotTrack"in window?window.doNotTrack:"msDoNotTrack"in navigator?navigator.msDoNotTrack:null}const s={includeBrowserInfo:!0,includeDeviceInfo:!0,includeScreenInfo:!0,includeTimezone:!0,includeLanguage:!0,includeStorage:!0,storagePrefix:"userdna",storageType:"localStorage",customComponents:[]};class r{constructor(n={}){this.lastResult=null,this.options={...s,...n},this.options.customComponents&&this.options.customComponents.length>2&&(this.options.customComponents=this.options.customComponents.slice(0,2))}async getFingerprint(t={}){if(this.lastResult)return this.lastResult;const e=this.getFromStorage();if(e)return this.lastResult=e,e;const o=await this.collectComponents(),i={id:n(Object.entries(o).map((([n,t])=>null==t?null:"object"==typeof t?JSON.stringify(t):String(t))).filter(Boolean)),components:o,createdAt:Date.now(),fromCache:!1};return"none"!==this.options.storageType&&this.saveToStorage(i),this.lastResult=i,i}async getVisitorId(){return(await this.getFingerprint()).id}async isSameVisitor(n){return(await this.getFingerprint()).id===n}async collectComponents(){const n={};if(this.options.includeBrowserInfo&&(n.browserInfo=function(){if("undefined"==typeof navigator)return{userAgent:"",browserName:"unknown",browserVersion:"unknown",os:"unknown",osVersion:"unknown",device:"unknown",vendor:"unknown",cookiesEnabled:!1,doNotTrack:null};const{userAgent:n}=navigator,t=function(n){var t,e,o,i,s,r;let a="unknown",u="unknown";return n.includes("Edg/")?(a="Edge",u=(null===(t=n.match(/Edg\/([0-9.]+)/))||void 0===t?void 0:t[1])||"unknown"):n.includes("Chrome/")?(a="Chrome",u=(null===(e=n.match(/Chrome\/([0-9.]+)/))||void 0===e?void 0:e[1])||"unknown"):n.includes("Safari/")&&!n.includes("Chrome/")?(a="Safari",u=(null===(o=n.match(/Version\/([0-9.]+)/))||void 0===o?void 0:o[1])||"unknown"):n.includes("Firefox/")?(a="Firefox",u=(null===(i=n.match(/Firefox\/([0-9.]+)/))||void 0===i?void 0:i[1])||"unknown"):n.includes("OPR/")||n.includes("Opera/")?(a="Opera",u=(null===(s=n.match(/(?:OPR|Opera)\/([0-9.]+)/))||void 0===s?void 0:s[1])||"unknown"):n.includes("Trident/")&&(a="Internet Explorer",u=(null===(r=n.match(/rv:([0-9.]+)/))||void 0===r?void 0:r[1])||"unknown"),{name:a,version:u}}(n),e=function(n){var t,e,o,i,s,r;let a="unknown",u="unknown";if(n.includes("Windows"))a="Windows",n.includes("Windows NT 10.0")?u="10":n.includes("Windows NT 6.3")?u="8.1":n.includes("Windows NT 6.2")?u="8":n.includes("Windows NT 6.1")?u="7":n.includes("Windows NT 6.0")?u="Vista":n.includes("Windows NT 5.1")?u="XP":n.includes("Windows NT 5.0")&&(u="2000");else if(n.includes("Macintosh")||n.includes("Mac OS X")){a="macOS";const o=(null===(t=n.match(/Mac OS X (\d+[._]\d+[._]\d+)/))||void 0===t?void 0:t[1])||(null===(e=n.match(/Mac OS X (\d+[._]\d+)/))||void 0===e?void 0:e[1]);o&&(u=o.replace(/_/g,"."))}else/iPhone|iPad|iPod/.test(n)?(a="iOS",u=(null===(i=null===(o=n.match(/OS (\d+[._]\d+[._]?\d*)/))||void 0===o?void 0:o[1])||void 0===i?void 0:i.replace(/_/g,"."))||"unknown"):n.includes("Android")?(a="Android",u=(null===(r=null===(s=n.match(/Android (\d+[._]\d+[._]?\d*)/))||void 0===s?void 0:s[1])||void 0===r?void 0:r.replace(/_/g,"."))||"unknown"):n.includes("Linux")&&(a="Linux");return{name:a,version:u}}(n),o=function(n){return/iPhone|iPod/.test(n)?"iPhone":/iPad/.test(n)?"iPad":/Android/.test(n)?/Mobile/.test(n)?"Android Mobile":"Android Tablet":/Windows Phone/.test(n)?"Windows Phone":/Macintosh|Mac OS X/.test(n)?"Mac":/Windows/.test(n)?"Windows":/Linux/.test(n)?"Linux":"unknown"}(n);return{userAgent:n,browserName:t.name,browserVersion:t.version,os:e.name,osVersion:e.version,device:o,vendor:navigator.vendor||"unknown",cookiesEnabled:navigator.cookieEnabled,doNotTrack:i()}}()),this.options.includeScreenInfo&&(n.screenInfo=function(){if("undefined"==typeof window||!window.screen)return{width:0,height:0,availWidth:0,availHeight:0,colorDepth:0,pixelRatio:1};const{screen:n}=window;return{width:n.width,height:n.height,availWidth:n.availWidth,availHeight:n.availHeight,colorDepth:n.colorDepth,pixelRatio:window.devicePixelRatio||1}}()),this.options.includeTimezone)try{n.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(t){n.timezone=String((new Date).getTimezoneOffset())}if(this.options.includeLanguage&&(n.language=navigator.language||navigator.userLanguage||navigator.browserLanguage||"unknown"),this.options.includeStorage&&(n.storage={localStorage:o.save({test:!0},{storageType:"localStorage"}),sessionStorage:o.save({test:!0},{storageType:"sessionStorage"}),cookies:!1,indexedDB:"indexedDB"in window}),this.options.customComponents&&this.options.customComponents.length>0){n.custom={};const t=this.options.customComponents.slice(0,2);await Promise.all(t.map((async t=>{try{n.custom[t.name]=await t.getValue()}catch(e){n.custom[t.name]=null}})))}return n}getFromStorage(){if("none"===this.options.storageType)return null;const n=o.get({storageType:this.options.storageType,storagePrefix:this.options.storagePrefix});if(!n||"object"!=typeof n)return null;try{const t=n;return t.id&&t.components&&t.createdAt?(t.fromCache=!0,t):null}catch(n){return null}}saveToStorage(n){"none"!==this.options.storageType&&o.save(n,{storageType:this.options.storageType,storagePrefix:this.options.storagePrefix})}updateOptions(n){this.options={...this.options,...n},this.options.customComponents&&this.options.customComponents.length>2&&(this.options.customComponents=this.options.customComponents.slice(0,2)),this.lastResult=null}getOptions(){return{...this.options}}}function a(n){return new r(n)}const u={createUserDNA:a,FingerprintGenerator:r};export{r as FingerprintGenerator,a as createUserDNA,u as default}; //# sourceMappingURL=index.esm.min.js.map