0, 'latest_version' => '1.4.8', 'min_version' => '1.4.0', 'force_update' => 1, 'notes' => '管理端配置字段无需暴露给下载页', 'packages' => [ 'windows_x64' => ['url' => 'https://cdn.example.test/doctor-setup.exe', 'sha256' => str_repeat('A', 64), 'size' => 123, 'filename' => 'doctor-setup.exe', 'type' => 'inno_setup'], 'macos_arm64' => ['url' => 'https://cdn.example.test/doctor-apple.zip', 'sha256' => str_repeat('b', 64), 'filename' => 'doctor-apple.zip'], 'macos_x64' => ['url' => '', 'sha256' => ''], ], ]; $catalog = DesktopWorkstationLogic::downloadCatalog($config); downloadExpect(array_keys($catalog) === ['version', 'packages'], 'catalog exposes only version and installer metadata'); downloadExpect($catalog['version'] === '1.4.8', 'latest published version is shown'); downloadExpect(array_column($catalog['packages'], 'platform') === ['windows_x64', 'macos_arm64'], 'only actually configured platforms are available'); downloadExpect($catalog['packages'][0]['sha256'] === str_repeat('a', 64), 'published hashes are normalized'); downloadExpect($catalog['packages'][0]['type'] === 'inno_setup', 'Windows installation type remains accurate'); downloadExpect(str_contains($catalog['packages'][0]['label'], 'Windows'), 'installer names explain which OS to choose'); downloadExpect(!isset($catalog['force_update']) && !isset($catalog['notes']), 'system settings are not part of the public download payload'); downloadExpect(count($catalog['packages']) === 2, 'turning off automatic updates does not remove first-install downloads'); foreach (['javascript:alert(1)', 'data:text/html,test', 'file:///tmp/setup.exe', '//cdn.example.test/setup.exe', 'https://user:password@cdn.example.test/setup.exe', 'https:///missing-host'] as $badUrl) { $invalid = $config; $invalid['packages'] = ['windows_x64' => ['url' => $badUrl, 'sha256' => str_repeat('a', 64)]]; downloadExpect(DesktopWorkstationLogic::downloadCatalog($invalid)['packages'] === [], 'unsafe or invalid download URL is not advertised'); } foreach (['', 'bad', str_repeat('g', 64), str_repeat('a', 63)] as $badHash) { $invalid = $config; $invalid['packages'] = ['windows_x64' => ['url' => 'https://cdn.example.test/setup.exe', 'sha256' => $badHash]]; downloadExpect(DesktopWorkstationLogic::downloadCatalog($invalid)['packages'] === [], 'unverified or incomplete uploads are not advertised'); } downloadExpect(DesktopWorkstationLogic::downloadCatalog([]) === ['version' => '', 'packages' => []], 'an unpublished package has an explicit empty state'); $controller = file_get_contents(dirname(__DIR__) . '/app/adminapi/controller/setting/DesktopWorkstationController.php'); downloadExpect(str_contains($controller, "public array \$notNeedLogin = ['check', 'downloads'];"), 'download listing is available without system configuration permissions'); downloadExpect(str_contains($controller, 'DesktopWorkstationLogic::downloads()'), 'public endpoint uses the existing published package source'); echo "Desktop workstation downloads: {$assertions} assertions passed\n";