diff --git a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java index 7870f5f7..edf13fcf 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java @@ -266,6 +266,8 @@ public void changePassword(int teamMemberId, String oldPassword, String newPassw String salt = teamMember.getAuthInfo().getSalt(); String newHashedPassword = AuthInfoService.hashPassword(newPassword, salt); teamMember.getAuthInfo().setHashedPassword(newHashedPassword); + }else{ + throw new RuntimeException("password is incorrect" + oldPassword); } } diff --git a/frontend/react-app/src/App.js b/frontend/react-app/src/App.js index 73357622..992a8fb4 100644 --- a/frontend/react-app/src/App.js +++ b/frontend/react-app/src/App.js @@ -15,6 +15,7 @@ import ProtectedRoute from './components/ProtectedRoute'; import CreateAccount from './pages/CreateAccount'; import AdminPanel from './pages/AdminPanel'; import CreateTask from './pages/CreateTask'; +import ChangePassword from './pages/ChangePassword'; function App() { @@ -34,7 +35,8 @@ function App() { } urlReirect={"/login"}>}/> } urlReirect={"/login"}>}/> } urlReirect={"/home"}>}/> - + } urlReirect={"/login"}>}/> + {/*Default path should be login, unless specified */} } /> diff --git a/frontend/react-app/src/api/teamMemberApi.js b/frontend/react-app/src/api/teamMemberApi.js index d6a985f8..c73822c5 100644 --- a/frontend/react-app/src/api/teamMemberApi.js +++ b/frontend/react-app/src/api/teamMemberApi.js @@ -111,6 +111,7 @@ export const massAssignMemberToTask = async(taskId, teamMemberIds) => { //Change password export const changePassword = async (teamMemberId, oldPassword, newPassword) => { try { + console.log(JSON.stringify({oldPassword, newPassword})) const response = await fetch(`${BASE_URL}/team-members/${teamMemberId}/change-password`, { method: 'POST', headers: { "Content-Type": "application/json" }, @@ -122,7 +123,7 @@ export const changePassword = async (teamMemberId, oldPassword, newPassword) => return null; } - return await response.json(); + return await true; } catch (error) { console.error("Error changing password: ", error); @@ -144,7 +145,7 @@ export const resetPassword = async (teamMemberId, newPassword) => { return null; } - return await response.json(); + return await true; } catch (error) { console.error("Error resetting password: ", error); diff --git a/frontend/react-app/src/components/CreateAccountForm.jsx b/frontend/react-app/src/components/CreateAccountForm.jsx index c6cdc61c..cd7cac71 100644 --- a/frontend/react-app/src/components/CreateAccountForm.jsx +++ b/frontend/react-app/src/components/CreateAccountForm.jsx @@ -86,7 +86,7 @@ export default function CreateAccountForm({teams}){ } })} /> - @@ -95,6 +95,7 @@ export default function CreateAccountForm({teams}){ control={control} defaultValue={[]} className='Select' + id = 'selectTeam' name="teams" rules={{required:true}} render={({field}) => ( diff --git a/frontend/react-app/src/css/ChangePassword.css b/frontend/react-app/src/css/ChangePassword.css new file mode 100644 index 00000000..9cf84c14 --- /dev/null +++ b/frontend/react-app/src/css/ChangePassword.css @@ -0,0 +1,41 @@ +.changePassSumbitButton{ + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; + font-size: 1em; + margin-top: 20px; + margin-bottom: 20px; + border: none; + border-radius: 10px; + color: white; + background-color: #3f5d8b; +} +.changePassSumbitButton:hover { + cursor: pointer; + background-color: #2f486d; +} +.changePasswordInput{ + width: 65vw; + height: 7vh; + min-width: 100px; + max-width: 100%; + min-height: 30px; + max-height: 100%; + border: 2px solid grey; + border-radius: 10px; + padding-left: 8px; + background-color: #BFCDE0; + margin: 10px 0px; +} +.formContainer{ + display: flex; + flex-direction: column; + align-items: center; + height: 100%; + justify-content: center; + font-family: Arial, Helvetica, sans-serif; + background-color: #BFCDE0; + border: none; + border-radius: 10px; +} diff --git a/frontend/react-app/src/pages/ChangePassword.jsx b/frontend/react-app/src/pages/ChangePassword.jsx new file mode 100644 index 00000000..147db6ae --- /dev/null +++ b/frontend/react-app/src/pages/ChangePassword.jsx @@ -0,0 +1,86 @@ +import { useCookies } from 'react-cookie'; +import Header from '../components/Header' +import {useForm} from 'react-hook-form' +import { changePassword } from '../api/teamMemberApi'; +import '../css/ChangePassword.css' +import { useState } from 'react'; +export default function ChangePassword(){ + const {register, handleSubmit, formState: {errors}} = useForm(); + const [cookies, removeCookie] = useCookies(['userInfo']) + const onSubmit = async(data)=>{ + try { + if(data.newPassword === data.conNewPassword && data.newPassword !== ''){ + const changePass = await changePassword(cookies.userInfo.accountId, data.oldPassword, data.newPassword); + if(changePass){ + await alert("Your password has been changed") + removeCookie("userInfo"); + window.location.href="/login"; + }else{ + await alert("Failed to change password") + } + }else{ + alert("THOSE PASSWORDS DON'T MATCH") + } + } catch (error) { + console.log(error) + } + + + } + + + return( +
+
+
+
+
+ Change Password +
+ + + + + + +
+
+
+ ) + +} + + diff --git a/frontend/react-app/src/pages/Profile.jsx b/frontend/react-app/src/pages/Profile.jsx index fbe28de2..bbb478e4 100644 --- a/frontend/react-app/src/pages/Profile.jsx +++ b/frontend/react-app/src/pages/Profile.jsx @@ -23,6 +23,9 @@ function Profile(){ ))} + diff --git a/frontend/react-app/src/tests/CreateAccountForm.test.js b/frontend/react-app/src/tests/CreateAccountForm.test.js index dae4385d..5e00ffda 100644 --- a/frontend/react-app/src/tests/CreateAccountForm.test.js +++ b/frontend/react-app/src/tests/CreateAccountForm.test.js @@ -1,5 +1,10 @@ import { fireEvent, render, screen} from "@testing-library/react" import CreateAccountForm from "../components/CreateAccountForm" +const team =[{ + value: 1, + label:'thisTeam', + name: 'thisTeam' +}] test('Testing Form To see if onSumbit runs',()=>{ render() let consoleLog = jest.spyOn(console, 'log'); @@ -7,9 +12,12 @@ test('Testing Form To see if onSumbit runs',()=>{ const inputEmail = screen.getByPlaceholderText('Email'); const inputPassword = screen.getByPlaceholderText('Password'); const sumbit = document.getElementById('createAccountSumbitButton'); + const selectRole = document.getElementById('selectorRole'); + const selectTeam = document.getElementById('selectTeam'); fireEvent.change(inputUserName, { target: { value: 'test' } }); fireEvent.change(inputEmail, { target: { value: 'test@gmail.com' } }); fireEvent.change(inputPassword, { target: { value: 'test' } }); + fireEvent.change(selectRole,{target:{value:'Admin'}}); fireEvent.click(sumbit) expect(consoleLog == JSON.stringify({username:'test',email:'test@gmail.com', password:'test'})) diff --git a/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js b/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js index a0e6fb22..77f3f182 100644 --- a/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js @@ -130,7 +130,7 @@ describe('Team Member API', () => { //test: changing a password test('chanegPassword should return success on valid password change', async () => { - const mockResponse = { sucess: true }; + const mockResponse = true; fetch.mockResponseOnce(JSON.stringify(mockResponse), { status: 200 }); @@ -147,7 +147,7 @@ describe('Team Member API', () => { //test: resetting a password test('resetPassword should return success on valid password reset', async () => { - const mockResponse = { success: true }; + const mockResponse = true; fetch.mockResponseOnce(JSON.stringify(mockResponse), { status: 200 });