diff --git a/backend/index.js b/backend/index.js index be7b6f5..c020d78 100644 --- a/backend/index.js +++ b/backend/index.js @@ -296,7 +296,7 @@ app.get('/API/resourcelist', function (req, res) { app.post("/API/user/setname", async function (req, res) { let { email, password } = req.body; if (email && password) { - if (DEBUG) return res.status(status.OK).send(); + if (DEBUG) return res.status(status.OK).send("username changed"); try { if (!await validatePassword(req.user.email, password)) return res.status(status.UNAUTHORIZED).send("wrong password supplied"); @@ -317,7 +317,7 @@ app.post("/API/user/setname", async function (req, res) { app.post("/API/user/setpassword", async function (req, res) { let { oldpassword, newpassword } = req.body; if (oldpassword && newpassword) { - if (DEBUG) return res.status(status.OK).send(); + if (DEBUG) return res.status(status.OK).send("password changed"); try { if (!await validatePassword(req.user.email, oldpassword)) return res.status(status.UNAUTHORIZED).send("wrong password supplied"); @@ -326,8 +326,8 @@ app.post("/API/user/setpassword", async function (req, res) { } connection.query(`UPDATE user SET password = ${mysql.escape(bcrypt.hashSync(newpassword, saltRounds))} WHERE email = ${mysql.escape(req.user.email)}`, function (err, rows) { if (err) - return res.status(status.INTERNAL_SERVER_ERROR).send("the username seems invalid or already taken - if you think this is an error contact the sys admin"); - return res.status(status.OK).send("username changed"); + return res.status(status.INTERNAL_SERVER_ERROR).send("the password could not be set - if you think this is an error contact the sys admin"); + return res.status(status.OK).send("password changed"); }); } else { return res.status(status.BAD_REQUEST).send("invalid data supplied"); diff --git a/frontend/src/App.js b/frontend/src/App.js index 237a6f9..668facf 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -22,7 +22,7 @@ class ProtectedRoute extends Component { async componentWillMount() { const url = "/simcompanies/API/testlogin"; const response = await fetch(url); - if (response.status == "200") { + if (response.status === 200) { this.setState({ auth: true }); @@ -59,7 +59,7 @@ class CheckRoute extends Component { async componentWillMount() { const url = "/simcompanies/API/testlogin"; const response = await fetch(url); - if (response.status == "200") { + if (response.status === 200) { this.setState({ auth: true }); diff --git a/frontend/src/components/login/createAccount.js b/frontend/src/components/login/createAccount.js index 3f3ed5f..8320467 100644 --- a/frontend/src/components/login/createAccount.js +++ b/frontend/src/components/login/createAccount.js @@ -1,5 +1,4 @@ import React from 'react'; -import { Link } from "react-router-dom"; import { makeStyles, withStyles } from '@material-ui/core/styles'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; @@ -84,7 +83,7 @@ export default function CreateAccount() { const text = await response.text() await setStatusText(text) setStatus(response.status) - if (response.status == "200") { + if (response.status === 200) { setTimeout(() => { setLogin(false) }, 2000) } setDisabled(false) @@ -139,7 +138,7 @@ export default function CreateAccount() { { setLogin(false) }, 2000) } @@ -149,7 +149,7 @@ export default function Login() { { - if (login != props.login) { + if (login !== props.login) { setChange(true) setOpen(true) setOpen1(true) @@ -31,7 +31,7 @@ export default function LoginFeedback(props) { }; const snack = (login) => { - if (login == "200") { + if (login === 200) { setOutput( @@ -52,7 +52,7 @@ export default function LoginFeedback(props) { setChange(false) } - if (change == true) { + if (change === true) { snack(login) } diff --git a/frontend/src/components/navigation.js b/frontend/src/components/navigation.js index 5956fe4..d9c3440 100644 --- a/frontend/src/components/navigation.js +++ b/frontend/src/components/navigation.js @@ -17,16 +17,11 @@ import Footer from "./footer"; import Content from "./content" import Link1 from '@material-ui/core/Link'; import { Link } from "react-router-dom"; -import SearchIcon from '@material-ui/icons/Search'; -import InputBase from '@material-ui/core/InputBase'; import EmojiObjectsIcon from '@material-ui/icons/EmojiObjects'; import { ListItemIcon } from '@material-ui/core'; import Tooltip from '@material-ui/core/Tooltip'; import Zoom from '@material-ui/core/Zoom'; import ApartmentIcon from '@material-ui/icons/Apartment'; -import MenuItem from '@material-ui/core/MenuItem'; -import Menu from '@material-ui/core/Menu'; -import AccountCircle from '@material-ui/icons/AccountCircle'; import AccountMenu from './accountMenu/accountMenu'; const drawerWidth = 64; diff --git a/frontend/src/components/profile/changePassword.js b/frontend/src/components/profile/changePassword.js new file mode 100644 index 0000000..dd42ca5 --- /dev/null +++ b/frontend/src/components/profile/changePassword.js @@ -0,0 +1,166 @@ +import React, { useEffect } from 'react'; +import Typography from '@material-ui/core/Typography'; +import Grid from '@material-ui/core/Grid'; +import Button from '@material-ui/core/Button'; +import TextField from '@material-ui/core/TextField'; +import LoginFeedback from '../login/loginfeedback'; +import Box from '@material-ui/core/Box'; + +export default function ChangePassword(props) { + const url = "/simcompanies/API/user/setpassword" + const [password, setPassword] = React.useState(""); + const [passwordNew, setPasswordNew] = React.useState(""); + const [passwordNew2, setPasswordNew2] = React.useState(""); + const [disabled, setDisabled] = React.useState(false); + const [error, setError] = React.useState(false); + const [statusText, setStatusText] = React.useState(null); + const [status, setStatus] = React.useState(null); + + const logout = async () => { + await fetch(`/simcompanies/API/user/logout`, { + method: 'DELETE', + mode: 'cors', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer' + }).then( + () => { window.location.reload() } + ) + } + + const postSetPassword = async (url, data) => { + + const response = await fetch(url, { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: JSON.stringify(data) + }); + + const text = await response.text() + await setStatusText(text) + setStatus(response.status) + if (response.status === 200) { + setTimeout(() => { logout() }, 2000) + } + setDisabled(false) + setTimeout(() => { setStatus(null) }, 2000) + } + + const handleClick = (e) => { + + if (passwordNew !== "" && password !== "" && passwordNew2 === passwordNew) { + setDisabled(true) + postSetPassword(url, { oldpassword: password, newpassword: passwordNew }) + + setPassword("") + setPasswordNew("") + setPasswordNew2("") + } + } + + const handleKeyDown = (e) => { + if (e.key === "Enter") { + if (passwordNew !== "" && password !== "" && passwordNew2 === passwordNew) { + setDisabled(true) + postSetPassword(url, { oldpassword: password, newpassword: passwordNew }) + + setPassword("") + setPasswordNew("") + setPasswordNew2("") + } + } + } + useEffect(() => { + if (passwordNew2 === passwordNew) { + setError(false) + } else { + setError(true) + } + }, [passwordNew, passwordNew2, setError]) + + const handleChangePWNew = (e) => { + setPasswordNew(e.target.value) + } + const handleChangePWNew2 = (e) => { + setPasswordNew2(e.target.value) + } + const handleChangePW = (e) => { + setPassword(e.target.value) + } + return ( + + + + + Change Password + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/frontend/src/components/profile/changeUsername.js b/frontend/src/components/profile/changeUsername.js new file mode 100644 index 0000000..83244c3 --- /dev/null +++ b/frontend/src/components/profile/changeUsername.js @@ -0,0 +1,135 @@ +import React from 'react'; +import Typography from '@material-ui/core/Typography'; +import Grid from '@material-ui/core/Grid'; +import Button from '@material-ui/core/Button'; +import TextField from '@material-ui/core/TextField'; +import LoginFeedback from '../login/loginfeedback'; +import Box from '@material-ui/core/Box'; + +export default function ChangeUsername(props) { + const url = "/simcompanies/API/user/setname" + const [username, setUsername] = React.useState(""); + const [password, setPassword] = React.useState(""); + const [disabled, setDisabled] = React.useState(false); + const [statusText, setStatusText] = React.useState(null); + const [status, setStatus] = React.useState(null); + + const logout = async () => { + await fetch(`/simcompanies/API/user/logout`, { + method: 'DELETE', + mode: 'cors', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer' + }).then( + () => { window.location.reload() } + ) + } + + const postSetName = async (url, data) => { + + const response = await fetch(url, { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: JSON.stringify(data) + }); + + const text = await response.text() + await setStatusText(text) + setStatus(response.status) + if (response.status === 200) { + setTimeout(() => { logout() }, 2000) + } + setDisabled(false) + setTimeout(() => { setStatus(null) }, 2000) + } + + const handleClick = (e) => { + + if (username !== "" && password !== "") { + setDisabled(true) + postSetName(url, { email: username, password: password }) + + setUsername("") + setPassword("") + } + } + + const handleKeyDown = (e) => { + if (e.key === "Enter") { + if (username !== "" && password !== "") { + setDisabled(true) + postSetName(url, { email: username, password: password }) + + setUsername("") + setPassword("") + } + } + } + + const handleChangeUSR = (e) => { + setUsername(e.target.value) + } + const handleChangePW = (e) => { + setPassword(e.target.value) + } + + return ( + + + + + Change Username + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/frontend/src/components/profile/profile.js b/frontend/src/components/profile/profile.js index 0fc1d69..f9889bf 100644 --- a/frontend/src/components/profile/profile.js +++ b/frontend/src/components/profile/profile.js @@ -1,12 +1,47 @@ import React from 'react'; import Typography from '@material-ui/core/Typography'; +import Card from '@material-ui/core/Card'; +import CardContent from '@material-ui/core/CardContent'; +import { makeStyles } from '@material-ui/core/styles'; +import Grid from '@material-ui/core/Grid'; +import ChangeUsername from './changeUsername'; +import ChangePassword from './changePassword'; + +const useStyles = makeStyles((theme) => ({ + root: { + display: 'flex', + }, + card: { + padding: 20 + } +})); export default function Profile(props) { + const classes = useStyles(); + return ( -
- - Profile Page - +
+ + + + Profile Page + + + + + + + + + + + + + + + + +
); } diff --git a/frontend/src/components/resourcechart/resourcechart.js b/frontend/src/components/resourcechart/resourcechart.js index 067df5f..4b91172 100644 --- a/frontend/src/components/resourcechart/resourcechart.js +++ b/frontend/src/components/resourcechart/resourcechart.js @@ -2,13 +2,11 @@ import React, { useEffect } from 'react'; import { useParams } from "react-router-dom"; -import CircularProgress from '@material-ui/core/CircularProgress'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; -import Button from '@material-ui/core/Button'; import Chart from './chart'; import FormHelperText from '@material-ui/core/FormHelperText'; import MenuItem from '@material-ui/core/MenuItem';