diff --git a/apiserver/cmd/server/server.go b/apiserver/cmd/server/server.go index 010ac674..67c78479 100644 --- a/apiserver/cmd/server/server.go +++ b/apiserver/cmd/server/server.go @@ -711,6 +711,14 @@ func (s *Server) VerifyAccount(w rest.ResponseWriter, r *rest.Request) { rest.Error(w, err.Error(), http.StatusInternalServerError) return } + + err = s.email.SendVerifiedEmail(account.Name, account.EmailAddress) + if err != nil { + glog.Error(err) + rest.Error(w, err.Error(), http.StatusInternalServerError) + return + } + approveUrl := r.BaseUrl().String() + "/api/register/approve?t=" + account.Token + "&u=" + account.Namespace denyUrl := r.BaseUrl().String() + "/api/register/deny?t=" + account.Token + "&u=" + account.Namespace err = s.email.SendNewAccountEmail(account, approveUrl, denyUrl) @@ -2386,7 +2394,6 @@ func (s *Server) ChangePassword(w rest.ResponseWriter, r *rest.Request) { if err != nil { glog.Error(err) rest.Error(w, err.Error(), http.StatusInternalServerError) - return } if ok { @@ -2394,12 +2401,9 @@ func (s *Server) ChangePassword(w rest.ResponseWriter, r *rest.Request) { if err != nil { glog.Error(err) rest.Error(w, err.Error(), http.StatusInternalServerError) - return } - w.WriteHeader(http.StatusOK) - } else { - w.WriteHeader(http.StatusConflict) } + w.WriteHeader(http.StatusOK) } func (s *Server) ResetPassword(w rest.ResponseWriter, r *rest.Request) { @@ -2418,8 +2422,14 @@ func (s *Server) ResetPassword(w rest.ResponseWriter, r *rest.Request) { return } - resetUrl := s.origin + "/#/recover?t=" + token - err = s.email.SendRecoveryEmail(account.Name, account.EmailAddress, resetUrl) + if account.Status == api.AccountStatusUnverified { + verifyUrl := s.origin + "/#/register/verify?t=" + account.Token + "&u=" + account.Namespace + err = s.email.SendVerificationEmail(account.Name, account.EmailAddress, verifyUrl) + } else { + resetUrl := s.origin + "/#/recover?t=" + token + err = s.email.SendRecoveryEmail(account.Name, account.EmailAddress, resetUrl, (account.Status == api.AccountStatusUnapproved)) + } + if err != nil { glog.Error(err) rest.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/apiserver/pkg/email/email.go b/apiserver/pkg/email/email.go index ec1f48f4..24401e1b 100644 --- a/apiserver/pkg/email/email.go +++ b/apiserver/pkg/email/email.go @@ -54,6 +54,29 @@ func (s *EmailHelper) SendVerificationEmail(name string, address string, url str return nil } +// Send email address verified +func (s *EmailHelper) SendVerifiedEmail(name string, address string) error { + + data := struct { + Name string + SupportEmail string + }{ + Name: name, + SupportEmail: s.SupportEmail, + } + + subject := "Registration pending" + msg, err := s.parseTemplate("templates/verified-email.html", data) + if err != nil { + return err + } + _, err = s.sendEmail(address, subject, msg) + if err != nil { + return err + } + return nil +} + // Send new account request email func (s *EmailHelper) SendNewAccountEmail(account *api.Account, approveUrl string, denyUrl string) error { @@ -123,17 +146,19 @@ func (s *EmailHelper) SendStatusEmail(name string, address string, url string, a } // Send password recovery email -func (s *EmailHelper) SendRecoveryEmail(name string, email string, recoveryUrl string) error { +func (s *EmailHelper) SendRecoveryEmail(name string, email string, recoveryUrl string, unapproved bool) error { data := struct { Name string Email string Link string SupportEmail string + Unapproved bool }{ Name: name, Email: email, Link: recoveryUrl, + Unapproved: unapproved, SupportEmail: s.SupportEmail, } @@ -142,7 +167,7 @@ func (s *EmailHelper) SendRecoveryEmail(name string, email string, recoveryUrl s if err != nil { return err } - _, err = s.sendEmail(s.SupportEmail, subject, msg) + _, err = s.sendEmail(email, subject, msg) if err != nil { return err } diff --git a/apiserver/pkg/types/types.go b/apiserver/pkg/types/types.go index b0feb10b..29dac58f 100644 --- a/apiserver/pkg/types/types.go +++ b/apiserver/pkg/types/types.go @@ -225,7 +225,7 @@ type Term struct { type SupportRequest struct { Type SupportRequestType `json:"type"` Message string `json:"message"` - Anonymous bool `json:"bool"` + Anonymous bool `json:"anonymous"` } type SupportRequestType string diff --git a/apiserver/templates/recovery-request.html b/apiserver/templates/recovery-request.html index 325818ab..be77d3d9 100644 --- a/apiserver/templates/recovery-request.html +++ b/apiserver/templates/recovery-request.html @@ -6,13 +6,22 @@ Hello {{.Name}},

-Someone has requested to reset your NDS Labs password. Please click on the link below to reset the password for your account: +{{ if .Unapproved }} + +Your registration request is still under review and has not been approved. Please contact us at the email address below with any questions. +{{ else }} + +

+Someone has requested to reset your NDS Labs password. If this action was not triggered by you, then you can safely ignore this message. Please click on the link below to reset the password for your account:

Reset password

This link is valid for 30 minutes. +{{ end }} +

+ Thank you,
NDS Labs team
{{.SupportEmail}}
diff --git a/apiserver/templates/verified-email.html b/apiserver/templates/verified-email.html new file mode 100644 index 00000000..37618c1d --- /dev/null +++ b/apiserver/templates/verified-email.html @@ -0,0 +1,23 @@ + + + +

+Hello {{.Name}}, +

+ +Thank you for verifying your email address.

+ +Your registration request will be reviewed by the NDS Labs team. You should hear back from us within 7 days. +Please feel free to contact us at the email address below with any questions. + +
+
+Sincerely,
+NDS Labs team
+{{.SupportEmail}}
+

+ + + +