Skip to content

Latest commit

 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GLPI Messenger

Mensagens instantâneas entre usuários do GLPI 10.

Chat flutuante em qualquer página, página completa de conversas, anexos, reações, indicador de digitação, confirmação de leitura e notificações — sem depender de serviço externo.


Requisitos

Item Versão
GLPI 10.0.0 – 11.0.x
PHP 7.4+ (extensão fileinfo obrigatória)
Banco MySQL 5.7+ / MariaDB 10.3+

O diretório files/_plugins (GLPI_PLUGIN_DOC_DIR) precisa ter permissão de escrita — é onde os anexos são gravados.


Instalação

  1. Copie a pasta messenger para glpi/plugins/.
  2. Em Configurar → Plugins, instale e ative o Messenger.
  3. Ajuste as opções em Configurar → Plugins → Messenger (ícone de engrenagem).

Atualizando da versão 1.x

A instalação detecta o esquema antigo e migra automaticamente, preservando todo o histórico de mensagens:

  • glpi_plugin_messengerglpi_plugin_messenger_messages
  • sender_idusers_id_sender, receiver_idusers_id_recipient, messagecontent, datedate_creation
  • as foreign keys da v1 são removidas (impediam a migração em alguns MySQL)
  • índices novos são criados para as consultas de conversa e de não lidas

Anexos antigos continuam acessíveis, mas agora exigem login. O diretório uploads/ da v1 recebe um .htaccess que bloqueia acesso HTTP direto.

Os endpoints antigos (send_message.php, check_new_messages.php, etc.) continuam existindo como camada de compatibilidade — já corrigidos.


Funcionalidades

  • Chat flutuante em qualquer página do GLPI (até 5 conversas simultâneas)
  • Página completa em Ferramentas → Messenger (lista de conversas + histórico)
  • Painel de contatos no botão flutuante, com busca
  • Histórico paginado (rolagem infinita para cima)
  • Anexos com validação de extensão e de conteúdo real (MIME)
  • Reações com emoji, editar (15 min) e excluir mensagem
  • "Está digitando", presença online e confirmação de leitura
  • Contador de não lidas no botão e no título da aba
  • Notificação do navegador e som quando a aba está em segundo plano
  • Tema claro/escuro do GLPI 10 e layout responsivo
  • Limpeza automática via tarefa agendada (retenção configurável)

Configuração

Configurar → Plugins → Messenger

Opção Padrão Observação
Intervalo de verificação 4000 ms limitado entre 2 s e 60 s
Liberar chat para todos os usuários Sim se "Não", exige direito de leitura em Usuários
Permitir anexos Sim
Tamanho máximo por anexo 10 MB limitado a 100 MB
Extensões permitidas jpg, png, pdf, docx, xlsx… extensões executáveis são sempre bloqueadas
Permitir editar / excluir Sim edição válida por 15 minutos
Permitir reações Sim conjunto fechado de 7 emojis
Notificações / som Sim apenas com a aba em segundo plano
Ícone de chat nos atores Sim ticket, ficha de usuário
Excluir mensagens após N dias 0 (nunca) executado pela tarefa messengerCleanup

O intervalo de verificação não precisa ser agressivo: apenas uma aba consulta o servidor e distribui o resultado para as outras via BroadcastChannel.


Arquitetura

setup.php                 hooks, versão, pré-requisitos
hook.php                  instalação, migração 1.x → 2.x, desinstalação
config.php                compatibilidade v1 (configuração agora vive no banco)
download.php              compatibilidade v1 (redireciona para front/download.php)

inc/api.class.php         base dos endpoints: auth, CSRF, JSON, lock de sessão
inc/config.class.php      configuração + formulário
inc/user.class.php        contatos, visibilidade por entidade, nome de exibição
inc/message.class.php     envio, histórico, polling, leitura, edição, cron
inc/attachment.class.php  upload validado, autorização, limpeza de órfãos
inc/reaction.class.php    reações (lista fechada de emojis)
inc/presence.class.php    online e "está digitando"
inc/messenger.class.php   shim depreciado da classe da v1

