1/* V106 - Auditoria de acesso e rotinas utilizadas */ 2(function () { 3 const COLECAO_LOG = 'logsAcessoPortal'; 4 const IP_CACHE_KEY = 'appconsultores_ip_publico_v106'; 5 6 function texto(v) { return String(v == null ? '' : v).trim(); } 7 function agoraISO() { try { return new Date().toISOString(); } catch (_) { return ''; } } 8 function normalizar(v) { 9 return texto(v).toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, ''); 10 } 11 function getUsuario() { 12 try { return (typeof getUsuarioLogado === 'function' && getUsuarioLogado()) || localStorage.getItem('appconsultores_usuario') || ''; } catch (_) { return ''; } 13 } 14 function getRegistro() { 15 try { return (typeof getUsuarioRegistro === 'function' && getUsuarioRegistro()) || JSON.parse(localStorage.getItem('appconsultores_usuario_registro') || '{}') || {}; } catch (_) { return {}; } 16 } 17 function getPerfil() { 18 try { return (typeof getPerfilLogado === 'function' && getPerfilLogado()) || localStorage.getItem('appconsultores_perfil') || ''; } catch (_) { return ''; } 19 } 20 function getEmpresa() { 21 try { 22 if (typeof getEmpresaSelecionadaV92 === 'function') return getEmpresaSelecionadaV92() || {}; 23 } catch (_) {} 24 try { return JSON.parse(localStorage.getItem('appconsultores_empresa_login_v92') || '{}') || {}; } catch (_) { return {}; } 25 } 26 function rotinaAtual() { 27 const h1 = document.querySelector('h1')?.textContent || ''; 28 const h2 = document.querySelector('h2')?.textContent || ''; 29 const title = document.title || ''; 30 const path = location.pathname.split('/').pop() || 'index.html'; 31 return texto(h1 || h2 || title || path) || path; 32 } 33 function idRotinaAtual() { 34 const path = location.pathname || ''; 35 const file = path.split('/').pop() || 'index.html'; 36 return normalizar(file.replace(/\.html?$/i, '') || 'index'); 37 } 38 function isPaginaLogin() { 39 try { return typeof paginaAtualLogin === 'function' ? paginaAtualLogin() : /(^|\/)index\.html$|\/$/.test(location.pathname); } catch (_) { return false; } 40 } 41 async function ipPublico() { 42 try { 43 const cache = localStorage.getItem(IP_CACHE_KEY); 44 if (cache) return cache; 45 } catch (_) {} 46 try { 47 const ctrl = new AbortController(); 48 const t = setTimeout(() => ctrl.abort(), 1400); 49 const resp = await fetch('https://api.ipify.org?format=json', { signal: ctrl.signal, cache: 'no-store' }); 50 clearTimeout(t); 51 if (resp.ok) { 52 const json = await resp.json(); 53 const ip = texto(json.ip); 54 if (ip) { 55 try { localStorage.setItem(IP_CACHE_KEY, ip); } catch (_) {} 56 return ip; 57 } 58 } 59 } catch (_) {} 60 return 'não identificado pelo navegador'; 61 } 62 function dadosBase(evento, rotina, extra) { 63 const emp = getEmpresa(); 64 const reg = getRegistro(); 65 const usuario = getUsuario(); 66 return { 67 evento: texto(evento || 'acesso_rotina'), 68 rotina: texto(rotina || rotinaAtual()), 69 rotinaId: idRotinaAtual(), 70 usuario: usuario || reg.usuarioFinal || reg.usuario || reg.login || 'não identificado', 71 nomeUsuario: reg.nomeUsuario || reg.nome || reg.nomeCompleto || reg.consultorNome || reg.nomeConsultor || reg.clienteNome || reg.nomeCliente || usuario || '', 72 perfil: getPerfil() || reg.perfilFinal || reg.perfil || '', 73 empresaId: emp.id || emp.empresaId || reg.empresaId || reg.idEmpresa || '', 74 empresaCodigo: emp.codigo || emp.empresaCodigo || reg.empresaCodigo || reg.codigoEmpresa || '', 75 empresaNome: emp.nome || emp.empresaNome || reg.empresaNome || reg.nomeEmpresa || '', 76 url: location.href, 77 path: location.pathname, 78 origem: 'web', 79 navegador: navigator.userAgent || '', 80 idioma: navigator.language || '', 81 plataforma: navigator.platform || '', 82 larguraTela: window.innerWidth || null, 83 alturaTela: window.innerHeight || null, 84 dataHoraLocal: new Date().toLocaleString('pt-BR'), 85 dataHoraISO: agoraISO(), 86 extra: extra || {} 87 }; 88 } 89 async function registrarAuditoriaPortalV106(evento, rotina, extra) { 90 try { 91 if (!window.db) return false;
92 const usuario = getUsuario(); 93 if (!usuario && evento !== 'login_sucesso') return false; 94 const base = dadosBase(evento, rotina, extra); 95 base.ip = await ipPublico(); 96 base.criadoEm = (window.firebase && firebase.firestore && firebase.firestore.FieldValue) ? firebase.firestore.FieldValue.serverTimestamp() : new Date(); 97 await db.collection(COLECAO_LOG).add(base); 98 return true; 99 } catch (e) { 100 console.warn('Auditoria V106 não gravada:', e); 101 return false; 102 } 103 } 104 window.registrarAuditoriaPortalV106 = registrarAuditoriaPortalV106; 105 106 document.addEventListener('DOMContentLoaded', function () { 107 setTimeout(function () { 108 if (!isPaginaLogin() && getUsuario()) registrarAuditoriaPortalV106('acesso_rotina', rotinaAtual(), { auto: true }); 109 }, 800); 110 }); 111})(); 112 113 114/* V107 - proteção Firestore auditoria */ 115(function(){ 116 window.gravarLogAcessoPortalSeguroV107 = async function(evento, rotina){ 117 try { 118 if (typeof window.registrarAuditoriaPortalV106 === 'function') { 119 return await window.registrarAuditoriaPortalV106(evento, rotina); 120 } 121 } catch (e) { 122 console.warn('Auditoria não gravada:', e); 123 } 124 }; 125})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.