Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add custom formatting #1313

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type ScanCmdOptions struct {
DisabledScanners []string
PluginPaths []string
EnvFiles []string
Formats []string
}

func init() {
Expand All @@ -31,6 +32,7 @@ func init() {
cmd.PersistentFlags().StringArrayVarP(&opts.DisabledScanners, "disable", "D", []string{}, "Scanner to skip for this scan")
cmd.PersistentFlags().StringArrayVar(&opts.PluginPaths, "plugin", []string{}, "Extra scanner plugin to use for the scan")
cmd.PersistentFlags().StringSliceVar(&opts.EnvFiles, "env-file", []string{}, "Env files to parse environment variables from (looks for .env by default)")
cmd.PersistentFlags().StringSliceVarP(&opts.Formats, "format", "f", []string{}, "Additional format for the given phone number(s)")
// scanCmd.PersistentFlags().StringVarP(&input, "input", "i", "", "Text file containing a list of phone numbers to scan (one per line)")
// scanCmd.PersistentFlags().StringVarP(&output, "output", "o", "", "Output to save scan results")
}
Expand Down Expand Up @@ -62,7 +64,7 @@ func runScan(opts *ScanCmdOptions) {
exitWithError(errors.New("given phone number is not valid"))
}

num, err := number.NewNumber(opts.Number)
num, err := number.NewNumber(opts.Number, opts.Formats...)
if err != nil {
exitWithError(err)
}
Expand Down
24 changes: 24 additions & 0 deletions docs/getting-started/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,30 @@ phoneinfoga scan -n "+1 555-444-3333"

!!! note "Note that the country code is essential. You don't know which country code to use ? [Find it here](https://www.countrycode.org/)"

## Custom formats

There's several ways to write down phone numbers and the way they're indexed by search engine makes it difficult to find them without applying custom formatting according to the country they come from. So you can specify a custom template that will be used by scanners and enhance the results.

The letter `x` will be replaced by each digit of the local phone number (excluding 0). Some variables can be used in the template such as :

| Variable | Description | Example |
|:------------|:------------------------------------------|:-------------|
| CountryCode | Country code of the phone number | 34 |
| Country | Country of the phone number as letters | US |

### Examples

```bash
# Add custom format +1 555.444.3333
phoneinfoga scan -n "+1 555-444-3333" -f "+{{.CountryCode}} xxx.xxx.xxxx"

# You can specify multiple formats at once
phoneinfoga scan -n "+1 555-444-3333" -f "xxx.xxx.xxxx" -f "xxx-xxx-xxxx"

# Add custom format 06.78.23.22.11
phoneinfoga scan -n "+34678232211" -f "0x.xx.xx.xx.xx"
```

<!--
#### Input & output file

Expand Down
46 changes: 45 additions & 1 deletion lib/number/number.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package number

import (
"bytes"
"fmt"
"github.com/nyaruka/phonenumbers"
"strings"
"text/template"
)

const templateDigitPlaceholder = "x"

// Number is a phone number
type Number struct {
Valid bool
Expand All @@ -14,9 +20,15 @@ type Number struct {
CountryCode int32
Country string
Carrier string
CustomFormats []string
}

type FormatTemplateData struct {
CountryCode string
Country string
}

func NewNumber(number string) (res *Number, err error) {
func NewNumber(number string, formats ...string) (res *Number, err error) {
n := "+" + FormatNumber(number)
country := ParseCountryCode(n)

Expand All @@ -34,7 +46,39 @@ func NewNumber(number string) (res *Number, err error) {
CountryCode: num.GetCountryCode(),
Country: country,
Carrier: num.GetPreferredDomesticCarrierCode(),
CustomFormats: []string{},
}

for _, format := range formats {
res.CustomFormats = append(res.CustomFormats, convertFormatTemplate(res, format))
}

return res, nil
}

func convertFormatTemplate(n *Number, f string) string {
countryCodeStr := fmt.Sprintf("%d", n.CountryCode)

var out []string
splitNumber := strings.Split(strings.Replace(n.International, countryCodeStr, "", 1), "")
splitFormat := strings.Split(f, "")
for _, j := range splitFormat {
if strings.ToLower(j) == templateDigitPlaceholder && len(splitNumber) > 0 {
j = splitNumber[0]
splitNumber = splitNumber[1:]
}
out = append(out, j)
}

t := template.Must(template.New("custom-format").Parse(strings.Join(out, "")))

var tpl bytes.Buffer
err := t.Execute(&tpl, FormatTemplateData{
CountryCode: countryCodeStr,
Country: n.Country,
})
if err != nil {
return strings.Join(out, "")
}
return tpl.String()
}
53 changes: 53 additions & 0 deletions lib/number/number_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func TestNumber(t *testing.T) {
CountryCode: 33,
Country: "FR",
Carrier: "",
CustomFormats: []string{},
},
},
{
Expand All @@ -39,6 +40,7 @@ func TestNumber(t *testing.T) {
CountryCode: 1,
Country: "",
Carrier: "",
CustomFormats: []string{},
},
},

Expand All @@ -58,3 +60,54 @@ func TestNumber(t *testing.T) {
})
}
}

