'https://mx1.domena.pl:2222', 'MAIL_LOGIN_SSH_HOST' => 'mx1.domena.pl', 'MAIL_LOGIN_SSH_PORT' => '222', 'MAIL_LOGIN_SSH_USER' => 'root', 'MAIL_LOGIN_SSH_IDENTITY' => '/secure/key', 'MAIL_LOGIN_SSH_KNOWN_HOSTS' => '/secure/known_hosts', 'LOGIN_KEY_TTL' => '30', 'USER_IP_BOUND' => '1', ]); $request = new LoginUrlRequest('mxtest', 'h4.domena.pl', 'h4', 30, true, '198.51.100.10', '/', 1782810000); $command = RemoteLoginUrlClient::buildCommand($settings, $request); assert_same('ssh', $command[0]); assert_contains('UserKnownHostsFile=/secure/known_hosts', implode(' ', $command)); assert_contains('root@mx1.domena.pl', implode(' ', $command)); assert_not_contains('mail-login-create-url', implode(' ', $command)); assert_contains('/usr/bin/da login-url', implode(' ', $command)); assert_contains('--user=mxtest', implode(' ', $command)); assert_contains('--expiry=30s', implode(' ', $command)); assert_contains('--ip=198.51.100.10', implode(' ', $command)); }); test('remote login url client builds helper ssh command when mode is helper', function (): void { $settings = Settings::fromArray([ 'MAIL_LOGIN_TARGET_BASE_URL' => 'https://mx1.domena.pl:2222', 'MAIL_LOGIN_SSH_HOST' => 'mx1.domena.pl', 'MAIL_LOGIN_SSH_PORT' => '222', 'MAIL_LOGIN_SSH_USER' => 'root', 'MAIL_LOGIN_SSH_IDENTITY' => '/secure/key', 'MAIL_LOGIN_SSH_KNOWN_HOSTS' => '/secure/known_hosts', 'LOGIN_KEY_TTL' => '30', 'USER_IP_BOUND' => '1', 'MX_LOGIN_MODE' => '2', ]); $request = new LoginUrlRequest('mxtest', 'h4.domena.pl', 'h4', 30, true, '198.51.100.10', '/', 1782810000); $command = RemoteLoginUrlClient::buildCommand($settings, $request); assert_same('ssh', $command[0]); $pos = array_search('mail-login-create-url', $command, true); assert_true(is_int($pos), 'Command marker missing'); assert_same('mxtest', $command[$pos + 1]); assert_same('1', $command[$pos + 5]); assert_same('1782810000', $command[$pos + 8]); }); test('remote login url client omits expiry when ttl is zero', function (): void { $settings = Settings::fromArray([ 'MAIL_LOGIN_TARGET_BASE_URL' => 'https://mx1.domena.pl:2222', 'MAIL_LOGIN_SSH_HOST' => 'mx1.domena.pl', 'MAIL_LOGIN_SSH_IDENTITY' => '/secure/key', 'MAIL_LOGIN_SSH_KNOWN_HOSTS' => '/secure/known_hosts', 'LOGIN_KEY_TTL' => '0', ]); $request = new LoginUrlRequest('mxtest', 'h4.domena.pl', 'h4', 0, true, '198.51.100.10', '/', 1782810000); $command = RemoteLoginUrlClient::buildCommand($settings, $request); assert_not_contains('--expiry=', implode(' ', $command)); }); test('remote login url client validates helper output before returning it', function (): void { $settings = Settings::fromArray(['MAIL_LOGIN_TARGET_BASE_URL' => 'https://mx1.domena.pl:2222']); $request = new LoginUrlRequest('mxtest', 'h4.domena.pl', 'h4', 30, true, '198.51.100.10', '/', 1782810000); $client = new RemoteLoginUrlClient(function (array $command, int $timeout): ProcessResult { return new ProcessResult(0, "URL: https://mx1.domena.pl:2222/api/login/url?key=SECRET\n", ''); }); assert_same('https://mx1.domena.pl:2222/api/login/url?key=SECRET', $client->create($settings, $request)); $badClient = new RemoteLoginUrlClient(function (array $command, int $timeout): ProcessResult { return new ProcessResult(0, "https://evil.example/api/login/url?key=SECRET\n", ''); }); try { $badClient->create($settings, $request); throw new RuntimeException('Expected invalid helper URL to fail'); } catch (RuntimeException $e) { assert_contains('login url', strtolower($e->getMessage())); } }); test('remote login url client reports direct ssh failure diagnostics', function (): void { $settings = Settings::fromArray([ 'MAIL_LOGIN_TARGET_BASE_URL' => 'https://mx1.domena.pl:2222', 'MX_LOGIN_MODE' => '1', ]); $request = new LoginUrlRequest('mxtest', 'h4.domena.pl', 'h4', 30, true, '198.51.100.10', '/', 1782810000); $client = new RemoteLoginUrlClient(function (array $command, int $timeout): ProcessResult { return new ProcessResult(255, '', "Host key verification failed.\n"); }); try { $client->create($settings, $request); throw new RuntimeException('Expected direct ssh failure to fail'); } catch (RuntimeException $e) { assert_contains('MX direct SSH command failed', $e->getMessage()); assert_contains('exit 255', $e->getMessage()); assert_contains('Host key verification failed.', $e->getMessage()); } }); test('process runner returns stdout and exit code from real command', function (): void { $result = RemoteLoginUrlClient::runProcess(['php', '-r', 'echo "ok\n";'], 5); assert_same(0, $result->exitCode); assert_same("ok\n", $result->stdout); });