PageSourceSearch

https://appagendaconsultor.web.app/js/auditoria-portal.js?v=125

js appagendaconsultor.web.app collected 2026-10-03 12:16:54 UTC 5,416 bytes, 125 lines download raw bytes

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.