func TestFormatTemplate(t *testing.T) {
cases := []struct {
name string
number string
format string
expected []string
wantErr error
}{
{
name: "should succeed to format with template",
number: "+15552221212",
format: "xxx-xxx-xxxx",
expected: []string{"555-222-1212"},
},
{
name: "should succeed to format with template",
number: "+33678342211",
format: "0x-Xx-xx-xX-xx",
expected: []string{"06-78-34-22-11"},
},
{
name: "should succeed to format with template",
number: "+911401871759",
format: "+{{.CountryCode}} xxxx-xxxxxx",
expected: []string{"+91 1401-871759"},
},
{
name: "should fail to format with template",
number: "+911401871759",
format: "+{{.DummyVar}} xxxx-xxxxxx",
expected: []string{"+{{.DummyVar}} 1401-871759"},
},
{
name: "should fail to format with template",
number: "+333333",
format: "+{{.DummyVar}} xxxx-xxxxxx",
expected: []string{"+{{.DummyVar}} 3333-xxxxxx"},
},
}

for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
n, err := NewNumber(tt.number, tt.format)
if err != nil {
t.Error(err)
}
assert.Equal(t, tt.expected, n.CustomFormats)
})
}
}
9 changes: 9 additions & 0 deletions lib/remote/googlecse_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ func (s *googleCSEScanner) generateDorkQueries(number number.Number) (results []
InText(number.Local),
}

// Add custom formats to dork queries
if len(number.CustomFormats) > 0 {
for _, d := range dorks {
for _, f := range number.CustomFormats {
d.Or().InText(f)
}
}
}

for _, dork := range dorks {
results = append(results, &GoogleSearchDork{
Number: number.E164,
Expand Down
18 changes: 18 additions & 0 deletions lib/remote/googlesearch_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ func getSocialMediaDorks(number number.Number) (results []*GoogleSearchDork) {
InText(number.RawLocal),
}

// Add custom formats to dork queries
if len(number.CustomFormats) > 0 {
for _, d := range dorks {
for _, f := range number.CustomFormats {
d.Or().InText(f)
}
}
}

for _, dork := range dorks {
results = append(results, &GoogleSearchDork{
Number: number.E164,
Expand Down Expand Up @@ -377,6 +386,15 @@ func getGeneralDorks(number number.Number) (results []*GoogleSearchDork) {
InText(number.RawLocal),
}

// Add custom formats to dork queries
if len(number.CustomFormats) > 0 {
for _, d := range dorks {
for _, f := range number.CustomFormats {
d.Or().InText(f)
}
}
}

for _, dork := range dorks {
results = append(results, &GoogleSearchDork{
Number: number.E164,
Expand Down
30 changes: 30 additions & 0 deletions web/docs/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions web/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,12 @@
"number"
],
"properties": {
"formats": {
"type": "array",
"items": {
"type": "string"
}
},
"number": {
"type": "string"
}
Expand All @@ -496,6 +502,12 @@
"countryCode": {
"type": "integer"
},
"custom_formats": {
"type": "array",
"items": {
"type": "string"
}
},
"e164": {
"type": "string"
},
Expand All @@ -519,6 +531,12 @@
"number"
],
"properties": {
"formats": {
"type": "array",
"items": {
"type": "string"
}
},
"number": {
"type": "string"
}
Expand Down Expand Up @@ -552,6 +570,12 @@
"number"
],
"properties": {
"formats": {
"type": "array",
"items": {
"type": "string"
}
},
"number": {
"type": "string"
}
Expand Down Expand Up @@ -586,6 +610,12 @@
"countryCode": {
"type": "integer"
},
"customFormats": {
"type": "array",
"items": {
"type": "string"
}
},
"e164": {
"type": "string"
},
Expand Down