Files
fitme3070.pt/shared/platform-tools/functions_routes.php
T
andreandClaude Opus 5.5 0e8b53f620 feat(audit): platform-tools atualizado (12f26fd) e registo de auditoria ligado
- shared/platform-tools: ea3616a → 12f26fd (27 commits). Traz o módulo de
  audit (f761d99, o pin da frota), «manter sessão iniciada», o registo de
  segurança da frota (o gancho que o login já tinha passa a funcionar) e a
  correção do IP do cliente encontrada nesta auditoria (último X-Forwarded-For
  / X-Real-IP), promovida ao partilhado. client_ip() da app delega nele.
- config/functions_audit.php: audit() sobre platform_audit(); tabela
  audit_log criada no primeiro uso, segredos ocultados, nunca parte a ação.
- Registado: login, falha de login, bloqueio por excesso de tentativas,
  logout, pedidos de recuperação, mudança/definição de palavra-passe,
  registo e criação de utilizadores, convites, perfil (antes/depois), todas
  as definições (db_update_setting, com valor anterior), cada passo da
  lixeira (apagar, restaurar, eliminar de vez) e ações nas mensagens.
- Sistema → Auditoria (views/sysadmin/audit.php), só sysadmin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:28:13 +01:00

106 lines
4.8 KiB
PHP

<?php
// ─── Rotas do front controller (router.php) ─────────────────────────────────
//
// A lista fechada de páginas partilhadas que o platform.php de um site serve.
// Uma ferramenta nova entra aqui e aparece em todos os sites que usam o router
// no próximo update do submódulo.
//
// file a página, relativa a este directório
// needs_db sem base de dados (montra estática) responde 503 explicado
// backup_helpers carrega os helpers de cópias antes (o que os stubs faziam
// com require config/functions_backup.php)
function platform_routes(): array {
return [
'index' => ['file' => 'index.php'],
'platform_update' => ['file' => 'platform_update.php'],
'backups' => ['file' => 'backups.php', 'needs_db' => true, 'backup_helpers' => true],
'restore' => ['file' => 'restore.php', 'needs_db' => true, 'backup_helpers' => true],
'ip_bans' => ['file' => 'ip_bans.php', 'needs_db' => true],
'geo' => ['file' => 'geo.php'],
'tracking' => ['file' => 'tracking.php', 'needs_db' => true],
'hub_integration' => ['file' => 'hub_integration.php'],
'smtp_status' => ['file' => 'smtp_status.php', 'needs_db' => true],
'audit' => ['file' => 'audit.php', 'needs_db' => true],
];
}
/**
* Os endpoints partilhados que o public/api/platform.php de um site serve
* (api/router.php). Cada um continua a autenticar-se a si próprio — chave de
* saúde, chave de operações, HMAC, sessão + CSRF —; o router só despacha.
*
* Os URLs antigos (api/health.php, api/hub_ops.php, …) ficam onde estão: os
* webhooks do Gitea e os caminhos que o hub guarda por plataforma apontam para
* eles. Um endpoint NOVO entra só aqui e chega a todos os sites sem stub.
*/
function platform_api_routes(): array {
return [
'health' => 'api/hub_health.php',
'hub_ops' => 'api/hub_ops.php',
'hub_pair' => 'api/hub_pair.php',
'feedback' => 'api/feedback.php',
'agent' => 'api/agent.php',
'auto_update' => 'api/auto_update.php',
'backup_trigger' => 'api/backup_trigger.php',
'backup_download' => 'api/backup_download.php',
];
}
/** O site declarou `'router' => true` no platform_connect() (tem o public/platform.php). */
function platform_router_enabled(): bool {
return function_exists('platform_config') && !empty(platform_config()['router']);
}
/**
* URLs sem `.php`? Só quando o site o declara (`'clean_urls' => true`), porque
* precisa da regra do .htaccess que serve `/platform` a partir de
* `platform.php` — sem ela, o URL limpo dava 404.
*/
function platform_clean_urls(): bool {
return function_exists('platform_config') && !empty(platform_config()['clean_urls']);
}
/** URL de uma ferramenta pelo router; $query sem o `?` (p. ex. 'tab=db'). */
function platform_route_url(string $tool, string $query = ''): string {
$script = platform_clean_urls() ? 'platform' : 'platform.php';
$path = $script . '?tool=' . rawurlencode($tool) . ($query !== '' ? '&' . ltrim($query, '?&') : '');
return platform_route_absolute_url($path);
}
/** URL de um endpoint pelo router da API. */
function platform_api_url(string $endpoint, string $query = ''): string {
$script = platform_clean_urls() ? 'api/platform' : 'api/platform.php';
$path = $script . '?endpoint=' . rawurlencode($endpoint) . ($query !== '' ? '&' . ltrim($query, '?&') : '');
return platform_route_absolute_url($path);
}
/** Um caminho relativo ao base_url passa a absoluto; um URL ou caminho absoluto fica. */
function platform_route_absolute_url(string $url): string {
if ($url === '' || preg_match('#^([a-z][a-z0-9+.-]*:)?//#i', $url) || $url[0] === '/') return $url;
if (function_exists('base_url')) return (string) base_url($url);
if (function_exists('hub_base_url')) return hub_base_url($url);
return '/' . $url;
}
/**
* As ferramentas que este site serve, com o URL de cada uma — anunciadas no
* health para o hub poder ligar para a página local. [] sem router: os stubs
* antigos variam de site para site, e anunciar um URL que dá 404 é pior do que
* não anunciar.
*/
function platform_routes_announced(): array {
if (!platform_router_enabled()) return [];
$out = [];
foreach (array_keys(platform_routes()) as $tool) $out[$tool] = platform_route_url($tool);
return $out;
}
/** O mesmo para os endpoints, com a mesma condição. */
function platform_api_routes_announced(): array {
if (!platform_router_enabled()) return [];
$out = [];
foreach (array_keys(platform_api_routes()) as $endpoint) $out[$endpoint] = platform_api_url($endpoint);
return $out;
}