]>
Commit | Line | Data |
---|---|---|
85545aba | 1 | package api |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | "time" | |
6 | ||
7 | "github.com/dchest/passwordreset" | |
1d68446a | 8 | "git.immae.eu/Cryptoportfolio/Front.git/db" |
85545aba | 9 | ) |
10 | ||
11 | var PASSWORD_RESET_SECRET []byte | |
12 | ||
13 | type PasswordResetQuery struct { | |
14 | In struct { | |
15 | Email string | |
16 | } | |
17 | } | |
18 | ||
19 | func (q PasswordResetQuery) ValidateParams() *Error { | |
20 | if q.In.Email == "" { | |
21 | return &Error{InvalidEmail, "invalid email", fmt.Errorf("invalid email")} | |
22 | } | |
23 | ||
24 | return nil | |
25 | } | |
26 | ||
27 | func (q PasswordResetQuery) Run() (interface{}, *Error) { | |
28 | user, err := db.GetUserByEmail(q.In.Email) | |
29 | if err != nil { | |
30 | return nil, NewInternalError(err) | |
31 | } | |
32 | ||
33 | if user == nil { | |
34 | return nil, &Error{NotFound, "account not found", fmt.Errorf("'%v' is not registered", q.In.Email)} | |
35 | } | |
36 | ||
37 | token := passwordreset.NewToken(q.In.Email, time.Hour*24*1, []byte(user.PasswordHash), PASSWORD_RESET_SECRET) | |
38 | if CONFIG.FreeSMSUser != "" { | |
39 | err := SendSMS(CONFIG.FreeSMSUser, CONFIG.FreeSMSPass, fmt.Sprintf("'%v' request a password reset. Token '/change-password?token=%v'", q.In.Email, token)) | |
40 | if err != nil { | |
41 | return nil, NewInternalError(err) | |
42 | } | |
43 | } | |
44 | ||
2da5b12c | 45 | if MAIL_CONFIG.IsEnabled { |
46 | err = SendResetPasswordMail(q.In.Email, token) | |
47 | if err != nil { | |
48 | return nil, NewInternalError(err) | |
49 | } | |
50 | } | |
51 | ||
8d238416 | 52 | return nil, nil |
85545aba | 53 | } |
54 | ||
55 | type ChangePasswordQuery struct { | |
56 | In struct { | |
57 | Token string | |
58 | Password string | |
59 | } | |
60 | } | |
61 | ||
62 | func (q ChangePasswordQuery) ValidateParams() *Error { | |
63 | if q.In.Password == "" { | |
64 | return &Error{InvalidPassword, "invalid password", fmt.Errorf("invalid password")} | |
65 | } | |
66 | ||
67 | if q.In.Token == "" { | |
68 | return &Error{BadRequest, "invalid token", fmt.Errorf("invalid token")} | |
69 | } | |
70 | ||
71 | return nil | |
72 | } | |
73 | ||
74 | func (q ChangePasswordQuery) Run() (interface{}, *Error) { | |
75 | var user *db.User | |
76 | ||
77 | email, err := passwordreset.VerifyToken(q.In.Token, func(email string) ([]byte, error) { | |
78 | var err error | |
79 | user, err = db.GetUserByEmail(email) | |
80 | if err != nil { | |
81 | return nil, err | |
82 | } | |
83 | ||
84 | if user == nil { | |
85 | return nil, fmt.Errorf("'%v' is not registered", email) | |
86 | } | |
87 | ||
88 | return []byte(user.PasswordHash), nil | |
89 | ||
90 | }, PASSWORD_RESET_SECRET) | |
91 | ||
92 | if err != nil && (err == passwordreset.ErrExpiredToken) { | |
93 | return nil, &Error{BadRequest, "expired token", fmt.Errorf("expired token")} | |
94 | } else if err != nil && (err == passwordreset.ErrMalformedToken || err == passwordreset.ErrWrongSignature) { | |
95 | return nil, &Error{BadRequest, "wrong token", fmt.Errorf("wrong token")} | |
96 | } else if err != nil { | |
97 | return nil, NewInternalError(err) | |
98 | } | |
99 | ||
100 | if user == nil { | |
101 | return nil, &Error{BadRequest, "bad request", fmt.Errorf("no user found for email '%v'", email)} | |
102 | } | |
103 | ||
104 | err = db.SetPassword(user, q.In.Password) | |
105 | if err != nil { | |
106 | return nil, NewInternalError(err) | |
107 | } | |
108 | ||
8d238416 | 109 | return nil, nil |
85545aba | 110 | } |