ajax/bootstrap.php        usuário, configuração e cursor inicial
ajax/contacts.php         lista de contatos
ajax/history.php          histórico paginado
ajax/poll.php             polling incremental (mensagens, leitura, digitando)
ajax/send.php             envio
ajax/read.php             marcar como lida
ajax/react.php            reação
ajax/message.php          editar / excluir
ajax/typing.php           heartbeat de digitação
ajax/upload.php           upload de anexo

front/messenger.php       página completa
front/download.php        entrega autenticada de anexos
front/config.form.php     página de configuração

scripts/messenger.js      front-end completo (sem dependências)
css/messenger.css         tema claro/escuro, responsivo

Tabelas

Tabela Conteúdo
glpi_plugin_messenger_messages mensagens (texto puro)
glpi_plugin_messenger_attachments anexos (arquivo fora do webroot)
glpi_plugin_messenger_reactions reações
glpi_plugin_messenger_presences presença e digitação (1 linha por usuário)
glpi_plugin_messenger_configs configuração (1 linha)

Segurança

Correções em relação à versão 1.x:

Problema na v1 Situação atual
upload_attachment.php aceitava upload sem autenticação e gravava dentro do webroot sessão + CSRF obrigatórios; arquivo gravado em GLPI_PLUGIN_DOC_DIR, nome aleatório
download.php servia qualquer arquivo sem autenticação exige login e participação na conversa; mesma resposta 404 para inexistente e sem permissão
sender_id vinha do cliente — dava para enviar mensagem no nome de outro usuário remetente sempre da sessão
receiver_id vinha do cliente em mark_messages_read.php — dava para marcar mensagens de terceiros destinatário sempre da sessão
conteúdo com HTML era injetado via innerHTML (XSS armazenado) conteúdo é texto puro; DOM montado com textContent; links criados como nós <a> validados
get_user_list.php expunha e-mail, telefone e grupo de todos os usuários, ignorando permissões apenas id, nome e foto, restrito às entidades visíveis
sem CSRF nas escritas cabeçalho customizado obrigatório + Sec-Fetch-Site + token do GLPI rotativo
sem limite de envio 30 mensagens/minuto por sessão
extensão validada, conteúdo não extensão + MIME real coerentes; lista negra de executáveis; extensão dupla rejeitada
onclick inline em HTML gerado delegação de eventos (compatível com CSP)

Anexos são servidos com X-Content-Type-Options: nosniff, Content-Security-Policy: default-src 'none'; sandbox e apenas imagens e PDF podem abrir inline — o resto é sempre download.


Performance

Antes Agora
polling a cada 1,5 s retornando todas as não lidas intervalo configurável, cursor incremental (só o que mudou)
MutationObserver disparava um fetch da lista completa de usuários a cada alteração do DOM observer com debounce e zero requisições
sessão do PHP travada durante o polling, serializando toda a navegação Session::writeClose() nos endpoints de leitura
cada aba consultava o servidor uma aba "líder" consulta e distribui via BroadcastChannel
sem backoff em erro backoff exponencial, pausa quando a aba está oculta ou o usuário está inativo
SELECT sem índice de conversa índices conversation e unread
N+1 para anexos e reações 2 consultas agregadas por página de mensagens

Solução de problemas

O chat não aparece. Verifique se o plugin está ativo e se o usuário atende a "Liberar chat para todos os usuários". Abra o console do navegador: mensagens do plugin começam com [messenger].

"Token CSRF ausente". A página foi carregada antes da ativação do plugin. Recarregue com Ctrl+F5.

Anexo não envia. Confira upload_max_filesize e post_max_size no PHP, a permissão de escrita em files/_plugins/messenger e se a extensão está na lista permitida.

Mensagens antigas sem data. A v1 permitia date nulo; a instalação preenche esses registros com a data da migração.


Licença

GPLv3.

Autor original: R&M. Reescrita 2.0 mantendo compatibilidade de dados.

About

Mensageiro interno do GLPI

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages