--- name: Painel Cliente agenciahost (2026-05-04) description: Sistema CI4 de gestão e cobrança de hospedagem em agenciahost.com/cliente, banco agencia_painel (WHMCS legacy), liberação de IP no firewall via helper bash type: project originSessionId: 4fcacab0-14f5-48d4-9ca9-322e9af89c9f --- # Painel Cliente agenciahost - MVP Fase 1 (2026-05-04) Painel CI4 + MVC para gestão e cobrança de clientes de hospedagem. Substitui WHMCS antigo (banco `agencia_painel`). ## URLs - **Produção:** `https://agenciahost.com/cliente/` - **Admin login:** `admin@agenciahost.com` / `AgenciaHost@2026` (resetada 2026-05-04, trocar depois) - **Local dev:** `D:\xampp\htdocs\painel-agencia\` ## Stack - **Backend:** CodeIgniter 4 + PHP 8.1.34 - **Frontend:** Tailwind CSS local (build via /usr/local/bin/tailwindcss em `cliente/public/assets/css/tailwind.css`) + JS vanilla. NÃO usa CDN. - **Banco:** MariaDB 10.6, schema `agencia_painel` (WHMCS legacy 369 clientes, 1324 faturas, 1100+ pagamentos, 831 tickets) ## Servidor produção - **Path:** `/home/agencia/public_html/cliente/` (user cPanel: `agencia`) - **PHP vhost:** ea-php81 (mesmo da agenciahost.com) - **MySQL user dedicado:** `agencia_painelapp` — senha em `/root/painel-cliente-credentials.txt` (chmod 600). Permissão SELECT em `agencia_painel.*` + INSERT/UPDATE/DELETE só em `painel_unblock_log`. - **Helper unblock IP:** `/usr/local/bin/painel-unblock.sh` (root, valida IP, executa `csf -dr` + `imunify360-agent ip-list local delete --purpose drop|captcha|splashscreen` + `csf -ta 1h`). - **Sudoers:** `/etc/sudoers.d/agencia-painel` permite user `agencia` rodar o helper sem senha. ## Tabela log ```sql agencia_painel.painel_unblock_log - id, client_id, client_email (formato 'admin:email' ou 'client:email'), ip, unblocked_at, user_agent, result_csf, result_imunify ``` ## Funcionalidades (Fase 1) **Cliente** (login `tblclients` ATIVO + senha bcrypt): - Dashboard: ver IP, liberar IP, hospedagens, faturas em aberto - /conta, /conta/hospedagens, /conta/faturas, /conta/faturas/{id} - Rate limit: 5 unblocks/24h **Admin** (login `tbladmins` não disabled): - /admin: stats (clientes ativos, hospedagens, faturas em aberto/pagas) - /admin/clientes (lista + busca), /admin/clientes/{id} (detalhe) - /admin/faturas (com filtro status), /admin/hospedagens, /admin/unblocks - Sem rate limit ## Pegadinhas resolvidas no setup 1. **`/home/agencia/public_html/.htaccess` parent tem lockdown** ` Require all denied ` — colocado em 30/Abr (incidente CVE-2026-41940). Override via `Require all granted` no `.htaccess` do `cliente/`. 2. **`session.savePath = null`** no .env era lido como string literal "null" → CI4 tentava `touch('null/ci_session_xxx')`. Fix: setar path absoluto. 3. **`zlib.output_compression`** ativo no PHP do servidor → CI4 abortava. Fix: `.user.ini` no `cliente/` com `zlib.output_compression = Off`. 4. **`vendor/composer/autoload_files.php`** referenciava phpunit (excluí no tar). Fix: `composer install --no-dev --optimize-autoloader` no servidor. 5. **CDN Tailwind (`cdn.tailwindcss.com`)** ficava travado no Chrome do user (Safe Browsing pós-incidente). Fix: build local via `tailwindcss-linux-x64 v3.4.17` em `/usr/local/bin/tailwindcss`, output em `cliente/public/assets/css/tailwind.css` (214 KB). 6. **Trailing slash** redirect 301 do `public/.htaccess` expunha `/cliente/public/admin` na URL. Fix: comentei o "Redirect Trailing Slashes" do `public/.htaccess` + adicionei rewrite de trailing slash 302 no `cliente/.htaccess`. 7. **Pasta `painel/` no servidor** foi criada inicialmente vazia (403). Migrada para `cliente/` por preferência do user. ## Estrutura de pastas ``` /home/agencia/public_html/cliente/ ├── .env (CI_ENVIRONMENT=production, baseURL https://agenciahost.com/cliente/) ├── .htaccess (rewrite + Require all granted override) ├── .user.ini (zlib.output_compression = Off) ├── app/ (Controllers/Models/Views/Filters/Helpers/Config) ├── public/ │ ├── index.php (entry CI4) │ ├── .htaccess (CI4 default - trailing slash redirect comentado) │ └── assets/css/tailwind.css (Tailwind compilado, 214 KB) ├── system/ (CI4 framework) ├── vendor/ (composer install --no-dev) └── writable/ ├── cache/, debugbar/, logs/, session/, uploads/ ``` ## Quarentena de backdoors da agencia `/home/agencia/QUARANTINE-2026-05-04/` — 3 ajax.php do uploader (md5 `d5b525d863483437e2d0809c93c9e2cd`) movidos: `public_html/ajax.php`, `api/ajax.php`, `teste/ajax.php`. ## Roadmap - ✅ **Fase 1** (MVP): login, dashboard, liberação de IP, listagens read-only — entregue 2026-05-04 - ✅ **Fase 2** (CRUD admin): cria/edita cliente, hospedagem, fatura (com itens dinâmicos JS); marca paga/cancelada/reabre; suspende/reativa cliente; reset senha — entregue 2026-05-04. - ✅ **Fase 3** (cobrança + suporte + segurança) — entregue 2026-05-04: - **PayPal REST API** (Orders v2): `app/Libraries/PayPalApi.php`, `app/Controllers/Pagar.php` (botão pagar fatura → redirect → captura → marca paga), `Webhook` (POST `/pagar/webhook`), tela admin `/admin/gateways` pra colar Client ID + Secret. **NÃO usa Sicoob** (preferência do usuário). MercadoPago alternativa pendente. - **Tickets** completos: lista/abrir/responder/status (cliente + admin), reaproveita `tbltickets`/`tblticketreplies`/`tblticketdepartments` do WHMCS (3 deps: Suporte/Financeiro/Vendas). - **Hospedagem detalhe cliente** (`/conta/hospedagens/{id}`): dados completos + botão **"Abrir cPanel"** via SSO (`whmapi1 create_user_session` via helper bash root) + **solicitação de cancelamento** (tipo imediato/fim período + motivo). - **Cancelamentos** (admin): `/admin/cancelamentos` lista pendentes, aprovar (encerra hospedagem) ou rejeitar. - **Segurança hardened**: rate limit login (5 falhas/15min por IP **e** por e-mail) + log em `painel_login_log` + HSTS/X-Frame-Options DENY/X-Content-Type-Options/Referrer-Policy/Permissions-Policy + HTTPS forçado (redirect 301) + cookie secure/httponly/samesite=Strict + CSRF global + delays anti-brute-force. - **Helper bash novo**: `/usr/local/bin/painel-cpanel-sso.sh` (root, valida `[a-z][a-z0-9_-]{0,15}`, executa `whmapi1 create_user_session user=$user service=cpaneld`). Sudoers: `agencia` user pode executar via sudo sem senha. - **Tabelas novas**: `painel_login_log`, `painel_gateways`, `painel_pagamentos`, `painel_cancel_requests` (no banco `agencia_painel`, com permissões INSERT/UPDATE/DELETE pro user `agencia_painelapp`). - **index.html da agenciahost.com**: botão "Acessar Área do Cliente" (gradient indigo/violet) na página de manutenção. - **Composer**: adicionado `chillerlan/php-qrcode` (pra futuro QR PIX se quiser PayPal Brasil/MP). - **Pendências para finalizar Fase 3:** - Usuário precisa criar app no `developer.paypal.com/dashboard/applications/live`, copiar Client ID + Secret e colar em `/admin/gateways` (form pronto). - **NÃO foi possível decriptar** os dados antigos do PayPal Classic (NVP/SOAP) do `tblpaymentgateways` — sem `cc_encryption_hash` do WHMCS legado em `/home/agencia/.trash/hostrwhmcs.zip` (zip só tem templates, não tem `configuration.php`). - **Fase 4** (futura): cron de cobrança automática (3d antes/vence hoje/atrasada via WhatsApp+e-mail), NFSe, MercadoPago alternativo, provisionamento WHM API criar/suspender/terminar conta cPanel.