cgnat: fix
Signed-off-by: Rodrigo Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
1 parent
8449bd0442
commit
b0f58144a8
2 files changed
+87
-80
No files matched your search
+16
-34
@@ -9006,10 +9006,11 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
{ parse_mode: 'Markdown' }
|
{ parse_mode: 'Markdown' }
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await this.topsapp.obterAcessosPorIp(
|
const result = await this.topsapp.buscarSessaoPorHorario(
|
||||||
session.privateIP,
|
session.privateIP,
|
||||||
dataStr,
|
dataStr,
|
||||||
dataStr
|
dataStr,
|
||||||
|
horaStr || null
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
@@ -9022,39 +9023,20 @@ Digite /help para ver todos os comandos disponíveis!
|
|||||||
|
|
||||||
if (result.total === 0) {
|
if (result.total === 0) {
|
||||||
const extra = result.totalGeral > 0
|
const extra = result.totalGeral > 0
|
||||||
? `\n\n_(${result.totalGeral} registros no período, nenhum com IP \`${session.privateIP}\`)_`
|
? `\n\n_${result.totalGeral} registros retornados para ${dataStr} — nenhuma sessão com IP \`${session.privateIP}\` ou ativa às ${horaStr || 'hora informada'}._`
|
||||||
|
: `\n\n_Nenhum registro retornado para ${dataStr}._`;
|
||||||
|
await this.bot.sendMessage(chatId,
|
||||||
|
`ℹ️ Não foi possível identificar o cliente para \`${session.privateIP}\` em ${dataStr}${horaStr ? ' ' + horaStr : ''}.${extra}`,
|
||||||
|
{ parse_mode: 'Markdown' }
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const aviso = result.modoFallback
|
||||||
|
? '\n⚠️ _IP não encontrado nos registros (sessão encerrada). Mostrando sessões ativas nesse horário._\n'
|
||||||
: '';
|
: '';
|
||||||
await this.bot.sendMessage(chatId,
|
const titulo = `Sessão em ${dataStr}${horaStr ? ' ' + horaStr : ''}`;
|
||||||
`ℹ️ Nenhum acesso encontrado para o IP \`${session.privateIP}\` em ${dataStr}.${extra}`,
|
await this._exibirAcessosCgnat(chatId, session.privateIP, result.dados, titulo + aviso);
|
||||||
{ parse_mode: 'Markdown' }
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filtrar por hora se informada
|
|
||||||
let filtrados = result.dados;
|
|
||||||
if (horaStr) {
|
|
||||||
const [hh, mm] = horaStr.split(':').map(Number);
|
|
||||||
const refMs = hh * 3600000 + mm * 60000;
|
|
||||||
const janela = 3600000; // ±1 hora
|
|
||||||
filtrados = result.dados.filter(a => {
|
|
||||||
const inicioMatch = a.inicio ? a.inicio.match(/(\d{2}):(\d{2})/) : null;
|
|
||||||
if (!inicioMatch) return true;
|
|
||||||
const aMs = parseInt(inicioMatch[1]) * 3600000 + parseInt(inicioMatch[2]) * 60000;
|
|
||||||
return Math.abs(aMs - refMs) <= janela;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filtrados.length === 0) {
|
|
||||||
await this.bot.sendMessage(chatId,
|
|
||||||
`ℹ️ Nenhum acesso de \`${session.privateIP}\` próximo às ${horaStr} em ${dataStr}.\n_(${result.total} registro(s) no dia fora desse horário)_`,
|
|
||||||
{ parse_mode: 'Markdown' }
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const titulo = `Acessos em ${dataStr}${horaStr ? ' ± 1h de ' + horaStr : ''}`;
|
|
||||||
await this._exibirAcessosCgnat(chatId, session.privateIP, filtrados, titulo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+71
-46
@@ -1330,46 +1330,8 @@ class TopSappManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Busca acessos por data no TopSapp e filtra pelo IP privado CGNAT client-side
|
* Busca sessão ativa com determinado IP privado CGNAT.
|
||||||
* (estacao = nome NAS, não o IP — por isso filtramos pelo campo `ip` da resposta)
|
* Usa status:'on' — somente sessões ativas têm o campo `ip` preenchido pelo RADIUS.
|
||||||
*/
|
|
||||||
async obterAcessosPorIp(privateIP, dataInicial, dataFinal, location = '') {
|
|
||||||
if (!this.isReady()) {
|
|
||||||
return { success: false, error: 'TopSapp não está configurado' };
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const credentials = this.config.getCredentialsByLocation(location);
|
|
||||||
const instance = this.api.getInstanceByLocation(location);
|
|
||||||
const params = {};
|
|
||||||
if (dataInicial) params.dataInicial = dataInicial;
|
|
||||||
if (dataFinal) params.dataFinal = dataFinal;
|
|
||||||
const result = await this.api.obterAcessos(params, instance, credentials);
|
|
||||||
|
|
||||||
if (!result.success) return result;
|
|
||||||
|
|
||||||
const todos = result.data?.dados || [];
|
|
||||||
console.log(`🔍 CGNAT: ${todos.length} acessos retornados para o período`);
|
|
||||||
if (todos.length > 0) {
|
|
||||||
console.log(`🔍 CGNAT: campos do primeiro registro:`, Object.keys(todos[0]));
|
|
||||||
console.log(`🔍 CGNAT: amostra ip/estacao:`, todos.slice(0, 3).map(a => ({ ip: a.ip, estacao: a.estacao, usuario: a.usuario })));
|
|
||||||
}
|
|
||||||
|
|
||||||
const encontrados = todos.filter(a => a.ip === privateIP);
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
dados: encontrados,
|
|
||||||
total: encontrados.length,
|
|
||||||
totalGeral: todos.length,
|
|
||||||
instance: result.instance
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return { success: false, error: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Busca qual serviço está usando um IP privado CGNAT agora (conexões ativas)
|
|
||||||
* Usa ObterClientesServicos com conexao: "online" e filtra client-side pelo campo ip
|
|
||||||
*/
|
*/
|
||||||
async buscarConexaoAtivaPorIp(privateIP, location = '') {
|
async buscarConexaoAtivaPorIp(privateIP, location = '') {
|
||||||
if (!this.isReady()) {
|
if (!this.isReady()) {
|
||||||
@@ -1378,16 +1340,12 @@ class TopSappManager {
|
|||||||
try {
|
try {
|
||||||
const credentials = this.config.getCredentialsByLocation(location);
|
const credentials = this.config.getCredentialsByLocation(location);
|
||||||
const instance = this.api.getInstanceByLocation(location);
|
const instance = this.api.getInstanceByLocation(location);
|
||||||
const result = await this.api.obterConexoesAtivas(instance, credentials);
|
const result = await this.api.obterAcessos({ status: 'on' }, instance, credentials);
|
||||||
|
|
||||||
if (!result.success) return result;
|
if (!result.success) return result;
|
||||||
|
|
||||||
const todos = result.data?.dados || [];
|
const todos = result.data?.dados || [];
|
||||||
console.log(`🔍 CGNAT ativas: ${todos.length} conexões online retornadas`);
|
console.log(`🔍 CGNAT ativas: ${todos.length} sessões ativas retornadas`);
|
||||||
if (todos.length > 0) {
|
|
||||||
console.log(`🔍 CGNAT ativas: campos do primeiro registro:`, Object.keys(todos[0]));
|
|
||||||
console.log(`🔍 CGNAT ativas: amostra ip/usuario:`, todos.slice(0, 3).map(s => ({ ip: s.ip, usuario: s.usuario })));
|
|
||||||
}
|
|
||||||
|
|
||||||
const encontrados = todos.filter(s => s.ip === privateIP);
|
const encontrados = todos.filter(s => s.ip === privateIP);
|
||||||
return {
|
return {
|
||||||
@@ -1402,6 +1360,73 @@ class TopSappManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Busca qual sessão estava ativa num determinado horário (histórico).
|
||||||
|
* Como sessões encerradas têm ip:'', filtramos por janela de tempo:
|
||||||
|
* sessões que iniciaram antes do horário e encerraram depois (ou ainda ativas).
|
||||||
|
* @param {string} privateIP
|
||||||
|
* @param {string} dataInicial DD/MM/YYYY
|
||||||
|
* @param {string} dataFinal DD/MM/YYYY
|
||||||
|
* @param {string} horaRef HH:MM (opcional) — filtra sessões ativas naquele momento
|
||||||
|
* @param {string} location
|
||||||
|
*/
|
||||||
|
async buscarSessaoPorHorario(privateIP, dataInicial, dataFinal, horaRef = null, location = '') {
|
||||||
|
if (!this.isReady()) {
|
||||||
|
return { success: false, error: 'TopSapp não está configurado' };
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const credentials = this.config.getCredentialsByLocation(location);
|
||||||
|
const instance = this.api.getInstanceByLocation(location);
|
||||||
|
const params = {};
|
||||||
|
if (dataInicial) params.dataInicial = dataInicial;
|
||||||
|
if (dataFinal) params.dataFinal = dataFinal;
|
||||||
|
const result = await this.api.obterAcessos(params, instance, credentials);
|
||||||
|
|
||||||
|
if (!result.success) return result;
|
||||||
|
|
||||||
|
const todos = result.data?.dados || [];
|
||||||
|
console.log(`🔍 CGNAT histórico: ${todos.length} registros retornados para o período`);
|
||||||
|
|
||||||
|
// Sessões com IP preenchido (ativas durante o período)
|
||||||
|
const comIp = todos.filter(a => a.ip === privateIP);
|
||||||
|
|
||||||
|
// Se não achamos pelo IP (sessões encerradas têm ip:''), tentar por janela de tempo
|
||||||
|
// Sessões ativas no horário: inicio <= horaRef <= termino (ou termino vazio)
|
||||||
|
let porHorario = [];
|
||||||
|
if (horaRef && comIp.length === 0) {
|
||||||
|
const [hh, mm] = horaRef.split(':').map(Number);
|
||||||
|
const refTotalMin = hh * 60 + mm;
|
||||||
|
|
||||||
|
porHorario = todos.filter(a => {
|
||||||
|
if (!a.inicio) return false;
|
||||||
|
const inicioMatch = a.inicio.match(/(\d{2}):(\d{2})/);
|
||||||
|
if (!inicioMatch) return false;
|
||||||
|
const inicioMin = parseInt(inicioMatch[1]) * 60 + parseInt(inicioMatch[2]);
|
||||||
|
if (inicioMin > refTotalMin) return false; // ainda não havia iniciado
|
||||||
|
|
||||||
|
if (!a.termino) return true; // sessão ainda ativa
|
||||||
|
|
||||||
|
const terminoMatch = a.termino.match(/(\d{2}):(\d{2})/);
|
||||||
|
if (!terminoMatch) return true;
|
||||||
|
const terminoMin = parseInt(terminoMatch[1]) * 60 + parseInt(terminoMatch[2]);
|
||||||
|
return terminoMin >= refTotalMin;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const encontrados = comIp.length > 0 ? comIp : porHorario;
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
dados: encontrados,
|
||||||
|
total: encontrados.length,
|
||||||
|
totalGeral: todos.length,
|
||||||
|
modoFallback: comIp.length === 0 && porHorario.length > 0,
|
||||||
|
instance: result.instance
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: error.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = TopSappManager;
|
module.exports = TopSappManager;
|
||||||
Reference in new issue
Block a user