feat: initial commit

This commit is contained in:
root
2026-06-14 14:00:24 +08:00
commit 72d388f642
118 changed files with 39015 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
<?php
/**
* Cloudflare 域名自动化回归(CLI 输出 JSONMock HTTP
*/
$root = dirname(__DIR__);
require_once $root . '/cong.php';
require_once $root . '/lib/Cloak/DomainRepository.php';
require_once $root . '/lib/Cloak/CloudflareConfig.php';
require_once $root . '/lib/Cloak/CloudflareClient.php';
require_once $root . '/lib/Cloak/DomainProvisioningService.php';
class MockCloudflareClient extends CloudflareClient
{
public $zoneStatus = 'pending';
public $deleteCalled = false;
public $upsertCalls = [];
public function __construct()
{
}
public function createZone($hostname)
{
return [
'ok' => true,
'result' => [
'id' => 'zone_mock_' . md5($hostname),
'name_servers' => ['ada.ns.cloudflare.com', 'bob.ns.cloudflare.com'],
],
];
}
public function getZone($zoneId)
{
return [
'ok' => true,
'result' => [
'id' => $zoneId,
'status' => $this->zoneStatus,
'name_servers' => ['ada.ns.cloudflare.com', 'bob.ns.cloudflare.com'],
],
];
}
public function deleteZone($zoneId)
{
$this->deleteCalled = true;
return ['ok' => true, 'result' => ['id' => $zoneId]];
}
public function upsertARecord($zoneId, $fqdn, $ip, $proxied = true)
{
$this->upsertCalls[] = compact('zoneId', 'fqdn', 'ip', 'proxied');
return ['ok' => true, 'result' => ['id' => 'rec_' . md5($fqdn)]];
}
public function setSslFlexible($zoneId)
{
return ['ok' => true];
}
public function setAlwaysHttps($zoneId)
{
return ['ok' => true];
}
}
$tests = [];
$host = 'cf-mock-' . substr(md5((string) microtime(true)), 0, 8) . '.test';
try {
$pdo = DomainRepository::pdo();
DomainRepository::ensureTable($pdo);
// 未启用 CF:添加后 cf_status=local
CloudflareConfig::clearTestOverrides();
DomainProvisioningService::clearClientOverride();
$addLocal = DomainProvisioningService::provisionOnAdd($pdo, $host);
$rowLocal = DomainRepository::findById($pdo, (int) ($addLocal['id'] ?? 0));
$tests['add_local_cf_status'] = ($addLocal['ok'] ?? false) === true
&& ($addLocal['cf_status'] ?? '') === 'local'
&& ($rowLocal['cf_status'] ?? '') === 'local';
DomainRepository::deleteById($pdo, (int) $addLocal['id']);
// Mockpending_ns → ready
CloudflareConfig::setTestOverrides(['enabled' => true, 'server_ip' => '203.0.113.10']);
$mock = new MockCloudflareClient();
DomainProvisioningService::setClientOverride($mock);
$addCf = DomainProvisioningService::provisionOnAdd($pdo, $host);
$domainId = (int) ($addCf['id'] ?? 0);
$tests['add_cf_pending_ns'] = ($addCf['ok'] ?? false) === true
&& ($addCf['cf_status'] ?? '') === 'pending_ns'
&& count($addCf['nameservers'] ?? []) === 2;
$pending = DomainProvisioningService::checkAndProvision($pdo, $domainId);
$tests['check_pending_ns'] = ($pending['ok'] ?? false) === true
&& ($pending['status'] ?? '') === 'pending_ns';
$mock->zoneStatus = 'active';
$ready = DomainProvisioningService::checkAndProvision($pdo, $domainId);
$rowReady = DomainRepository::findById($pdo, $domainId);
$tests['check_ready'] = ($ready['ok'] ?? false) === true
&& ($ready['status'] ?? '') === 'ready'
&& ($rowReady['cf_status'] ?? '') === 'ready'
&& count($mock->upsertCalls) === 2;
$del = DomainProvisioningService::deleteWithCloudflare($pdo, $domainId);
$tests['delete_calls_zone'] = ($del['ok'] ?? false) === true && $mock->deleteCalled === true;
$tests['delete_row_gone'] = DomainRepository::findById($pdo, $domainId) === null;
} catch (Throwable $e) {
$tests['exception'] = false;
$tests['error'] = $e->getMessage();
} finally {
CloudflareConfig::clearTestOverrides();
DomainProvisioningService::clearClientOverride();
}
$ok = !in_array(false, $tests, true) && !isset($tests['error']);
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";