mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-31 10:37:13 -04:00 
			
		
		
		
	Add edit password
This commit is contained in:
		
							parent
							
								
									dbe8e319c8
								
							
						
					
					
						commit
						31d545530b
					
				| @ -12,6 +12,23 @@ import ( | ||||
| 	"github.com/google/uuid" | ||||
| ) | ||||
| 
 | ||||
| const clearOtherSessions = `-- name: ClearOtherSessions :exec | ||||
| delete from sessions as s using users as u | ||||
| where s.user_pk = u.pk | ||||
| 	and s.id != $1 | ||||
| 	and u.id = $2 | ||||
| ` | ||||
| 
 | ||||
| type ClearOtherSessionsParams struct { | ||||
| 	SessionId uuid.UUID `json:"sessionId"` | ||||
| 	UserId    uuid.UUID `json:"userId"` | ||||
| } | ||||
| 
 | ||||
| func (q *Queries) ClearOtherSessions(ctx context.Context, arg ClearOtherSessionsParams) error { | ||||
| 	_, err := q.db.Exec(ctx, clearOtherSessions, arg.SessionId, arg.UserId) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| const createSession = `-- name: CreateSession :one | ||||
| insert into sessions(token, user_pk, device) | ||||
| 	values ($1, $2, $3) | ||||
|  | ||||
| @ -417,6 +417,60 @@ const docTemplate = `{ | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     }, | ||||
|                     "422": { | ||||
|                         "description": "Invalid body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/users/me/password": { | ||||
|             "patch": { | ||||
|                 "security": [ | ||||
|                     { | ||||
|                         "Jwt": [] | ||||
|                     } | ||||
|                 ], | ||||
|                 "description": "Edit your password", | ||||
|                 "consumes": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "produces": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "tags": [ | ||||
|                     "users" | ||||
|                 ], | ||||
|                 "summary": "Edit password", | ||||
|                 "parameters": [ | ||||
|                     { | ||||
|                         "type": "boolean", | ||||
|                         "default": true, | ||||
|                         "description": "Invalidate other sessions", | ||||
|                         "name": "invalidate", | ||||
|                         "in": "query" | ||||
|                     }, | ||||
|                     { | ||||
|                         "description": "New password", | ||||
|                         "name": "user", | ||||
|                         "in": "body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.EditPasswordDto" | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 "responses": { | ||||
|                     "204": { | ||||
|                         "description": "No Content" | ||||
|                     }, | ||||
|                     "422": { | ||||
|                         "description": "Invalid body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @ -535,7 +589,7 @@ const docTemplate = `{ | ||||
|                     { | ||||
|                         "type": "string", | ||||
|                         "format": "uuid", | ||||
|                         "description": "User id of the user to delete", | ||||
|                         "description": "User id of the user to edit", | ||||
|                         "name": "id", | ||||
|                         "in": "path" | ||||
|                     }, | ||||
| @ -560,12 +614,30 @@ const docTemplate = `{ | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     }, | ||||
|                     "422": { | ||||
|                         "description": "Invalid body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "definitions": { | ||||
|         "main.EditPasswordDto": { | ||||
|             "type": "object", | ||||
|             "required": [ | ||||
|                 "password" | ||||
|             ], | ||||
|             "properties": { | ||||
|                 "password": { | ||||
|                     "type": "string", | ||||
|                     "example": "password1234" | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "main.EditUserDto": { | ||||
|             "type": "object", | ||||
|             "properties": { | ||||
|  | ||||
| @ -411,6 +411,60 @@ | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     }, | ||||
|                     "422": { | ||||
|                         "description": "Invalid body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/users/me/password": { | ||||
|             "patch": { | ||||
|                 "security": [ | ||||
|                     { | ||||
|                         "Jwt": [] | ||||
|                     } | ||||
|                 ], | ||||
|                 "description": "Edit your password", | ||||
|                 "consumes": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "produces": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "tags": [ | ||||
|                     "users" | ||||
|                 ], | ||||
|                 "summary": "Edit password", | ||||
|                 "parameters": [ | ||||
|                     { | ||||
|                         "type": "boolean", | ||||
|                         "default": true, | ||||
|                         "description": "Invalidate other sessions", | ||||
|                         "name": "invalidate", | ||||
|                         "in": "query" | ||||
|                     }, | ||||
|                     { | ||||
|                         "description": "New password", | ||||
|                         "name": "user", | ||||
|                         "in": "body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.EditPasswordDto" | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 "responses": { | ||||
|                     "204": { | ||||
|                         "description": "No Content" | ||||
|                     }, | ||||
|                     "422": { | ||||
|                         "description": "Invalid body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @ -529,7 +583,7 @@ | ||||
|                     { | ||||
|                         "type": "string", | ||||
|                         "format": "uuid", | ||||
|                         "description": "User id of the user to delete", | ||||
|                         "description": "User id of the user to edit", | ||||
|                         "name": "id", | ||||
|                         "in": "path" | ||||
|                     }, | ||||
| @ -554,12 +608,30 @@ | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     }, | ||||
|                     "422": { | ||||
|                         "description": "Invalid body", | ||||
|                         "schema": { | ||||
|                             "$ref": "#/definitions/main.KError" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "definitions": { | ||||
|         "main.EditPasswordDto": { | ||||
|             "type": "object", | ||||
|             "required": [ | ||||
|                 "password" | ||||
|             ], | ||||
|             "properties": { | ||||
|                 "password": { | ||||
|                     "type": "string", | ||||
|                     "example": "password1234" | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "main.EditUserDto": { | ||||
|             "type": "object", | ||||
|             "properties": { | ||||
|  | ||||
| @ -217,6 +217,7 @@ func main() { | ||||
| 	r.DELETE("/users/me", h.DeleteSelf) | ||||
| 	r.PATCH("/users/:id", h.EditUser) | ||||
| 	r.PATCH("/users/me", h.EditSelf) | ||||
| 	r.PATCH("/users/me/password", h.ChangePassword) | ||||
| 	g.POST("/users", h.Register) | ||||
| 
 | ||||
| 	g.POST("/sessions", h.Login) | ||||
|  | ||||
| @ -43,3 +43,8 @@ where s.user_pk = u.pk | ||||
| returning | ||||
| 	s.*; | ||||
| 
 | ||||
| -- name: ClearOtherSessions :exec | ||||
| delete from sessions as s using users as u | ||||
| where s.user_pk = u.pk | ||||
| 	and s.id != @session_id | ||||
| 	and u.id = @user_id; | ||||
|  | ||||
| @ -58,6 +58,10 @@ type EditUserDto struct { | ||||
| 	Claims   jwt.MapClaims `json:"claims,omitempty" example:"preferOriginal: true"` | ||||
| } | ||||
| 
 | ||||
| type EditPasswordDto struct { | ||||
| 	Password string `json:"password" validate:"required" example:"password1234"` | ||||
| } | ||||
| 
 | ||||
| func MapDbUser(user *dbc.User) User { | ||||
| 	return User{ | ||||
| 		Pk:          user.Pk, | ||||
| @ -293,6 +297,7 @@ func (h *Handler) DeleteSelf(c echo.Context) error { | ||||
| // @Param        user     body  EditUserDto  false  "Edited user info" | ||||
| // @Success      200  {object}  User | ||||
| // @Success      403  {object}  KError  "You can't edit a protected claim" | ||||
| // @Success      422  {object}  KError  "Invalid body" | ||||
| // @Router /users/me [patch] | ||||
| func (h *Handler) EditSelf(c echo.Context) error { | ||||
| 	var req EditUserDto | ||||
| @ -340,6 +345,7 @@ func (h *Handler) EditSelf(c echo.Context) error { | ||||
| // @Param        user     body  EditUserDto  false  "Edited user info" | ||||
| // @Success      200  {object}  User | ||||
| // @Success      403  {object}  KError  "You don't have permissions to edit another account" | ||||
| // @Success      422  {object}  KError  "Invalid body" | ||||
| // @Router /users/{id} [patch] | ||||
| func (h *Handler) EditUser(c echo.Context) error { | ||||
| 	err := CheckPermissions(c, []string{"user.write"}) | ||||
| @ -375,3 +381,55 @@ func (h *Handler) EditUser(c echo.Context) error { | ||||
| 
 | ||||
| 	return c.JSON(200, MapDbUser(&ret)) | ||||
| } | ||||
| 
 | ||||
| // @Summary      Edit password | ||||
| // @Description  Edit your password | ||||
| // @Tags         users | ||||
| // @Accept       json | ||||
| // @Produce      json | ||||
| // @Security     Jwt | ||||
| // @Param        invalidate  query  bool  false  "Invalidate other sessions" default(true) | ||||
| // @Param        user     body  EditPasswordDto  false  "New password" | ||||
| // @Success      204 | ||||
| // @Success      422  {object}  KError  "Invalid body" | ||||
| // @Router /users/me/password [patch] | ||||
| func (h *Handler) ChangePassword(c echo.Context) error { | ||||
| 	uid, err := GetCurrentUserId(c) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	sid, err := GetCurrentSessionId(c) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	var req EditPasswordDto | ||||
| 	err = c.Bind(&req) | ||||
| 	if err != nil { | ||||
| 		return echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error()) | ||||
| 	} | ||||
| 	if err = c.Validate(&req); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	_, err = h.db.UpdateUser(context.Background(), dbc.UpdateUserParams{ | ||||
| 		Id:       uid, | ||||
| 		Password: &req.Password, | ||||
| 	}) | ||||
| 	if err == pgx.ErrNoRows { | ||||
| 		return echo.NewHTTPError(http.StatusNotFound, "Invalid token, user not found") | ||||
| 	} else if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	err = h.db.ClearOtherSessions(context.Background(), dbc.ClearOtherSessionsParams{ | ||||
| 		SessionId: sid, | ||||
| 		UserId:    uid, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return c.NoContent(http.StatusNoContent) | ||||
| } | ||||
|  | ||||
| @ -28,6 +28,32 @@ func GetCurrentUserId(c echo.Context) (uuid.UUID, error) { | ||||
| 	return ret, nil | ||||
| } | ||||
| 
 | ||||
| func GetCurrentSessionId(c echo.Context) (uuid.UUID, error) { | ||||
| 	user := c.Get("user").(*jwt.Token) | ||||
| 	if user == nil { | ||||
| 		return uuid.UUID{}, echo.NewHTTPError(401, "Unauthorized") | ||||
| 	} | ||||
| 	claims, ok := user.Claims.(jwt.MapClaims) | ||||
| 	if !ok { | ||||
| 		return uuid.UUID{}, echo.NewHTTPError(403, "Could not retrieve claims") | ||||
| 	} | ||||
| 	sid, ok := claims["sid"] | ||||
| 	if !ok { | ||||
| 		return uuid.UUID{}, echo.NewHTTPError(403, "Could not retrieve session") | ||||
| 	} | ||||
| 
 | ||||
| 	sid_str, ok := sid.(string) | ||||
| 	if !ok { | ||||
| 		return uuid.UUID{}, echo.NewHTTPError(403, "Invalid session id claim.") | ||||
| 	} | ||||
| 
 | ||||
| 	ret, err := uuid.Parse(sid_str) | ||||
| 	if err != nil { | ||||
| 		return uuid.UUID{}, echo.NewHTTPError(403, "Invalid id") | ||||
| 	} | ||||
| 	return ret, nil | ||||
| } | ||||
| 
 | ||||
| func CheckPermissions(c echo.Context, perms []string) error { | ||||
| 	token, ok := c.Get("user").(*jwt.Token) | ||||
| 	if !ok { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user