diff --git a/src/imports/auth/login/index.ts b/src/imports/auth/login/index.ts index be2bdb1..55c66cb 100644 --- a/src/imports/auth/login/index.ts +++ b/src/imports/auth/login/index.ts @@ -16,9 +16,10 @@ interface LoginParams { resolution?: { width: number; height: number } | string; userAgent?: string; source?: string; + fingerprint?: string; } -interface accessLog { +interface AccessLog { _createdAt: Date; _updatedAt: Date; ip?: string | string[]; @@ -31,6 +32,7 @@ interface accessLog { resolution?: { width: number; height: number }; reason?: string; source?: string; + fingerprint?: string; __from?: string; _user?: [ { @@ -41,10 +43,10 @@ interface accessLog { ]; } -export async function login({ ip, user, password, password_SHA256, geolocation, resolution, userAgent, source }: LoginParams) { +export async function login({ ip, user, password, password_SHA256, geolocation, resolution, userAgent, source, fingerprint }: LoginParams) { const ua = new UAParser(userAgent ?? 'API Call').getResult(); - const accessLog: accessLog = { + const accessLog: AccessLog = { _createdAt: new Date(), _updatedAt: new Date(), ip, @@ -54,6 +56,7 @@ export async function login({ ip, user, password, password_SHA256, geolocation, os: ua.os.name, platform: ua.device.type, source, + fingerprint, __from: 'login', }; diff --git a/src/imports/model/Namespace.ts b/src/imports/model/Namespace.ts index 76c5ec4..131490c 100644 --- a/src/imports/model/Namespace.ts +++ b/src/imports/model/Namespace.ts @@ -40,6 +40,7 @@ export const NamespaceSchema = z .object({ type: z.literal('Namespace'), trackUserGeolocation: z.boolean().optional(), + trackUserFingerprint: z.boolean().optional(), loginExpiration: z.number().optional(), dateFormat: z.string().optional(), logoURL: z.string().optional(), diff --git a/src/private/templates/fingerprint.js b/src/private/templates/fingerprint.js new file mode 100644 index 0000000..a5bae74 --- /dev/null +++ b/src/private/templates/fingerprint.js @@ -0,0 +1,26 @@ +(function () { + if (window.localStorage) { + const MAX_FP_AGE = 10 * 24 * 60 * 60 * 1000; // 10 days + window.fingerprint = localStorage.getItem('_k.fp'); + + if (window.fingerprint) { + var fpDate = localStorage.getItem('_k.fp.date'); + + if (fpDate && Date.now() - Number(fpDate) > MAX_FP_AGE) { + localStorage.removeItem('_k.fp'); + localStorage.removeItem('_k.fp.date'); + window.fingerprint = null; + } + } + + if (!window.fingerprint) { + const fpPromise = window.FingerprintJS.load(); + + fpPromise.then((fp) => fp.get()).then((result) => { + window.fingerprint = result.visitorId; + localStorage.setItem('_k.fp', result.visitorId); + localStorage.setItem('_k.fp.date', new Date().getTime().toString()); + }); + } + } +})(); diff --git a/src/private/templates/index.hbs b/src/private/templates/index.hbs index f2bbf11..0ea5dbc 100644 --- a/src/private/templates/index.hbs +++ b/src/private/templates/index.hbs @@ -64,6 +64,10 @@ integrity="sha512-Kq3/MTxphzXJIRDWtrpLhhNnLDPiBXPMKkx/KogMYZO92Geor9j8sJguZ1OozBS+YVmVKo2HEx2gZfGOQBFM8A==" crossorigin="anonymous" > + {{#if collectFingerprint}} + + + {{/if}} + + {{/if}}