diff --git a/domain/user/endpoint.go b/domain/user/endpoint.go index be2365af..6a471b66 100644 --- a/domain/user/endpoint.go +++ b/domain/user/endpoint.go @@ -586,6 +586,7 @@ func (h *Handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { ctx := domain.GetRequestContext(r) ctx.Subdomain = organization.GetSubdomainFromHost(r) + // Get email address from payload. defer streamutil.Close(r.Body) body, err := ioutil.ReadAll(r.Body) if err != nil { @@ -593,7 +594,6 @@ func (h *Handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { h.Runtime.Log.Error(method, err) return } - u := new(user.User) err = json.Unmarshal(body, &u) if err != nil { @@ -602,6 +602,15 @@ func (h *Handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { return } + // Exit process if user does not exist. + _, err = h.Store.User.GetByEmail(ctx, u.Email) + if err != nil { + response.WriteNotFound(w) + h.Runtime.Log.Error(method, err) + return + } + + // Set token for password reset process. ctx.Transaction, err = h.Runtime.Db.Beginx() if err != nil { response.WriteServerError(w, method, err) @@ -610,7 +619,6 @@ func (h *Handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { } token := secrets.GenerateSalt() - err = h.Store.User.ForgotUserPassword(ctx, u.Email, token) if err != nil && err != sql.ErrNoRows { ctx.Transaction.Rollback() @@ -618,7 +626,6 @@ func (h *Handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { h.Runtime.Log.Error(method, err) return } - if err == sql.ErrNoRows { ctx.Transaction.Rollback() h.Runtime.Log.Info(fmt.Sprintf("User %s not found for password reset process", u.Email)) @@ -628,6 +635,7 @@ func (h *Handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { ctx.Transaction.Commit() + // Fire reset email to user. appURL := ctx.GetAppURL(fmt.Sprintf("auth/reset/%s", token)) mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx} go mailer.PasswordReset(u.Email, appURL) diff --git a/gui/app/components/user/forgot-password.js b/gui/app/components/user/forgot-password.js index 74af0db5..19b690a9 100644 --- a/gui/app/components/user/forgot-password.js +++ b/gui/app/components/user/forgot-password.js @@ -18,6 +18,7 @@ import Component from '@ember/component'; export default Component.extend({ email: "", sayThanks: false, + sayError: false, emailEmpty: empty('email'), hasEmptyEmailError: and('emailEmpty', 'emailIsEmpty'), @@ -30,10 +31,16 @@ export default Component.extend({ return $("#email").focus(); } + set(this, 'sayThanks', false); + set(this, 'sayError', false); + + set(this, 'emailIsEmpty', false); + this.get('forgot')(email).then(() => { set(this, 'sayThanks', true); set(this, 'email', ''); - set(this, 'emailIsEmpty', false); + }).catch(() => { + set(this, 'sayError', true); }); } } diff --git a/gui/app/services/user.js b/gui/app/services/user.js index 29c726b9..a895fae5 100644 --- a/gui/app/services/user.js +++ b/gui/app/services/user.js @@ -10,7 +10,6 @@ // https://documize.com import { isEmpty } from '@ember/utils'; - import RSVP from 'rsvp'; import Service, { inject as service } from '@ember/service'; diff --git a/gui/app/templates/components/user/forgot-password.hbs b/gui/app/templates/components/user/forgot-password.hbs index a8bf23bc..c708809c 100644 --- a/gui/app/templates/components/user/forgot-password.hbs +++ b/gui/app/templates/components/user/forgot-password.hbs @@ -1,13 +1,17 @@
{{#if sayThanks}} -
Thanks. Check your email for instructions.
+

Thanks. Check your email for instructions.

{{else}}
{{focus-input type="email" value=email id="email" class=(if hasEmptyEmailError "form-control is-invalid" "form-control")}} + {{#if sayError}} +

Email not found

+ {{/if}}
{{ui/ui-button color=constants.Color.Yellow light=true label=constants.Label.Reset onClick=(action "forgot")}} {{/if}} + {{ui/ui-spacer size=400}} {{#link-to "auth.login"}}Click here to sign in{{/link-to}}