/
init.go
115 lines (97 loc) · 2.75 KB
/
init.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
106
107
108
109
110
111
112
113
114
115
package cmd
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/nnachevv/passmag/crypt"
"github.com/nnachevv/passmag/storage"
"github.com/spf13/cobra"
"go.mongodb.org/mongo-driver/bson"
"golang.org/x/crypto/argon2"
)
// NewInitCmd creates a new i
func NewInitCmd() *cobra.Command {
initCmd := &cobra.Command{
Use: "init",
Short: "Setup account",
Long: `Initialize your vault with email and masterpassword`,
RunE: func(cmd *cobra.Command, args []string) error {
email, password, err := initUserInput()
if err != nil {
return err
}
s, err := storage.New(bson.M{"email": email}, time.Now())
if err != nil {
return err
}
byteData, err := json.Marshal(s)
if err != nil {
return fmt.Errorf("failed to marshal map : %w", err)
}
vaultPwd := argon2.IDKey([]byte(password), []byte(s.Email), 1, 64*1024, 4, 32)
vaultData, err := crypt.Encrypt(byteData, vaultPwd)
if err != nil {
return fmt.Errorf("failed to add user to db :%w", err)
}
err = MongoDB.Insert(s.Email, vaultData, Client)
if err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "%s is successfully created!\n", email)
return nil
},
}
return initCmd
}
func initUserInput() (email string, password string, err error) {
answers := struct {
Email string
MasterPassword string
ConfirmPassword string
}{}
qs := []*survey.Question{
{
Name: "email",
Prompt: &survey.Input{Message: "Enter your email address:"},
Validate: func(val interface{}) error {
if input, ok := val.(string); !ok || len(input) < 8 {
return errors.New("email should be longer than 8 characters")
}
if _, err := MongoDB.Find(val.(string), Client); err == nil {
return errors.New("email address already exist in our database")
}
return nil
},
},
{
Name: "masterpassword",
Prompt: &survey.Password{Message: "Enter your password:"},
Validate: func(val interface{}) error {
if str, ok := val.(string); !ok || len(str) < 8 {
return errors.New("password should be longer than 8 characters")
}
return nil
},
},
{
Name: "confirmpassword",
Prompt: &survey.Password{Message: "Enter again your password:"},
Validate: func(val interface{}) error {
if str, ok := val.(string); !ok || len(str) < 8 {
return errors.New("password should be longer than 8 characters")
}
return nil
},
},
}
err = survey.Ask(qs, &answers, survey.WithStdio(Stdio.In, Stdio.Out, Stdio.Err))
if err != nil {
return "", "", fmt.Errorf("failed to process input : %w", err)
}
if answers.MasterPassword != answers.ConfirmPassword {
return "", "", errors.New("passwords must match")
}
return answers.Email, answers.MasterPassword, nil
}