--- name: app-for-cloudflare description: Gestão da zona Cloudflare a partir do wp-admin via App for Cloudflare® (`app-for-cf`, Digital Point) — SSL/TLS, Speed, Caching, Network, Scrape Shield, Bot Management, Super Bot Fight Mode, WAF real via Managed Ruleset, HSTS, Certificate Transparency, Leaked Credential Checks, Turnstile CAPTCHA, R2 media storage, Zero Trust Access, Page/Cache Rules, DMARC, Web Analytics, ferramentas de diagnóstico (request trace/IP/domain/WHOIS), purge de cache, guest page caching a nível de edge. Usar quando "app for cloudflare", "cloudflare wordpress", "zona cloudflare", "waf cloudflare", "bot management", "super bot fight mode", "hsts cloudflare", "rocket loader", "certificate transparency", "leaked credential checks", "bots de ia cloudflare", "ai_bots_protection", "is_robots_txt_managed", "managed ruleset", "purge cache cloudflare", "turnstile", "cloudflare r2", "cloudflare access", "page rules cloudflare", "cache rules cloudflare", "dmarc cloudflare", "cfPageCachingSeconds", "cfTurnstile", "app_for_cf", ou qualquer alteração a definições de zona Cloudflare/config do plugin num site do bundle Descomplicar. --- # /app-for-cloudflare — Gestão de zona Cloudflare via App for Cloudflare® Plugin `app-for-cf` (Digital Point), versão `1.10.0` (`APP_FOR_CLOUDFLARE_VERSION`), instalado nos sites do bundle Descomplicar®. Não é um simples proxy visual — a maior parte das definições de "boas práticas" que o plugin lista **não vivem em `wp_options`**: são lidas e escritas directamente na **Cloudflare API v4**, usando um token scoped guardado numa única opção serializada. Confundir as duas camadas é o erro mais comum ao operar este plugin. **Fonte:** `CONFIG-Plugins-Referencia.md` §1 (App for Cloudflare®) e `BUNDLE-Excelencia-WP.md` §2.2 e §2.4 (GEO/bots de IA) — mapeamento inicial feito em `emanuelalmeida.pt` (16-08-2026), zona `574b243ebabd8ea2b8d89e68921f52cc`, plano **Free Website**. Expandido na mesma sessão com leitura completa do código-fonte (11.309 linhas em 61 ficheiros PHP, `wp-content/plugins/app-for-cf/`): `Repository/Cloudflare.php` (2178 linhas — `getSettingsToManage()`, `setEasyMode()`, `updateSettings()`), `Setup.php` (defaults de `wp_options`), `Admin/Template/Settings.php` (766 linhas — UI completa das 6 tabs), `Admin/Base/Admin.php` (estrutura das 14 páginas de menu), `Base/Pub.php` (657 linhas — guest page caching, purge, preload), `Helper/Api.php` (gate Free/Pro), `Cron/Jobs.php` e `Cli/PurgeCache.php` (automação de purge), e todos os 14 templates de página em `Admin/Template/`. --- ## 0. As duas camadas de config — não confundir | Camada | Onde vive | Como ler/escrever | Exemplos | |---|---|---|---| | **Config do plugin** (não é Cloudflare) | `wp_options.app_for_cf`, array PHP serializado, 18 chaves (ver §8) | `wp option get/patch` | `cfZoneId`, `cfAccountId`, `cloudflareAuth.token`, `cfPageCachingSeconds`, `cloudflarePreload`, `cfPurgeCacheOnAdminBar`, `cfTurnstile`, `cfProxy`, `cfR2Bucket` | | **Config de zona Cloudflare** (as ~52 "boas práticas" + Bot Management + WAF, ver §1) | **Na Cloudflare, não no WordPress** | API v4 (`https://api.cloudflare.com/client/v4`), bearer token = `cloudflareAuth.token` da opção acima | `ssl`, `security_header` (HSTS), `waf`, `bot_management`, `rocket_loader`, `cache_level`, `hotlink_protection`, etc. | Confirmado por leitura completa do código: **não existe** namespace WP REST próprio exposto pelo plugin (`app-for-cf` não aparece em `rest_api_init` em nenhum dos 61 ficheiros PHP) — todas as chamadas de configuração de zona são directas à Cloudflare API v4 a partir do backend PHP do plugin (`Api/Cloudflare.php`), usando o token guardado localmente. Para automatizar fora do wp-admin, replicar essa mesma chamada directa (`curl`/PHP) em vez de procurar um endpoint local que não existe. A opção `cloudflareAuth` suporta **dois modos de autenticação** (ver `Setup::defaults()`): `type: 'token'` (API token scoped, o único usado nos sites do bundle) ou o modo legado `email` + `api_key` (Global API Key — não usar, é o modo antigo e menos seguro da Cloudflare, mantido só por compatibilidade retroativa no plugin). ### Ler a config do plugin (wp-cli) ```bash PATH=/home/USER/public_html # Opção completa (JSON) wp option get app_for_cf --format=json --allow-root --path=$PATH # Uma sub-chave wp option pluck app_for_cf cfZoneId --allow-root --path=$PATH wp option pluck app_for_cf cfPageCachingSeconds --allow-root --path=$PATH # Editar uma sub-chave sem apagar as restantes (SEMPRE patch, nunca update, em opção serializada) wp option patch update app_for_cf cfPageCachingSeconds 21600 --allow-root --path=$PATH wp option patch update app_for_cf cloudflarePreload 1 --allow-root --path=$PATH ``` `cfProxy`, `cfR2Bucket`, `cloudflareAuth`, `cfTurnstile` são sub-arrays — `wp option patch` só edita um nível; para sub-arrays aninhados usar `wp eval` com `update_option()` sobre o array completo lido primeiro. ### Extrair o token para chamar a Cloudflare API directamente ```bash TOKEN=$(wp eval 'echo maybe_unserialize(get_option("app_for_cf"))["cloudflareAuth"]["token"];' --allow-root --path=$PATH) ZONE=$(wp eval 'echo maybe_unserialize(get_option("app_for_cf"))["cfZoneId"];' --allow-root --path=$PATH) curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ "https://api.cloudflare.com/client/v4/zones/$ZONE/settings" | jq . ``` --- ## 1. As definições de zona (por categoria) — lista completa do código Fonte: `Repository/Cloudflare.php::getSettingsToManage()` (linhas 88-721), a definição autoritativa usada pelo próprio plugin para desenhar a página de Settings e para `updateSettings()`. **Achado desta expansão:** o número "44" da auditoria original referia-se à contagem informal mostrada na UI (que agrupa alguns campos); a contagem real de entradas no array `getSettingsToManage()` é **52**. Lidas em bloco via `GET /zones/{zone}/settings` (a maioria) + endpoints individuais para os campos com `override_endpoint` (`security_header`, `certificate_transparency`, `leaked_credential_checks`, `bot_management`, `speed_brain`, `fonts`, `content_converter`, `origin_max_http_version`, `h2_prioritization`, `settings/nel`, `flags` para `crawlhints`, `argo/tiered_caching`). Escritas via `PATCH /zones/{zone}/settings/{setting_id}` com `{"value": ...}`, excepto onde a definição tem `overwrite_write_method` diferente (`PUT` para tudo em `bot_management`, `POST` para `leaked-credential-checks`/`ct/alerting`/`crawlhints`). | Categoria | Definições | |---|---| | **Topo (fora de secção)** | `development_mode` (bool, bom = `off`), `security_level` (select: `off`/`essentially_off`/`low`/`medium`/`high`/`under_attack`, bom = `essentially_off`) — mostradas no topo da página Settings, não numa tab | | **SSL/TLS** | `ssl` (modo de encriptação: `off`/`flexible`/`full`/`strict`/`origin_pull`), `always_use_https`, `security_header` (HSTS — ver §3), `min_tls_version` (`1.0`-`1.3`), `opportunistic_encryption`, `tls_1_3` (radio: `off`/`on`/`zrt` — zero round trip), `automatic_https_rewrites`, `ech` (Encrypted Client Hello), `certificate_transparency` (ver §4, `beta`), `tls_client_auth` | | **Segurança** | `waf` (toggle legado, **deprecated** — ver §2), `bot_fight_mode` (Bot Fight Mode básico — ver §5a), `ai_bots_protection`, `crawler_protection` (ambos geridos via `bot_management` PUT — ver §5a), `bot_likely_automated`, `bot_definitely_automated`, `bot_verified_bots`, `bot_static_resource_protection`, `bot_optimize_wordpress`, `bot_enable_js` (Super Bot Fight Mode — ver §5a), `leaked_credential_checks` (ver §4), `challenge_ttl` (select 5min-12meses, bom = 30min), `browser_check`, `replace_insecure_js` | | **Speed** | `polish` (select: `off`/`lossless`/`lossy`), `webp`, `speed_brain` (`beta`, substitui Rocket Loader/Mirage antigos), `fonts` (`beta`, Cloudflare Fonts — serve Google Fonts a partir do edge), `early_hints`, `rocket_loader` (deprecated para segurança — ver §2), `content_converter` (`beta`), `http2`, `origin_max_http_version` (int, bom = `2`), `http3`, `h2_prioritization`, `0rtt` (TLS 1.3 zero round trip) | | **Caching** | `cache_level` (radio: `basic`/`simplified`/`aggressive`, bom = `aggressive`), `browser_cache_ttl` (select 0-12meses, `0` = respeitar headers de origem), `crawlhints` (`beta`, indica a crawlers quando o conteúdo mudou), `always_online`, `tiered_caching` (Argo Tiered Cache) | | **Network** | `ipv6`, `websockets`, `pseudo_ipv4` (select: `off`/`add_header`/`overwrite_header`), `ip_geolocation`, `max_upload` (select 100-500MB), `nel` (Network Error Logging, `value.enabled` aninhado), `opportunistic_onion` | | **Scrape Shield** | `email_obfuscation`, `hotlink_protection` | ```bash # Ler uma definição individual curl -s -H "Authorization: Bearer $TOKEN" \ "https://api.cloudflare.com/client/v4/zones/$ZONE/settings/rocket_loader" | jq . # Escrever uma definição individual (formato standard "value") curl -s -X PATCH -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ "https://api.cloudflare.com/client/v4/zones/$ZONE/settings/rocket_loader" \ -d '{"value":"off"}' | jq . ``` `webp`, `content_converter`, `speed_brain`, `fonts`, `crawlhints`, `tiered_caching` e outros podem estar **plan-locked** (não editáveis no plano Free Website) — a API devolve o valor actual mas ignora tentativas de escrita; não é bug, é limite de plano. A UI do plugin marca isto lendo `editable` do resultado da API (ver `override_result_editable_if_has` no código) e desactiva o `