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 }) => (
+
+ )}
+
+
+ )}
+
+
+
+
+ )
+}
+
+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"]