GeoNetAgent, LDAPWeb, server-audit, server-connection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
7.3 KiB

(function () {
'use strict';
var cfg = window.__AUDIT_BEACON__;
if (!cfg || !cfg.context) {
return;
}
function csrfToken() {
var meta = document.querySelector('meta[name="csrf-token"]');
return meta ? meta.getAttribute('content') : '';
}
function postBeacon(url, fields) {
var fd = new FormData();
fd.append('_token', csrfToken());
Object.keys(fields).forEach(function (key) {
if (fields[key] !== null && fields[key] !== undefined && fields[key] !== '') {
fd.append(key, fields[key]);
}
});
if (navigator.sendBeacon) {
navigator.sendBeacon(url, fd);
return;
}
fetch(url, { method: 'POST', body: fd, credentials: 'same-origin', keepalive: true }).catch(function () {});
}
function detectBrowser() {
var ua = navigator.userAgent;
if (ua.indexOf('Edg/') !== -1) {
return { name: 'Edge', version: (ua.match(/Edg\/([\d.]+)/) || [])[1] || '' };
}
if (ua.indexOf('OPR/') !== -1 || ua.indexOf('Opera') !== -1) {
return { name: 'Opera', version: (ua.match(/(?:OPR|Opera)\/([\d.]+)/) || [])[1] || '' };
}
if (ua.indexOf('Chrome/') !== -1 && ua.indexOf('Edg/') === -1) {
return { name: 'Chrome', version: (ua.match(/Chrome\/([\d.]+)/) || [])[1] || '' };
}
if (ua.indexOf('Firefox/') !== -1) {
return { name: 'Firefox', version: (ua.match(/Firefox\/([\d.]+)/) || [])[1] || '' };
}
if (ua.indexOf('Safari/') !== -1 && ua.indexOf('Chrome') === -1) {
return { name: 'Safari', version: (ua.match(/Version\/([\d.]+)/) || [])[1] || '' };
}
return { name: 'Unknown', version: '' };
}
function detectOs() {
var ua = navigator.userAgent;
var platform = navigator.platform || '';
if (/Windows NT 10/.test(ua)) return { name: 'Windows', version: '10/11' };
if (/Windows NT 6\.3/.test(ua)) return { name: 'Windows', version: '8.1' };
if (/Windows NT 6\.1/.test(ua)) return { name: 'Windows', version: '7' };
if (/Android/.test(ua)) return { name: 'Android', version: (ua.match(/Android ([\d.]+)/) || [])[1] || '' };
if (/iPhone|iPad|iPod/.test(ua)) return { name: 'iOS', version: (ua.match(/OS ([\d_]+)/) || [])[1].replace(/_/g, '.') || '' };
if (/Mac OS X/.test(ua)) return { name: 'macOS', version: (ua.match(/Mac OS X ([\d_]+)/) || [])[1].replace(/_/g, '.') || '' };
if (/Linux/.test(ua) || /Linux/.test(platform)) return { name: 'Linux', version: '' };
return { name: platform || 'Unknown', version: '' };
}
function detectGpu() {
try {
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) return '';
var ext = gl.getExtension('WEBGL_debug_renderer_info');
if (!ext) return '';
var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
return renderer ? String(renderer).substring(0, 255) : '';
} catch (e) {
return '';
}
}
function detectWebrtcIp() {
return new Promise(function (resolve) {
var resolved = false;
var finish = function (ip) {
if (resolved) return;
resolved = true;
resolve(ip || '');
};
setTimeout(function () { finish(''); }, 2500);
try {
var RTCPeer = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (!RTCPeer) {
finish('');
return;
}
var pc = new RTCPeer({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
pc.createDataChannel('');
pc.createOffer().then(function (offer) { return pc.setLocalDescription(offer); }).catch(function () { finish(''); });
pc.onicecandidate = function (event) {
if (!event || !event.candidate || !event.candidate.candidate) return;
var parts = event.candidate.candidate.split(' ');
var ip = parts[4];
if (ip && ip.indexOf('.') !== -1) {
finish(ip);
pc.close();
}
};
} catch (e) {
finish('');
}
});
}
function collectContext() {
var browser = detectBrowser();
var os = detectOs();
var screenRes = window.screen ? window.screen.width + 'x' + window.screen.height : '';
var ctx = {
browser: browser.name,
browser_version: browser.version,
os: os.name,
os_version: os.version,
screen: screenRes,
cpu_cores: navigator.hardwareConcurrency || '',
device_memory_gb: navigator.deviceMemory || '',
gpu: detectGpu(),
language: navigator.language || (navigator.languages && navigator.languages[0]) || '',
timezone: ''
};
try {
ctx.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || '';
} catch (e) {}
return ctx;
}
function sendContext(ctx) {
postBeacon(cfg.context, ctx);
}
function newVisitId() {
if (window.crypto && crypto.randomUUID) {
return crypto.randomUUID();
}
return 'v-' + Date.now() + '-' + Math.random().toString(16).slice(2);
}
var pageVisitId = newVisitId();
var pageStart = Date.now();
var hiddenAt = null;
var activeMs = 0;
function onVisibilityChange() {
if (document.hidden) {
hiddenAt = Date.now();
} else if (hiddenAt !== null) {
activeMs += Date.now() - hiddenAt;
hiddenAt = null;
}
}
function currentDurationMs() {
var now = Date.now();
var extra = document.hidden && hiddenAt !== null ? now - hiddenAt : 0;
return Math.max(0, now - pageStart - activeMs - extra);
}
function sendPageView() {
postBeacon(cfg.pageView, {
page_visit_id: pageVisitId,
path: window.location.pathname,
title: document.title || '',
referrer: document.referrer || ''
});
}
function sendPageDuration() {
postBeacon(cfg.pageDuration, {
page_visit_id: pageVisitId,
path: window.location.pathname,
duration_ms: Math.round(currentDurationMs())
});
}
document.addEventListener('visibilitychange', onVisibilityChange);
window.addEventListener('pagehide', sendPageDuration);
window.addEventListener('beforeunload', sendPageDuration);
function startPageVisit() {
sendPageDuration();
pageVisitId = newVisitId();
pageStart = Date.now();
hiddenAt = null;
activeMs = 0;
sendPageView();
}
var ctx = collectContext();
detectWebrtcIp().then(function (webrtcIp) {
if (webrtcIp) {
ctx.webrtc_ip = webrtcIp;
}
sendContext(ctx);
sendPageView();
});
document.addEventListener('app:frame-loaded', function () {
startPageVisit();
});
})();