- Fixed looking up invalid profiles
- Added valid error handling to bad request && rate limiting
- Add Sendgrid library (Will add SMTP later)
- Complete password reset process
This commit is contained in:
Daniel Mason 2021-04-02 01:56:08 +13:00
parent e570314ac2
commit fd615102a8
Signed by: idanoo
GPG key ID: 387387CDBC02F132
28 changed files with 871 additions and 261 deletions

View file

@ -1,4 +1,5 @@
import React, { useContext, useState, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import '../App.css';
import './Login.css';
import { Button } from 'reactstrap';
@ -9,6 +10,7 @@ import { Switch } from 'formik-material-ui';
import { getConfigs, postConfigs } from '../Api/index'
const Admin = () => {
const history = useHistory();
const { user } = useContext(AuthContext);
const [loading, setLoading] = useState(true);
const [configs, setConfigs] = useState({})
@ -38,11 +40,7 @@ const Admin = () => {
}
if (!user || !user.admin) {
return (
<div className="pageWrapper">
<h1>Unauthorized</h1>
</div>
)
history.push("/login")
}
return (

View file

@ -8,7 +8,7 @@ import ScrobbleTable from "../Components/ScrobbleTable";
import AuthContext from '../Contexts/AuthContext';
const Dashboard = () => {
const history = useHistory();
// const history = useHistory();
let { user } = useContext(AuthContext);
let [loading, setLoading] = useState(true);
let [dashboardData, setDashboardData] = useState({});

View file

@ -16,6 +16,10 @@ const Login = () => {
history.push("/dashboard");
}
const redirectReset = () => {
history.push("/reset")
}
return (
<div className="pageWrapper">
<h1>
@ -42,7 +46,6 @@ const Login = () => {
<Field
name="password"
type="password"
required={boolTrue}
className="loginFields"
/>
</label>
@ -53,6 +56,14 @@ const Login = () => {
className="loginButton"
disabled={loading}
>{loading ? <ScaleLoader color="#FFF" size={35} /> : "Login"}</Button>
<br/><br/>
<Button
color="secondary"
type="button"
className="loginButton"
onClick={redirectReset}
disabled={loading}
>{loading ? <ScaleLoader color="#FFF" size={35} /> : "Reset Password"}</Button>
</Form>
</Formik>
</div>

View file

@ -35,7 +35,7 @@ const Profile = (route) => {
)
}
if (!username || Object.keys(profile).length === 0) {
if (!username || !profile.username) {
return (
<div className="pageWrapper">
Unable to fetch user
@ -50,7 +50,7 @@ const Profile = (route) => {
</h1>
<div className="profileBody">
Last 10 scrobbles...<br/>
<ScrobbleTable data={profile.scrobbles}/>
<ScrobbleTable data={profile.scrobbles}/>
</div>
</div>
);

15
web/src/Pages/Reset.css Normal file
View file

@ -0,0 +1,15 @@
.resetBody {
padding: 20px 5px 5px 5px;
font-size: 16pt;
width: 300px;
}
.resetFields {
width: 100%;
}
.resetButton {
height: 50px;
width: 100%;
margin-top:-5px;
}

153
web/src/Pages/Reset.js Normal file
View file

@ -0,0 +1,153 @@
import React, { useState, useEffect, useContext } from 'react';
import '../App.css';
import './Reset.css';
import { Button } from 'reactstrap';
import { Formik, Form, Field } from 'formik';
import ScaleLoader from 'react-spinners/ScaleLoader';
import { validateResetPassword, sendPasswordReset } from '../Api/index';
import AuthContext from '../Contexts/AuthContext';
const Reset = (route) => {
let boolTrue = true;
const [loading, setLoading] = useState(true);
const [reset, setReset] = useState({});
const [sent, setSent] = useState(false);
let { ResetPassword } = useContext(AuthContext);
let reqToken = false;
if (route && route.match && route.match.params && route.match.params.token) {
reqToken = route.match.params.token
}
const sendReset = (values) => {
sendPasswordReset(values).then(() => {
setSent(true);
});
}
useEffect(() => {
if (!reqToken) {
setLoading(false);
return false;
}
validateResetPassword(reqToken)
.then(data => {
setReset(data);
console.log(data)
setLoading(false);
})
}, [reqToken])
if (loading) {
return (
<div className="pageWrapper">
<ScaleLoader color="#6AD7E5" />
</div>
)
}
if (sent) {
return (
<div className="pageWrapper">
<h1>
Check your email!
</h1>
</div>
)
}
if (!reqToken) {
return (
<div className="pageWrapper">
<h1>
Reset Password
</h1>
<div className="loginBody">
<Formik
initialValues={{ email: '' }}
onSubmit={values => sendReset(values)}
>
<Form>
<label>
Email<br/>
<Field
name="email"
type="email"
required={boolTrue}
className="loginFields"
/>
</label>
<br/><br/>
<Button
color="primary"
type="submit"
className="loginButton"
disabled={loading}
>{loading ? <ScaleLoader color="#FFF" size={35} /> : "Reset"}</Button>
</Form>
</Formik>
</div>
</div>
)
}
if (reqToken && !reset.valid) {
return (
<div className="pageWrapper">
Invalid Reset Token or Token expired
</div>
)
}
return (
<div className="pageWrapper">
<h1>
Reset Password
</h1>
<div className="resetBody">
<Formik
initialValues={{ password: '', comfirmpassword: '', token: reqToken }}
onSubmit={values => ResetPassword(values)}
>
<Form>
<label>
New Password<br/>
<Field
name="password"
type="password"
required={boolTrue}
className="resetFields"
/>
</label>
<br/>
<label>
Confirm New Password<br/>
<Field
name="comfirmpassword"
type="password"
required={boolTrue}
className="resetFields"
/>
</label>
<Field
name="token"
type="hidden"
className="resetFields"
/>
<br/><br/>
<Button
color="primary"
type="submit"
className="loginButton"
disabled={loading}
>{loading ? <ScaleLoader color="#FFF" size={35} /> : "Reset"}</Button>
</Form>
</Formik>
</div>
</div>
);
}
export default Reset;