UNPKG

@thumbmarkjs/thumbmarkjs

Version:

![GitHub package.json dynamic](https://img.shields.io/github/package-json/version/ilkkapeltola/thumbmarkjs) ![NPM Version](https://img.shields.io/npm/v/@thumbmarkjs/thumbmarkjs) ![NPM Downloads](https://img.shields.io/npm/dm/%40thumbmarkjs%2Fthumbmarkjs

118 lines (108 loc) 5.05 kB
import {componentInterface, getComponentPromises, timeoutInstance} from '../factory' import {hash} from '../utils/hash' import {raceAll, raceAllPerformance} from '../utils/raceAll' import {options} from './options' import * as packageJson from '../../package.json' export function getVersion(): string { return packageJson.version } export async function getFingerprintData(): Promise<componentInterface> { try { const promiseMap: Record<string, Promise<componentInterface>> = getComponentPromises() const keys: string[] = Object.keys(promiseMap) const promises: Promise<componentInterface>[] = Object.values(promiseMap) const resolvedValues: (componentInterface | undefined)[] = await raceAll(promises, options?.timeout || 1000, timeoutInstance); const validValues: componentInterface[] = resolvedValues.filter((value): value is componentInterface => value !== undefined); const resolvedComponents: Record<string, componentInterface> = {}; validValues.forEach((value, index) => { resolvedComponents[keys[index]] = value }) return filterFingerprintData(resolvedComponents, options.exclude || [], options.include || [], "") } catch (error) { throw error } } /** * This function filters the fingerprint data based on the exclude and include list * @param {componentInterface} obj - components objects from main componentInterface * @param {string[]} excludeList - elements to exclude from components objects (e.g : 'canvas', 'system.browser') * @param {string[]} includeList - elements to only include from components objects (e.g : 'canvas', 'system.browser') * @param {string} path - auto-increment path iterating on key objects from components objects * @returns {componentInterface} result - returns the final object before hashing in order to get fingerprint */ export function filterFingerprintData(obj: componentInterface, excludeList: string[], includeList: string[], path: string = ""): componentInterface { const result: componentInterface = {}; for (const [key, value] of Object.entries(obj)) { const currentPath = path + key + "."; if (typeof value === "object" && !Array.isArray(value)) { const filtered = filterFingerprintData(value, excludeList, includeList, currentPath); if (Object.keys(filtered).length > 0) { result[key] = filtered; } } else { const isExcluded = excludeList.some(exclusion => currentPath.startsWith(exclusion)); const isIncluded = includeList.some(inclusion => currentPath.startsWith(inclusion)); if (!isExcluded || isIncluded) { result[key] = value; } } } return result; } export async function getFingerprint(includeData?: false): Promise<string> export async function getFingerprint(includeData: true): Promise<{ hash: string, data: componentInterface }> export async function getFingerprint(includeData?: boolean): Promise<string | { hash: string, data: componentInterface }> { try { const fingerprintData = await getFingerprintData() const thisHash = hash(JSON.stringify(fingerprintData)) if (Math.random() < 0.0001 && options.logging) logFingerprintData(thisHash, fingerprintData) if (includeData) { return { hash: thisHash.toString(), data: fingerprintData} } else { return thisHash.toString() } } catch (error) { throw error } } export async function getFingerprintPerformance() { try { const promiseMap = getComponentPromises() const keys = Object.keys(promiseMap) const promises = Object.values(promiseMap) const resolvedValues = await raceAllPerformance(promises, options?.timeout || 1000, timeoutInstance ) const resolvedComponents: { [key: string]: any } = { elapsed: {} } resolvedValues.forEach((value, index) => { resolvedComponents[keys[index]] = value.value resolvedComponents["elapsed"][keys[index]] = value.elapsed }); return resolvedComponents } catch (error) { throw error } } // Function to log the fingerprint data async function logFingerprintData(thisHash: string, fingerprintData: componentInterface) { const url = 'https://logging.thumbmarkjs.com/v1/log' const payload = { thumbmark: thisHash, components: fingerprintData, version: getVersion() }; if (!sessionStorage.getItem("_tmjs_l")) { sessionStorage.setItem("_tmjs_l", "1") try { await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); } catch { } // do nothing } }