-
Notifications
You must be signed in to change notification settings - Fork 24
/
search.go
105 lines (88 loc) · 2.06 KB
/
search.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package service
import (
"errors"
"fmt"
"sort"
"time"
"github.com/momaek/authy/totp"
"github.com/sahilm/fuzzy"
)
// Searcher
type Searcher struct {
isAlfred bool
keyword string
*Device
}
func (s *Searcher) showAll() bool {
return len(s.keyword) == 0 || s.keyword == ""
}
// NewSearcher ..
func NewSearcher(keyword string, isAlfred bool) *Searcher {
return &Searcher{
isAlfred: isAlfred,
keyword: keyword,
Device: NewDevice(NewDeviceConfig{}),
}
}
// Search fuzzy search tokens by name and origin_name
func (s *Searcher) Search() {
var (
tokens = []*Token{}
outputs = []Output{}
)
s.Device.LoadTokenFromCache()
if s.showAll() {
sort.Sort(Tokens(s.Device.tokens))
tokens = s.Device.tokens
} else {
tokens = s.searchTokens()
}
if len(s.Device.tokens) == 0 {
outputs = append(outputs, Output{
OTitle: "OTP tokens not found",
Error: errors.New("Please run 'authy refresh' in commandline"),
})
} else {
outputs = s.calcTokens(tokens)
}
s.showResult(outputs)
}
func (s *Searcher) searchTokens() []*Token {
results := fuzzy.FindFrom(s.keyword, Tokens(s.Device.tokens))
foundTokens := make([]*Token, 0, len(results))
for _, v := range results {
foundTokens = append(foundTokens, s.Device.tokens[v.Index])
s.Device.tokens[v.Index].updateWeight()
}
s.Device.saveToken()
return foundTokens
}
func calcRemainSec(challenge int64) int {
return 30 - int(time.Now().Unix()-challenge*30)
}
func (s *Searcher) calcTokens(tokens []*Token) []Output {
out := make([]Output, 0, len(tokens))
for _, tk := range tokens {
if len(tk.Secret) == 0 {
out = append(out, Output{
Token: tk,
Error: errors.New("OTP token is empty"),
})
continue
}
codes := totp.GetTotpCode(tk.Secret, tk.Digital)
challenge := totp.GetChallenge()
out = append(out, Output{
Token: tk,
Code: codes[1],
RemainSecs: calcRemainSec(challenge),
})
}
if len(out) == 0 {
out = append(out, Output{
OTitle: fmt.Sprintf("OTP token not found (%s)", s.keyword),
Error: errors.New("Please try another keyword"),
})
}
return out
}