diff --git a/front/app/_orgs/[orgslug]/settings/account/passwords/page.tsx b/front/app/_orgs/[orgslug]/settings/account/passwords/page.tsx new file mode 100644 index 00000000..9fc62bfe --- /dev/null +++ b/front/app/_orgs/[orgslug]/settings/account/passwords/page.tsx @@ -0,0 +1,56 @@ +"use client"; +import { AuthContext } from '@components/Security/AuthProvider'; +import React, { useEffect } from 'react' +import { Formik, Form, Field, ErrorMessage } from 'formik'; +import { updateProfile } from '@services/settings/profile'; +import { updatePassword } from '@services/settings/password'; + +function SettingsProfilePasswordsPage() { + + const auth: any = React.useContext(AuthContext); + + const updatePasswordUI = async (values: any) => { + let user_id = auth.userInfo.user_object.user_id; + console.log(values); + await updatePassword(user_id, values) + } + + + return ( +
+ + {auth.isAuthenticated && ( +
+

Account Password

+

+ + { + setTimeout(() => { + alert(JSON.stringify(values, null, 2)); + setSubmitting(false); + updatePasswordUI(values) + }, 400); + }} + > + {({ isSubmitting }) => ( +
+ Old Password
+ New password
+ + + )} +
+
+ )} + + +
+ + ) +} + +export default SettingsProfilePasswordsPage \ No newline at end of file diff --git a/front/services/settings/password.ts b/front/services/settings/password.ts new file mode 100644 index 00000000..3f1c00b4 --- /dev/null +++ b/front/services/settings/password.ts @@ -0,0 +1,15 @@ +import { getAPIUrl } from "@services/config"; +import { RequestBody } from "@services/utils/requests"; + +/* + This file includes only POST, PUT, DELETE requests + GET requests are called from the frontend using SWR (https://swr.vercel.app/) +*/ + +export async function updatePassword(user_id : string, data: any) { + const result: any = await fetch(`${getAPIUrl()}users/password/user_id/` + user_id, RequestBody("PUT", data)) + .then((result) => result.json()) + .catch((error) => console.log("error", error)); + + return result; +} diff --git a/src/routers/users.py b/src/routers/users.py index 3cdae9b1..6a600bd5 100644 --- a/src/routers/users.py +++ b/src/routers/users.py @@ -64,3 +64,10 @@ async def api_update_user(request: Request, user_object: User, user_id: str): Update user by ID """ return await update_user(request, user_id, user_object) + +@router.put("/password/user_id/{user_id}") +async def api_update_user_password(request: Request, user_id: str , passwordChangeForm : PasswordChangeForm): + """ + Update user password by ID + """ + return await update_user_password(request, user_id, passwordChangeForm) diff --git a/src/services/users.py b/src/services/users.py index a712e832..ccc84ca8 100644 --- a/src/services/users.py +++ b/src/services/users.py @@ -27,6 +27,10 @@ class PublicUser(User): creationDate: str updateDate: str +class PasswordChangeForm(BaseModel): + old_password: str + new_password: str + class UserInDB(UserWithPassword): user_id: str @@ -157,6 +161,27 @@ async def update_user(request: Request, user_id: str, user_object: User): return User(**user_object.dict()) +async def update_user_password(request: Request, user_id: str, password_change_form: PasswordChangeForm): + users = request.app.db["users"] + + isUserExists = await users.find_one({"user_id": user_id}) + + if not isUserExists: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, detail="User does not exist") + + if not await security_verify_password(password_change_form.old_password, isUserExists["password"]): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail="Wrong password") + + new_password = await security_hash_password(password_change_form.new_password) + + updated_user = {"$set": {"password": new_password}} + users.update_one({"user_id": user_id}, updated_user) + + return {"detail": "Password updated"} + + async def delete_user(request: Request, user_id: str): users = request.app.db["users"]