BillTracker/services/loginFingerprint.js

73 lines
2.1 KiB
JavaScript

'use strict';
const crypto = require('crypto');
function parseBrowser(userAgent) {
const ua = String(userAgent || '');
if (/Edg\//i.test(ua)) return 'Edge';
if (/OPR\//i.test(ua) || /Opera/i.test(ua)) return 'Opera';
if (/Firefox\//i.test(ua)) return 'Firefox';
if (/Chrome\//i.test(ua) || /CriOS\//i.test(ua)) return 'Chrome';
if (/Safari\//i.test(ua)) return 'Safari';
if (/curl\//i.test(ua)) return 'curl';
if (/PostmanRuntime\//i.test(ua)) return 'Postman';
return 'Unknown';
}
function parseOs(userAgent) {
const ua = String(userAgent || '');
if (/iPhone|iPad|iPod/i.test(ua)) return 'iOS';
if (/Android/i.test(ua)) return 'Android';
if (/Windows NT/i.test(ua)) return 'Windows';
if (/Mac OS X|Macintosh/i.test(ua)) return 'macOS';
if (/Linux/i.test(ua)) return 'Linux';
if (/CrOS/i.test(ua)) return 'ChromeOS';
return 'Unknown';
}
function parseDeviceType(userAgent) {
const ua = String(userAgent || '');
if (/iPad|Tablet/i.test(ua)) return 'tablet';
if (/Mobi|iPhone|Android/i.test(ua)) return 'mobile';
if (/curl|PostmanRuntime/i.test(ua)) return 'api';
return 'desktop';
}
function coarseIpPrefix(ipAddress) {
const ip = String(ipAddress || '').trim();
if (!ip) return '';
const v4 = ip.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.\d{1,3}$/);
if (v4) return `${v4[1]}.${v4[2]}.${v4[3]}.0/24`;
if (ip.includes(':')) {
return `${ip.split(':').slice(0, 4).join(':')}::/64`;
}
return ip;
}
function buildDeviceFingerprint({ userAgent, ipAddress }) {
const browser = parseBrowser(userAgent);
const os = parseOs(userAgent);
const deviceType = parseDeviceType(userAgent);
const ipPrefix = coarseIpPrefix(ipAddress);
const source = [browser, os, deviceType, String(userAgent || '').slice(0, 500), ipPrefix].join('|');
const fingerprint = crypto.createHash('sha256').update(source).digest('hex').slice(0, 16);
return {
browser,
os,
device_type: deviceType,
device_fingerprint: fingerprint,
};
}
module.exports = {
buildDeviceFingerprint,
coarseIpPrefix,
parseBrowser,
parseDeviceType,
parseOs,
};