feat: capture and log browser information during user login

- Integrated browser information capture in the login process, including user agent and IP address.
- Enhanced device and browser detection logic to provide more detailed insights into user environments.
- Improved system detection for various operating systems and devices, ensuring accurate reporting during authentication.
This commit is contained in:
2025-11-04 02:27:56 -03:00
parent 372b2b5bf9
commit f278ad4d17
3 changed files with 272 additions and 12 deletions

View File

@@ -0,0 +1,98 @@
/**
* Função utilitária para obter informações do navegador
* Sem usar APIs externas
*/
/**
* Obtém o User-Agent do navegador
*/
export function getUserAgent(): string {
if (typeof window === 'undefined' || !window.navigator) {
return '';
}
return window.navigator.userAgent || '';
}
/**
* Tenta obter o IP local usando WebRTC
* Esta função não usa API externa, mas pode falhar em alguns navegadores
* Retorna undefined se não conseguir obter
*/
export async function getLocalIP(): Promise<string | undefined> {
return new Promise((resolve) => {
// Verificar se está em ambiente browser
if (typeof window === 'undefined' || typeof RTCPeerConnection === 'undefined') {
resolve(undefined);
return;
}
try {
const pc = new RTCPeerConnection({
iceServers: []
});
let resolved = false;
const timeout = setTimeout(() => {
if (!resolved) {
resolved = true;
pc.close();
resolve(undefined);
}
}, 3000);
pc.onicecandidate = (event) => {
if (event.candidate && !resolved) {
const candidate = event.candidate.candidate;
// Regex para extrair IP local (IPv4)
const ipMatch = candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3})/);
if (ipMatch && ipMatch[1]) {
const ip = ipMatch[1];
// Verificar se não é IP localhost (127.0.0.1 ou ::1)
if (!ip.startsWith('127.') && !ip.startsWith('::1')) {
if (!resolved) {
resolved = true;
clearTimeout(timeout);
pc.close();
resolve(ip);
}
}
}
}
};
// Criar um data channel para forçar a criação de candidatos
pc.createDataChannel('');
pc.createOffer()
.then((offer) => pc.setLocalDescription(offer))
.catch(() => {
if (!resolved) {
resolved = true;
clearTimeout(timeout);
pc.close();
resolve(undefined);
}
});
} catch (error) {
resolve(undefined);
}
});
}
/**
* Obtém informações completas do navegador
*/
export interface BrowserInfo {
userAgent: string;
ipAddress?: string;
}
export async function getBrowserInfo(): Promise<BrowserInfo> {
const userAgent = getUserAgent();
const ipAddress = await getLocalIP();
return {
userAgent,
ipAddress,
};
}