From 33af108d39d90a0d33f62441985aa6ccb3cfdd62 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Mon, 26 Feb 2024 11:04:05 -0500 Subject: [PATCH] feat: add password reset endpoints --- api/account/account.go | 56 +++++++++++++++++++++++++++++++++++------ api/account/messages.go | 8 ++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/api/account/account.go b/api/account/account.go index ebba18f..b8f74ec 100644 --- a/api/account/account.go +++ b/api/account/account.go @@ -217,6 +217,46 @@ func (a AccountAPI) otpDisable(jc jape.Context) { } } +func (a AccountAPI) passwordResetRequest(jc jape.Context) { + var request PasswordResetRequest + + if jc.Decode(&request) != nil { + return + } + + exists, user, err := a.accounts.EmailExists(request.Email) + if jc.Check("invalid request", err) != nil || !exists { + return + } + + err = a.accounts.SendPasswordReset(user) + if jc.Check("failed to request password reset", err) != nil { + return + } + + jc.ResponseWriter.WriteHeader(http.StatusOK) +} + +func (a AccountAPI) passwordResetConfirm(jc jape.Context) { + var request PasswordResetVerifyRequest + + if jc.Decode(&request) != nil { + return + } + + exists, _, err := a.accounts.EmailExists(request.Email) + if jc.Check("invalid request", err) != nil || !exists { + return + } + + err = a.accounts.ResetPassword(request.Email, request.Password, request.Token) + if jc.Check("failed to reset password", err) != nil { + return + } + + jc.ResponseWriter.WriteHeader(http.StatusOK) +} + func (a AccountAPI) Routes() (*httprouter.Router, error) { authMw2fa := authMiddleware(middleware.AuthMiddlewareOptions{ Identity: a.identity, @@ -233,13 +273,15 @@ func (a AccountAPI) Routes() (*httprouter.Router, error) { }) return jape.Mux(map[string]jape.Handler{ - "POST /api/auth/login": middleware.ApplyMiddlewares(a.login, authMw2fa, middleware.ProxyMiddleware), - "POST /api/auth/register": middleware.ApplyMiddlewares(a.register, middleware.ProxyMiddleware), - "POST /api/auth/verify-email": middleware.ApplyMiddlewares(a.verifyEmail, middleware.ProxyMiddleware), - "GET /api/auth/otp/generate": middleware.ApplyMiddlewares(a.otpGenerate, authMw, middleware.ProxyMiddleware), - "POST /api/auth/otp/verify": middleware.ApplyMiddlewares(a.otpVerify, authMw, middleware.ProxyMiddleware), - "POST /api/auth/otp/validate": middleware.ApplyMiddlewares(a.otpValidate, authMw, middleware.ProxyMiddleware), - "POST /api/auth/otp/disable": middleware.ApplyMiddlewares(a.otpDisable, authMw, middleware.ProxyMiddleware), + "POST /api/auth/login": middleware.ApplyMiddlewares(a.login, authMw2fa, middleware.ProxyMiddleware), + "POST /api/auth/register": middleware.ApplyMiddlewares(a.register, middleware.ProxyMiddleware), + "POST /api/auth/verify-email": middleware.ApplyMiddlewares(a.verifyEmail, middleware.ProxyMiddleware), + "GET /api/auth/otp/generate": middleware.ApplyMiddlewares(a.otpGenerate, authMw, middleware.ProxyMiddleware), + "POST /api/auth/otp/verify": middleware.ApplyMiddlewares(a.otpVerify, authMw, middleware.ProxyMiddleware), + "POST /api/auth/otp/validate": middleware.ApplyMiddlewares(a.otpValidate, authMw, middleware.ProxyMiddleware), + "POST /api/auth/otp/disable": middleware.ApplyMiddlewares(a.otpDisable, authMw, middleware.ProxyMiddleware), + "POST /api/auth/password-reset/request": middleware.ApplyMiddlewares(a.passwordResetRequest, middleware.ProxyMiddleware), + "POST /api/auth/password-reset/confirm": middleware.ApplyMiddlewares(a.passwordResetConfirm, middleware.ProxyMiddleware), }), nil } func (a AccountAPI) Can(w http.ResponseWriter, r *http.Request) bool { diff --git a/api/account/messages.go b/api/account/messages.go index 071ec02..a03b9d2 100644 --- a/api/account/messages.go +++ b/api/account/messages.go @@ -30,3 +30,11 @@ type VerifyEmailRequest struct { Email string `json:"email"` Token string `json:"token"` } +type PasswordResetRequest struct { + Email string `json:"email"` +} +type PasswordResetVerifyRequest struct { + Email string `json:"email"` + Token string `json:"token"` + Password string `json:"password"` +}