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:
98
apps/web/src/lib/utils/browserInfo.ts
Normal file
98
apps/web/src/lib/utils/browserInfo.ts
Normal 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,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user