diff --git a/cmd/api/handlers-api.go b/cmd/api/handlers-api.go index 2c11e2f..627c26e 100644 --- a/cmd/api/handlers-api.go +++ b/cmd/api/handlers-api.go @@ -14,6 +14,7 @@ import ( "github.com/go-chi/chi/v5" "github.com/stripe/stripe-go/v79" + "golang.org/x/crypto/bcrypt" ) type stripePayload struct { @@ -465,3 +466,45 @@ func (app *application) SendPasswordResetEmail(w http.ResponseWriter, r *http.Re app.writeJSON(w, http.StatusCreated, resp) } + +func (app *application) ResetPassword(w http.ResponseWriter, r *http.Request) { + var payload struct { + Email string `json:"email"` + Password string `json:"password"` + } + + err := app.readJSON(w, r, &payload) + if err != nil { + app.errorLog.Println(err) + app.badRequest(w, r, err) + return + } + + user, err := app.DB.GetUserByEmail(payload.Email) + if err != nil { + app.errorLog.Println(err) + app.badRequest(w, r, err) + return + } + + newHash, err := bcrypt.GenerateFromPassword([]byte(payload.Password), 12) + if err != nil { + app.errorLog.Println(err) + app.badRequest(w, r, err) + return + } + + err = app.DB.UpdatePasswordForUser(user, string(newHash)) + if err != nil { + app.badRequest(w, r, err) + return + } + + var resp struct { + Error bool `json:"error"` + Message string `json:"message"` + } + resp.Error = false + resp.Message = "Password reset." + app.writeJSON(w, http.StatusCreated, resp) +} diff --git a/cmd/api/routes-api.go b/cmd/api/routes-api.go index a46836b..1cfbeb5 100644 --- a/cmd/api/routes-api.go +++ b/cmd/api/routes-api.go @@ -27,13 +27,14 @@ func (app *application) routes() http.Handler { mux.Route("/api/admin", func(mux chi.Router) { mux.Use(app.Auth) - mux.Get("/test", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("got in")) - }) + // mux.Get("/test", func(w http.ResponseWriter, r *http.Request) { + // w.Write([]byte("got in")) + // }) mux.Post("/virtual-terminal-succeeded", app.VirtualTerminalPaymentSucceeded) }) mux.Post("/api/forgot-password", app.SendPasswordResetEmail) + mux.Post("/api/reset-password", app.ResetPassword) return mux } diff --git a/cmd/api/templates/password-reset.html.gohtml b/cmd/api/templates/password-reset.html.gohtml index 3112a85..0db7510 100644 --- a/cmd/api/templates/password-reset.html.gohtml +++ b/cmd/api/templates/password-reset.html.gohtml @@ -12,6 +12,7 @@
+This link expires in 10 minutes.
--
diff --git a/cmd/api/templates/password-reset.plain.gohtml b/cmd/api/templates/password-reset.plain.gohtml
index dc29f44..8e01d91 100644
--- a/cmd/api/templates/password-reset.plain.gohtml
+++ b/cmd/api/templates/password-reset.plain.gohtml
@@ -7,6 +7,8 @@ Click on the link below to get started:
{{.Link}}
+This link expires in 10 minutes.
+
--
Widget Co.
{{ end }}
diff --git a/cmd/web/handlers.go b/cmd/web/handlers.go
index e50fcbb..7e8e77c 100644
--- a/cmd/web/handlers.go
+++ b/cmd/web/handlers.go
@@ -340,6 +340,13 @@ func (app *application) ShowResetPassword(w http.ResponseWriter, r *http.Request
return
}
+ // make sure not expired
+ expired := signer.Expired(testURL, 10)
+ if expired {
+ app.errorLog.Println("Link expired")
+ return
+ }
+
data := make(map[string]interface{})
data["email"] = r.URL.Query().Get("email")
if err := app.renderTemplate(w, r, "reset-password", &templateData{
diff --git a/cmd/web/templates/reset-password.page.gohtml b/cmd/web/templates/reset-password.page.gohtml
index d6f36fe..222df50 100644
--- a/cmd/web/templates/reset-password.page.gohtml
+++ b/cmd/web/templates/reset-password.page.gohtml
@@ -44,7 +44,7 @@ Reset Password
{{end}}
diff --git a/internal/models/models.go b/internal/models/models.go
index 472d21e..468937e 100644
--- a/internal/models/models.go
+++ b/internal/models/models.go
@@ -280,3 +280,16 @@ func (m *DBModel) Authenticate(email, password string) (int, error) {
return id, nil
}
+
+func (m *DBModel) UpdatePasswordForUser(u User, hash string) error {
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
+ defer cancel()
+
+ stmt := `UPDATE users SET password = ? where id = ?`
+
+ _, err := m.DB.ExecContext(ctx, stmt, hash, u.ID)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/static/js/login.js b/static/js/login.js
index 6d22359..2a4b67d 100644
--- a/static/js/login.js
+++ b/static/js/login.js
@@ -81,7 +81,7 @@ export function forgot(api) {
});
}
-export function reset(api) {
+export function reset(api, email) {
let form = document.getElementById("reset-form");
if (form.checkValidity() === false) {
@@ -98,7 +98,8 @@ export function reset(api) {
}
let payload = {
- email: document.getElementById("email").value,
+ password: document.getElementById("password").value,
+ email: email,
};
const requestOptions = {
@@ -116,6 +117,9 @@ export function reset(api) {
console.log(response)
if (response.error === false) {
showSuccess("reset-messages", "Password reset")
+ setTimeout(function () {
+ location.href = "/login"
+ }, 2000)
} else {
showError("reset-messages", response.message)
}