import Select from "@/common/Select"; import TransitionWrapper from "@/common/TransitionWrapper"; import Button from "@/components/Button"; import Card, { CardContent, CardHeader } from "@/components/Card"; import Notice from "@/components/Notice"; import PageContent from "@/layout/PageContent"; import { CF_AUTH_MODES, LINKS } from "@/lib/constants"; import { useSettingsStore } from "@/store/optionsStore"; import { useAppStore } from "@/store/store"; import { ExternalLinkIcon, Globe, Wifi, WifiOff, Wrench } from "lucide-react"; import ApiKeyForm from "./cloudflare/ApiKeyForm"; import ApiTokenForm from "./cloudflare/ApiTokenForm"; import ManagedSettingNotice from "./cloudflare/ManagedSettingNotice"; import ZoneIdConnect from "./cloudflare/ZoneIdConnect"; import { useConnectionStore } from "./cloudflare/connectionStore"; import { cn } from "@/lib/utils"; import { createInterpolateElement, useEffect, useState } from "@wordpress/element"; import { __ } from "@wordpress/i18n"; import ControlsGroup from "../controls/ControlsGroup"; import Separator from "@/common/Separator"; import ExternalLink from "@/common/ExternalLink"; import { spcApi } from "@/lib/api"; import { toast } from "sonner"; const CF_AUTH_MODE_OPTIONS = [ { label: __('API Key', 'wp-cloudflare-page-cache'), value: CF_AUTH_MODES.API_KEY.toString() }, { label: `${__('API Token', 'wp-cloudflare-page-cache')} (${__('Recommended', 'wp-cloudflare-page-cache')})`, value: CF_AUTH_MODES.API_TOKEN.toString() } ]; const ConnectionError = () => { const { errorMessage } = useConnectionStore(); if (!errorMessage) { return null; } const errAsArray = errorMessage.split(':'); let errorHeader = __('Connection Failed:', 'wp-cloudflare-page-cache'); // Use whatever is after the first `:` but include subsequent text. let displayMessage = <>{errAsArray.slice(1).join(':').trim()}>; if (errorMessage === 'permission_error') { errorHeader = __('Permission Error:', 'wp-cloudflare-page-cache'); displayMessage = createInterpolateElement(__('Please make sure you grant the token permissions as outlined in this documentation.', 'wp-cloudflare-page-cache'), { a: }) } return ( {errorHeader} {displayMessage} ) } const Cloudflare = () => { const { homeURL, ruleNeedsRepair, i18n } = window.SPCDash; const { alreadyOnCloudflare, setAlreadyOnCloudflare, cloudflareCheckDone, setCloudflareCheckDone, } = useConnectionStore(); const { asyncLocked, lockAsync, } = useAppStore(); const { cloudflareConnected, settings, isSettingOverridden, } = useSettingsStore(); const [authMode, setAuthMode] = useState(parseInt(settings.cf_auth_mode as string)); const authModeManaged = isSettingOverridden('cf_auth_mode'); const checkCloudflare = async () => { const response = await fetch(`${homeURL}/cdn-cgi/trace`); setCloudflareCheckDone(true); if (!response.ok || response.status !== 200) { return; } const text = await response.text(); if (text.includes('h=') && text.includes('ip=')) { setAlreadyOnCloudflare(true); return; } }; useEffect(() => { if (cloudflareCheckDone) { return; } checkCloudflare(); }, []); const displayAccountCreationNotice = !alreadyOnCloudflare && !cloudflareConnected && !settings.cf_zoneid_list; const hasZoneIDList = !!settings.cf_zoneid_list && Object.keys(settings.cf_zoneid_list).length > 0; const [isRepairingRule, setIsRepairingRule] = useState(false); const fixCacheRule = async () => { lockAsync(true); setIsRepairingRule(true); const response = await spcApi.repairCloudflareRule(); if (response.success) { toast.success(response.message, { description: __('Page will reload in a few seconds.', 'wp-cloudflare-page-cache'), }); setTimeout(() => { window.location.reload(); }, 3000); return; } setIsRepairingRule(false); lockAsync(false); toast.error(response.message, { description: __('Something went wrong. Please reload the page and try again. If the issue persists, disconnect and reconnect your Cloudflare account.', 'wp-cloudflare-page-cache'), }); } return ( {ruleNeedsRepair && ( {isRepairingRule ? __('Fixing Rule', 'wp-cloudflare-page-cache') + '...' : __('Fix Rule', 'wp-cloudflare-page-cache')} )} {cloudflareConnected ? : } {__('Cloudflare Connection', 'wp-cloudflare-page-cache')} {__('Connect your Cloudflare account to enable CDN features', 'wp-cloudflare-page-cache')} {!hasZoneIDList && ( {displayAccountCreationNotice && ( {__('Sign up for free', 'wp-cloudflare-page-cache')} )} {__('Authentication Mode', 'wp-cloudflare-page-cache')} { setAuthMode(parseInt(v)); }} options={CF_AUTH_MODE_OPTIONS} /> {__('API Tokens are more secure and provide better control over permissions', 'wp-cloudflare-page-cache')} {authMode === CF_AUTH_MODES.API_KEY && ( )} {authMode === CF_AUTH_MODES.API_TOKEN && ( )} )} {hasZoneIDList && ( )} {(cloudflareConnected && {__('Serve cached files from Cloudflare using Cache Rule.', 'wp-cloudflare-page-cache')} {' '} {__('More Info', 'wp-cloudflare-page-cache')} >, hide: !cloudflareConnected, }, ]} />)} ) } export default Cloudflare;
{__('Connect your Cloudflare account to enable CDN features', 'wp-cloudflare-page-cache')}
{__('API Tokens are more secure and provide better control over permissions', 'wp-cloudflare-page-cache')}