feat: recover password & refresh token

This commit is contained in:
2025-07-20 18:06:05 +01:00
parent 57730270a0
commit f85191b918
26 changed files with 748 additions and 332 deletions
+56 -10
View File
@@ -30,13 +30,13 @@ const roleContextKey roleKey = "role"
// @Security ApiKeyAuth
// @Router /admin/users [get]
func (api *api) getUsersHandler(w http.ResponseWriter, r *http.Request) {
role := getRoleFromContext(r)
isAdmin := false
if role.Level == 3 {
isAdmin = true
user := getUserFromContext(r)
if user == nil {
api.unauthorizedError(w, r, errors.New("user not found"))
return
}
users, err := api.store.Users.GetAll(r.Context(), isAdmin)
users, err := api.store.Users.GetAll(r.Context(), user.ID, user.Role.Level)
if err != nil {
api.internalServerError(w, r, err)
return
@@ -84,6 +84,57 @@ func (api *api) getUserHandler(w http.ResponseWriter, r *http.Request) {
}
}
type resetPasswordPayload struct {
NewPassword string `json:"new_password" validate:"required,password"`
NewPasswordConfirmation string `json:"new_password_confirmation" validate:"required,eqfield=NewPassword"`
}
// ResetPassword godoc
//
// @Summary Reset user password
// @Description Reset user password with verification
// @Tags users
// @Accept json
// @Param payload body resetPasswordPayload true "Reset Password"
// @Param token path string true "Reset Password Token"
// @Success 204 {string} string "Password reset successfully"
// @Failure 400 {object} error "Invalid request"
// @Failure 401 {object} error "Unauthorized"
// @Failure 500 {object} error "Internal server error"
// @Security ApiKeyAuth
// @Router /users/reset-password/{token} [put]
func (api *api) resetPasswordHandler(w http.ResponseWriter, r *http.Request) {
token := chi.URLParam(r, "token")
var payload resetPasswordPayload
if err := readJSON(w, r, &payload); err != nil {
api.badRequestError(w, r, err)
return
}
if err := Validate.Struct(payload); err != nil {
api.badRequestError(w, r, err)
return
}
err := api.store.Users.ResetPassword(r.Context(), token, payload.NewPassword)
if err != nil {
switch err {
case store.ErrNotFound:
api.notFoundError(w, r, err)
return
default:
api.internalServerError(w, r, err)
return
}
}
w.WriteHeader(http.StatusNoContent)
if err := api.jsonResponse(w, http.StatusNoContent, ""); err != nil {
api.internalServerError(w, r, err)
}
}
type updateUserPayload struct {
FirstName *string `json:"first_name" validate:"omitempty,max=100"`
LastName *string `json:"last_name" validate:"omitempty,max=100"`
@@ -331,8 +382,3 @@ func getUserFromContext(r *http.Request) *store.User {
user, _ := r.Context().Value(userContextKey).(*store.User)
return user
}
func getRoleFromContext(r *http.Request) *store.Role {
role, _ := r.Context().Value(roleContextKey).(*store.Role)
return role
}