@@ -22,11 +22,11 @@ import (
2222
2323// Config and other types remain the same
2424type Config struct {
25- TYPE string `yaml:"TYPE"`
26- SORT string `yaml:"SORT"`
27- DIRECTION string `yaml:"DIRECTION"`
28- PER_PAGE int `yaml:"PER_PAGE"`
29- PAGE int `yaml:"PAGE"`
25+ TYPE string `yaml:"TYPE"`
26+ SORT string `yaml:"SORT"`
27+ DIRECTION string `yaml:"DIRECTION"`
28+ PER_PAGE int `yaml:"PER_PAGE"`
29+ PAGE int `yaml:"PAGE"`
3030 Private string `yaml:"Private"`
3131 HTMLURL string `yaml:"HTMLURL"`
3232 Description string `yaml:"Description"`
@@ -170,13 +170,20 @@ func parseDuration(durationStr string) (time.Duration, error) {
170170 var duration time.Duration
171171
172172 switch unit {
173- case "s" : duration = time .Duration (num ) * time .Second
174- case "m" : duration = time .Duration (num ) * time .Minute
175- case "h" : duration = time .Duration (num ) * time .Hour
176- case "d" : duration = time .Duration (num ) * 24 * time .Hour
177- case "w" : duration = time .Duration (num ) * 7 * 24 * time .Hour
178- case "M" : duration = time .Duration (num ) * 30 * 24 * time .Hour
179- case "y" : duration = time .Duration (num ) * 365 * 24 * time .Hour
173+ case "s" :
174+ duration = time .Duration (num ) * time .Second
175+ case "m" :
176+ duration = time .Duration (num ) * time .Minute
177+ case "h" :
178+ duration = time .Duration (num ) * time .Hour
179+ case "d" :
180+ duration = time .Duration (num ) * 24 * time .Hour
181+ case "w" :
182+ duration = time .Duration (num ) * 7 * 24 * time .Hour
183+ case "M" :
184+ duration = time .Duration (num ) * 30 * 24 * time .Hour
185+ case "y" :
186+ duration = time .Duration (num ) * 365 * 24 * time .Hour
180187 default :
181188 return 0 , fmt .Errorf ("unknown time unit: %s" , unit )
182189 }
@@ -274,7 +281,7 @@ func fetchUserRepos(username string, config *Config, tokens []string, delay time
274281
275282 for {
276283 token := getRandomToken (tokens )
277- apiURL := fmt .Sprintf ("https://api.github.com/users/%s/repos?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
284+ apiURL := fmt .Sprintf ("https://api.github.com/users/%s/repos?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
278285 username , config .TYPE , config .SORT , config .DIRECTION , config .PER_PAGE , page )
279286
280287 req , err := http .NewRequest ("GET" , apiURL , nil )
@@ -364,7 +371,7 @@ func extractCommits(baseDir string, dateRange string) {
364371 outputFile := filepath .Join (outputRepoDir , "commits.txt" )
365372
366373 args := []string {"-C" , repoPath , "--no-pager" , "log" , "--pretty=format:%H" }
367-
374+
368375 if dateRange != "all" {
369376 re := regexp .MustCompile (`([0-9]+)([smhdwMy])` )
370377 matches := re .FindStringSubmatch (dateRange )
@@ -373,13 +380,20 @@ func extractCommits(baseDir string, dateRange string) {
373380 dateUnit := matches [2 ]
374381 var gitTime string
375382 switch dateUnit {
376- case "s" : gitTime = fmt .Sprintf ("%s seconds" , dateNum )
377- case "m" : gitTime = fmt .Sprintf ("%s minutes" , dateNum )
378- case "h" : gitTime = fmt .Sprintf ("%s hours" , dateNum )
379- case "d" : gitTime = fmt .Sprintf ("%s days" , dateNum )
380- case "w" : gitTime = fmt .Sprintf ("%s weeks" , dateNum )
381- case "M" : gitTime = fmt .Sprintf ("%s months" , dateNum )
382- case "y" : gitTime = fmt .Sprintf ("%s years" , dateNum )
383+ case "s" :
384+ gitTime = fmt .Sprintf ("%s seconds" , dateNum )
385+ case "m" :
386+ gitTime = fmt .Sprintf ("%s minutes" , dateNum )
387+ case "h" :
388+ gitTime = fmt .Sprintf ("%s hours" , dateNum )
389+ case "d" :
390+ gitTime = fmt .Sprintf ("%s days" , dateNum )
391+ case "w" :
392+ gitTime = fmt .Sprintf ("%s weeks" , dateNum )
393+ case "M" :
394+ gitTime = fmt .Sprintf ("%s months" , dateNum )
395+ case "y" :
396+ gitTime = fmt .Sprintf ("%s years" , dateNum )
383397 }
384398 if gitTime != "" {
385399 args = append (args , "--before=" + gitTime )
@@ -394,13 +408,13 @@ func extractCommits(baseDir string, dateRange string) {
394408 }
395409
396410 os .WriteFile (outputFile , output , 0644 )
397-
411+
398412 commits := strings .Split (strings .TrimSpace (string (output )), "\n " )
399413 commitCount := len (commits )
400414 if commitCount == 1 && commits [0 ] == "" {
401415 commitCount = 0
402416 }
403-
417+
404418 fmt .Printf ("%s[%d/%d]%s %s → %d commits\n " , ColorBlue , currentRepo , totalRepos , ColorReset , entry .Name (), commitCount )
405419 }
406420 }
@@ -443,7 +457,7 @@ func extractCode(baseDir string) {
443457 if entry .IsDir () {
444458 repoName := entry .Name ()
445459 commitsFile := filepath .Join (commitsDir , repoName , "commits.txt" )
446-
460+
447461 if _ , err := os .Stat (commitsFile ); os .IsNotExist (err ) {
448462 continue
449463 }
@@ -475,7 +489,7 @@ func extractCode(baseDir string) {
475489 processedCommits ++
476490 outputFilePath := filepath .Join (repoCodeDir , commit + ".txt" )
477491 repoPath := filepath .Join (downloadDir , repoName )
478-
492+
479493 cmd := exec .Command ("git" , "-C" , repoPath , "--no-pager" , "show" , commit )
480494 output , err := cmd .Output ()
481495 if err != nil {
@@ -525,7 +539,7 @@ func scanVulnerabilities(baseDir string, notifyID string) {
525539 if entry .IsDir () {
526540 repoName := entry .Name ()
527541 codePath := filepath .Join (codeDir , repoName , "code" )
528-
542+
529543 if _ , err := os .Stat (codePath ); os .IsNotExist (err ) {
530544 continue
531545 }
@@ -539,7 +553,7 @@ func scanVulnerabilities(baseDir string, notifyID string) {
539553 fmt .Printf ("%s[%d/%d]%s Scanning: %s\n " , ColorBlue , currentRepo , totalRepos , ColorReset , repoName )
540554
541555 trufflehogCmd := exec .Command ("trufflehog" , "filesystem" , "--json" , codePath )
542-
556+
543557 outputFile , err := os .Create (trufflehogOutputFile )
544558 if err != nil {
545559 continue
@@ -568,13 +582,13 @@ func scanVulnerabilities(baseDir string, notifyID string) {
568582 "bash" , "-c" ,
569583 fmt .Sprintf (`cat %s | jq -r --arg repo "%s" --arg vulnFile "%s" 'select(.Verified==true) | "Repo: \($repo), VulnDir: \($vulnFile), Leaks: \(.DetectorName): \(.Raw)"'` , trufflehogOutputFile , repoURL , trufflehogOutputFile ),
570584 )
571-
585+
572586 output , err := cmd .Output ()
573587 if err == nil && len (output ) > 0 {
574588 // Group vulnerabilities by unique combinations to avoid duplicates
575589 uniqueVulns := make (map [string ]bool )
576590 var formattedOutput []string
577-
591+
578592 lines := strings .Split (string (output ), "\n " )
579593 for _ , line := range lines {
580594 if line != "" && ! uniqueVulns [line ] {
@@ -592,7 +606,7 @@ func scanVulnerabilities(baseDir string, notifyID string) {
592606 )
593607 notifyCmd .Run ()
594608 }
595-
609+
596610 fmt .Printf ("%s✓%s Sent %d vulnerabilities to Discord\n " , ColorGreen , ColorReset , len (formattedOutput ))
597611 } else {
598612 fmt .Printf ("%s!%s No verified vulnerabilities\n " , ColorYellow , ColorReset )
@@ -616,13 +630,13 @@ func fetchData(username string, config *Config, tokens []string, delay time.Dura
616630 token := getRandomToken (tokens )
617631 var apiURL string
618632 if scanType == "member" {
619- apiURL = fmt .Sprintf ("https://api.github.com/orgs/%s/members?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
633+ apiURL = fmt .Sprintf ("https://api.github.com/orgs/%s/members?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
620634 username , config .TYPE , config .SORT , config .DIRECTION , config .PER_PAGE , page )
621635 } else if scanType == "user" {
622- apiURL = fmt .Sprintf ("https://api.github.com/users/%s/repos?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
636+ apiURL = fmt .Sprintf ("https://api.github.com/users/%s/repos?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
623637 username , config .TYPE , config .SORT , config .DIRECTION , config .PER_PAGE , page )
624638 } else {
625- apiURL = fmt .Sprintf ("https://api.github.com/orgs/%s/repos?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
639+ apiURL = fmt .Sprintf ("https://api.github.com/orgs/%s/repos?type=%s&sort=%s&direction=%s&per_page=%d&page=%d" ,
626640 username , config .TYPE , config .SORT , config .DIRECTION , config .PER_PAGE , page )
627641 }
628642
@@ -685,7 +699,7 @@ func fetchData(username string, config *Config, tokens []string, delay time.Dura
685699func executeLeaksMonitor () {
686700 scanTypes := strings .Split (scanType , "," )
687701 validScanTypes := make ([]string , 0 )
688-
702+
689703 for _ , st := range scanTypes {
690704 st = strings .TrimSpace (st )
691705 if st == "org" || st == "member" || st == "user" {
@@ -757,8 +771,13 @@ func executeLeaksMonitor() {
757771 }
758772
759773 // Save output
760- homeDir , _ := os .UserHomeDir ()
761- outputDir := filepath .Join (homeDir , ".gitrepoenum" )
774+ var outputDir string
775+ if downloadDir != "" {
776+ outputDir = downloadDir
777+ } else {
778+ homeDir , _ := os .UserHomeDir ()
779+ outputDir = filepath .Join (homeDir , ".gitrepoenum" )
780+ }
762781 os .MkdirAll (outputDir , 0755 )
763782
764783 var outputPath string
@@ -767,7 +786,7 @@ func executeLeaksMonitor() {
767786 } else {
768787 outputPath = filepath .Join (outputDir , fmt .Sprintf ("%s-%s.json" , username , currentScanType ))
769788 }
770-
789+
771790 if err := os .WriteFile (outputPath , output , 0644 ); err == nil {
772791 fmt .Printf ("%s✓%s Output saved to %s\n " , ColorGreen , ColorReset , outputPath )
773792 }
@@ -791,7 +810,7 @@ func executeLeaksMonitor() {
791810 fmt .Printf ("\n %s═══════════════════════════════════════════════════%s\n " , ColorCyan , ColorReset )
792811 fmt .Printf ("%s STEP 2: CLONING%s\n " , ColorCyan , ColorReset )
793812 fmt .Printf ("%s═══════════════════════════════════════════════════%s\n \n " , ColorCyan , ColorReset )
794-
813+
795814 fmt .Printf ("%s→%s Cloning %d repositories\n \n " , ColorBlue , ColorReset , len (uniqueCloneURLs ))
796815
797816 if downloadDir == "" {
@@ -825,4 +844,4 @@ func init() {
825844 leaksmoniterCmd .Flags ().IntVarP (& parallel , "parallel" , "p" , 10 , "Repositories to clone in parallel" )
826845 leaksmoniterCmd .Flags ().IntVarP (& depth , "depth" , "z" , 5 , "Git clone depth" )
827846 leaksmoniterCmd .Flags ().StringVarP (& notifyID , "notifyid" , "n" , "allvuln" , "Send verified vulnerabilities to Discord" )
828- }
847+ }
0 commit comments