|
1 | 1 | import { Command } from 'commander'; |
2 | | -import { parseEnvironmentVariables, parseDomains, parseDomainsFile, escapeShellArg, joinShellArgs, parseVolumeMounts, isValidIPv4, isValidIPv6, parseDnsServers, parseDnsOverHttps, validateAgentImage, isAgentImagePreset, AGENT_IMAGE_PRESETS, processAgentImageOption, processLocalhostKeyword, validateSkipPullWithBuildLocal, validateAllowHostPorts, parseMemoryLimit, validateFormat, validateApiProxyConfig, buildRateLimitConfig, validateRateLimitFlags, hasRateLimitOptions, collectRulesetFile, validateApiTargetInAllowedDomains, DEFAULT_OPENAI_API_TARGET, DEFAULT_ANTHROPIC_API_TARGET, DEFAULT_COPILOT_API_TARGET, emitApiProxyTargetWarnings, formatItem, program, parseAgentTimeout, applyAgentTimeout, handlePredownloadAction, resolveApiTargetsToAllowedDomains, extractGhesDomainsFromEngineApiTarget } from './cli'; |
| 2 | +import { parseEnvironmentVariables, parseDomains, parseDomainsFile, escapeShellArg, joinShellArgs, parseVolumeMounts, isValidIPv4, isValidIPv6, parseDnsServers, parseDnsOverHttps, validateAgentImage, isAgentImagePreset, AGENT_IMAGE_PRESETS, processAgentImageOption, processLocalhostKeyword, validateSkipPullWithBuildLocal, validateAllowHostPorts, parseMemoryLimit, validateFormat, validateApiProxyConfig, buildRateLimitConfig, validateRateLimitFlags, hasRateLimitOptions, collectRulesetFile, validateApiTargetInAllowedDomains, DEFAULT_OPENAI_API_TARGET, DEFAULT_ANTHROPIC_API_TARGET, DEFAULT_COPILOT_API_TARGET, emitApiProxyTargetWarnings, formatItem, program, parseAgentTimeout, applyAgentTimeout, handlePredownloadAction, resolveApiTargetsToAllowedDomains, extractGhesDomainsFromEngineApiTarget, extractGhecDomainsFromServerUrl } from './cli'; |
3 | 3 | import { redactSecrets } from './redact-secrets'; |
4 | 4 | import * as fs from 'fs'; |
5 | 5 | import * as path from 'path'; |
@@ -2216,6 +2216,125 @@ describe('cli', () => { |
2216 | 2216 | }); |
2217 | 2217 | }); |
2218 | 2218 |
|
| 2219 | + describe('extractGhecDomainsFromServerUrl', () => { |
| 2220 | + it('should return empty array when no env vars are set', () => { |
| 2221 | + const domains = extractGhecDomainsFromServerUrl({}); |
| 2222 | + expect(domains).toEqual([]); |
| 2223 | + }); |
| 2224 | + |
| 2225 | + it('should return empty array when GITHUB_SERVER_URL is github.com', () => { |
| 2226 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_SERVER_URL: 'https://github.com' }); |
| 2227 | + expect(domains).toEqual([]); |
| 2228 | + }); |
| 2229 | + |
| 2230 | + it('should return empty array for GHES (non-ghe.com) server URL', () => { |
| 2231 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_SERVER_URL: 'https://github.mycompany.com' }); |
| 2232 | + expect(domains).toEqual([]); |
| 2233 | + }); |
| 2234 | + |
| 2235 | + it('should extract GHEC tenant domain and API subdomain from GITHUB_SERVER_URL', () => { |
| 2236 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_SERVER_URL: 'https://myorg.ghe.com' }); |
| 2237 | + expect(domains).toContain('myorg.ghe.com'); |
| 2238 | + expect(domains).toContain('api.myorg.ghe.com'); |
| 2239 | + expect(domains).toHaveLength(2); |
| 2240 | + }); |
| 2241 | + |
| 2242 | + it('should handle GITHUB_SERVER_URL with trailing slash', () => { |
| 2243 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_SERVER_URL: 'https://myorg.ghe.com/' }); |
| 2244 | + expect(domains).toContain('myorg.ghe.com'); |
| 2245 | + expect(domains).toContain('api.myorg.ghe.com'); |
| 2246 | + }); |
| 2247 | + |
| 2248 | + it('should handle GITHUB_SERVER_URL with path components', () => { |
| 2249 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_SERVER_URL: 'https://acme.ghe.com/some/path' }); |
| 2250 | + expect(domains).toContain('acme.ghe.com'); |
| 2251 | + expect(domains).toContain('api.acme.ghe.com'); |
| 2252 | + }); |
| 2253 | + |
| 2254 | + it('should extract from GITHUB_API_URL for GHEC', () => { |
| 2255 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_API_URL: 'https://api.myorg.ghe.com' }); |
| 2256 | + expect(domains).toContain('api.myorg.ghe.com'); |
| 2257 | + }); |
| 2258 | + |
| 2259 | + it('should not add GITHUB_API_URL domain if already present from GITHUB_SERVER_URL', () => { |
| 2260 | + const domains = extractGhecDomainsFromServerUrl({ |
| 2261 | + GITHUB_SERVER_URL: 'https://myorg.ghe.com', |
| 2262 | + GITHUB_API_URL: 'https://api.myorg.ghe.com', |
| 2263 | + }); |
| 2264 | + expect(domains).toContain('myorg.ghe.com'); |
| 2265 | + expect(domains).toContain('api.myorg.ghe.com'); |
| 2266 | + // api.myorg.ghe.com should appear only once |
| 2267 | + const apiCount = domains.filter(d => d === 'api.myorg.ghe.com').length; |
| 2268 | + expect(apiCount).toBe(1); |
| 2269 | + }); |
| 2270 | + |
| 2271 | + it('should return empty array when GITHUB_API_URL is api.github.com', () => { |
| 2272 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_API_URL: 'https://api.github.com' }); |
| 2273 | + expect(domains).toEqual([]); |
| 2274 | + }); |
| 2275 | + |
| 2276 | + it('should ignore non-ghe.com GITHUB_API_URL', () => { |
| 2277 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_API_URL: 'https://api.github.mycompany.com' }); |
| 2278 | + expect(domains).toEqual([]); |
| 2279 | + }); |
| 2280 | + |
| 2281 | + it('should handle invalid GITHUB_SERVER_URL gracefully', () => { |
| 2282 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_SERVER_URL: 'not-a-valid-url' }); |
| 2283 | + expect(domains).toEqual([]); |
| 2284 | + }); |
| 2285 | + |
| 2286 | + it('should handle invalid GITHUB_API_URL gracefully', () => { |
| 2287 | + const domains = extractGhecDomainsFromServerUrl({ GITHUB_API_URL: 'not-a-valid-url' }); |
| 2288 | + expect(domains).toEqual([]); |
| 2289 | + }); |
| 2290 | + }); |
| 2291 | + |
| 2292 | + describe('resolveApiTargetsToAllowedDomains with GHEC', () => { |
| 2293 | + it('should auto-add GHEC domains when GITHUB_SERVER_URL is a ghe.com tenant', () => { |
| 2294 | + const domains: string[] = []; |
| 2295 | + const env = { GITHUB_SERVER_URL: 'https://myorg.ghe.com' }; |
| 2296 | + resolveApiTargetsToAllowedDomains({}, domains, env); |
| 2297 | + expect(domains).toContain('myorg.ghe.com'); |
| 2298 | + expect(domains).toContain('api.myorg.ghe.com'); |
| 2299 | + }); |
| 2300 | + |
| 2301 | + it('should not duplicate GHEC domains if already in allowlist', () => { |
| 2302 | + const domains: string[] = ['myorg.ghe.com', 'api.myorg.ghe.com']; |
| 2303 | + const env = { GITHUB_SERVER_URL: 'https://myorg.ghe.com' }; |
| 2304 | + resolveApiTargetsToAllowedDomains({}, domains, env); |
| 2305 | + const tenantCount = domains.filter(d => d === 'myorg.ghe.com').length; |
| 2306 | + const apiCount = domains.filter(d => d === 'api.myorg.ghe.com').length; |
| 2307 | + expect(tenantCount).toBe(1); |
| 2308 | + expect(apiCount).toBe(1); |
| 2309 | + }); |
| 2310 | + |
| 2311 | + it('should not add GHEC domains for public github.com', () => { |
| 2312 | + const initialLength = 0; |
| 2313 | + const domains: string[] = []; |
| 2314 | + const env = { GITHUB_SERVER_URL: 'https://github.com' }; |
| 2315 | + resolveApiTargetsToAllowedDomains({}, domains, env); |
| 2316 | + // github.com itself should NOT be auto-added just from GITHUB_SERVER_URL |
| 2317 | + expect(domains).not.toContain('github.com'); |
| 2318 | + expect(domains).not.toContain('api.github.com'); |
| 2319 | + expect(domains).toHaveLength(initialLength); |
| 2320 | + }); |
| 2321 | + |
| 2322 | + it('should auto-add GHEC domain from GITHUB_API_URL', () => { |
| 2323 | + const domains: string[] = []; |
| 2324 | + const env = { GITHUB_API_URL: 'https://api.myorg.ghe.com' }; |
| 2325 | + resolveApiTargetsToAllowedDomains({}, domains, env); |
| 2326 | + expect(domains).toContain('api.myorg.ghe.com'); |
| 2327 | + }); |
| 2328 | + |
| 2329 | + it('should combine GHEC domains with explicit API target', () => { |
| 2330 | + const domains: string[] = []; |
| 2331 | + const env = { GITHUB_SERVER_URL: 'https://company.ghe.com' }; |
| 2332 | + resolveApiTargetsToAllowedDomains({ copilotApiTarget: 'api.company.ghe.com' }, domains, env); |
| 2333 | + expect(domains).toContain('company.ghe.com'); |
| 2334 | + expect(domains).toContain('api.company.ghe.com'); |
| 2335 | + }); |
| 2336 | + }); |
| 2337 | + |
2219 | 2338 | describe('resolveApiTargetsToAllowedDomains with GHES', () => { |
2220 | 2339 | it('should auto-add GHES domains when ENGINE_API_TARGET is set', () => { |
2221 | 2340 | const domains: string[] = ['github.com']; |
|
0 commit comments