@@ -412,4 +412,72 @@ describe('GitClient', () => {
412412 expect ( fullOptionsClient ) . toBeInstanceOf ( GitClient ) ;
413413 } ) ;
414414 } ) ;
415+
416+ describe ( 'credential redaction in logs' , ( ) => {
417+ it ( 'should redact credentials from URLs but leave public URLs unchanged' , async ( ) => {
418+ const mockLogger = {
419+ info : vi . fn ( ) ,
420+ warn : vi . fn ( ) ,
421+ error : vi . fn ( ) ,
422+ debug : vi . fn ( )
423+ } ;
424+
425+ const clientWithLogger = new GitClient ( {
426+ baseUrl : 'http://test.com' ,
427+ port : 3000 ,
428+ logger : mockLogger
429+ } ) ;
430+
431+ // Test with credentials
432+ mockFetch . mockResolvedValueOnce (
433+ new Response (
434+ JSON . stringify ( {
435+ success : true ,
436+ stdout : "Cloning into 'private-repo'...\nDone." ,
437+ stderr : '' ,
438+ exitCode : 0 ,
439+ repoUrl :
'https://oauth2:[email protected] /user/private-repo.git' , 440+ branch : 'main' ,
441+ targetDir : '/workspace/private-repo' ,
442+ timestamp : '2023-01-01T00:00:00Z'
443+ } ) ,
444+ { status : 200 }
445+ )
446+ ) ;
447+
448+ await clientWithLogger . checkout (
449+ 'https://oauth2:[email protected] /user/private-repo.git' , 450+ 'test-session'
451+ ) ;
452+
453+ let logDetails = mockLogger . info . mock . calls [ 0 ] ?. [ 1 ] ?. details ;
454+ expect ( logDetails ) . not . toContain ( 'ghp_token123' ) ;
455+ expect ( logDetails ) . toContain ( 'https://******@github.com/user/private-repo.git' ) ;
456+
457+ // Test without credentials
458+ mockFetch . mockResolvedValueOnce (
459+ new Response (
460+ JSON . stringify ( {
461+ success : true ,
462+ stdout : "Cloning into 'react'...\nDone." ,
463+ stderr : '' ,
464+ exitCode : 0 ,
465+ repoUrl : 'https://github.com/facebook/react.git' ,
466+ branch : 'main' ,
467+ targetDir : '/workspace/react' ,
468+ timestamp : '2023-01-01T00:00:00Z'
469+ } ) ,
470+ { status : 200 }
471+ )
472+ ) ;
473+
474+ await clientWithLogger . checkout (
475+ 'https://github.com/facebook/react.git' ,
476+ 'test-session'
477+ ) ;
478+
479+ logDetails = mockLogger . info . mock . calls [ 1 ] ?. [ 1 ] ?. details ;
480+ expect ( logDetails ) . toContain ( 'https://github.com/facebook/react.git' ) ;
481+ } ) ;
482+ } ) ;
415483} ) ;
0 commit comments