Skip to content

Commit

Permalink
WIP Update user registration flow (#168)
Browse files Browse the repository at this point in the history
* Added pagination component with useQuery call connected

* tested on mock data, working without useeffect

* Pagination cleanup - ermoved Resources/Resources.js file, only show pagination component when there is no search term, and moved it down on the page

* register and login api updated

* login and registration apis working now, error handling tmp patch

* [Security] Bump axios from 0.19.0 to 0.21.1

Bumps [axios](https://github.com/axios/axios) from 0.19.0 to 0.21.1. **This update includes a security fix.**
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.21.1/CHANGELOG.md)
- [Commits](axios/axios@v0.19.0...v0.21.1)

Signed-off-by: dependabot-preview[bot] <[email protected]>

* Add constants file and differentiate between dev and prod for the API host URL

* fixed tests

* verify email post request working

* error validation on verify email screen

* Update src/components/Auth/SignUpForm.js

Co-authored-by: Linda <[email protected]>

* Add key to dependencies array for useEffect

* Added explanatory text re: verifying email

Co-authored-by: Linda Peng <[email protected]>
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Linda <[email protected]>
  • Loading branch information
4 people authored Apr 18, 2021
1 parent 2d41259 commit 9112cc3
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 117 deletions.
4 changes: 4 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Profile from './pages/Profile';
import ResourceSubmit from './pages/Resources/ResourceSubmit';
import ResourcePage from './pages/Resources/ResourcePage.js';
import PrivateRoute from './PrivateRoute';
import VerifyEmail from './components/Auth/VerifyEmail';

function App() {
const [authTokens, setAuthTokens] = useState(
Expand Down Expand Up @@ -48,6 +49,9 @@ function App() {
<Route path="/connect">
<Connect />
</Route>
<Route path="/api/v1/auth/registration/verify-email">
<VerifyEmail />
</Route>
<PrivateRoute path="/profile" component={Profile} />
<Route
path="/resources/:guid"
Expand Down
24 changes: 14 additions & 10 deletions src/components/Auth/AuthForm.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,28 @@ describe('Signup', () => {
username: 'Carolyne.Carter',
token:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IkNhcm9seW5lLkNhcnRlciIsImlhdCI6MTU4NDMzODQ4NiwiZXhwIjoxNTg0MzQyMDg2LCJ1c2VyX2lkIjo4MCwib3JpZ19pYXQiOjE1ODQzMzg0ODZ9.saO6OCOKV1uwHjTbM-iDGmhbkMNCnzrGFj4TBYnTv2E',
first_name: 'Carolyne',
last_name: 'Carter',
// first_name: 'Carolyne',
// last_name: 'Carter',
email: '[email protected]',
password1: 'password',
password2: 'password',
},
});

userEvent.type(screen.getByLabelText(/username/i), 'Carolyne.Carter');
userEvent.type(screen.getByLabelText('Username*'), 'Carolyne.Carter');

userEvent.type(screen.getByLabelText(/password/i), 'password');
userEvent.type(screen.getByLabelText('Password*'), 'password');

userEvent.type(screen.getByLabelText('Confirm Password*'), 'password');

userEvent.type(
screen.getByLabelText(/email/i),
screen.getByLabelText('Email*'),
'[email protected]'
);

userEvent.type(screen.getByLabelText(/first name/i), 'Carolyne');
// userEvent.type(screen.getByLabelText(/first name/i), 'Carolyne');

userEvent.type(screen.getByLabelText(/last name/i), 'Carter');
// userEvent.type(screen.getByLabelText(/last name/i), 'Carter');

userEvent.click(screen.getByText('Sign Up'));

Expand Down Expand Up @@ -129,15 +133,15 @@ describe('Login', () => {
data: {
token:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IkNhcm9seW5lLkNhcnRlciIsImlhdCI6MTU4NDM0MDAyMiwiZXhwIjoxNTg0MzQzNjIyLCJ1c2VyX2lkIjo4MCwib3JpZ19pYXQiOjE1ODQzNDAwMjJ9.0zNlXPVAjkBjxUQjq4B0HXnvrez93H2pz6n2ROKWzzg',
username: 'Carolyne.Carter',
email: 'Carolyne.Carter@mail.com',
},
});

await act(async () =>
userEvent.type(getByLabelText(/username/i), 'Carolyne.Carter')
userEvent.type(getByLabelText(/email/i), 'Carolyne.Carter@mail.com')
);
await act(async () =>
userEvent.type(getByLabelText(/username/i), 'Carolyne.Carter')
userEvent.type(getByLabelText(/email/i), 'Carolyne.Carter@mail.com')
);

await act(async () =>
Expand Down
23 changes: 16 additions & 7 deletions src/components/Auth/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAuth } from './AuthContext';
import axios from 'axios';

const LoginForm = ({ toggleActiveForm }) => {
const [username, setUsername] = useState(null);
const [email, setEmail] = useState(null);
const [password, setPassword] = useState(null);
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [errorMessage, setErrorMessage] = useState(null);
Expand All @@ -16,18 +16,27 @@ const LoginForm = ({ toggleActiveForm }) => {
const handleLogin = e => {
e.preventDefault();
const data = {
username,
email: email,
password,
};
axios
.post('/auth/obtain_token/', data)
.post('http://localhost:8000/api/v1/auth/login/', data)
.then(res => {
auth.setAuthTokens(res.data);
setIsLoggedIn(true);
})
.catch(error => {
if (error.response) {
setErrorMessage(error.response.data.non_field_errors[0]);
// todo: display field error in input field
if (error.response.data.email) {
setErrorMessage(error.response.data.email[0]);
} else if (error.response.data.password) {
setErrorMessage(error.response.data.password[0]);
} else if (error.response.data.non_field_errors) {
setErrorMessage(error.response.data.non_field_errors[0]);
} else {
setErrorMessage('There was an error!');
}
} else {
setErrorMessage('There was an error!');
}
Expand Down Expand Up @@ -55,14 +64,14 @@ const LoginForm = ({ toggleActiveForm }) => {
Log in
</Box>
<TextField
id="username"
label="username"
id="email"
label="Email"
fullWidth
required
variant="outlined"
margin="dense"
type="text"
onChange={e => setUsername(e.target.value)}
onChange={e => setEmail(e.target.value)}
/>
<TextField
id="password"
Expand Down
45 changes: 18 additions & 27 deletions src/components/Auth/SignUpForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,26 @@ import axios from 'axios';
import { useAuth } from './AuthContext';
import { validationResolver, defaultValues } from './SignUpForm.schema';
import { Form, Field } from '../form';
import { config } from '../../helpers/constants';

const SignUpForm = ({ toggleActiveForm }) => {
const [errorMessage, setErrorMessage] = useState(null);
const [isLoggedIn, setIsLoggedIn] = useState(false);
const referer = '/profile';
const referer = '/api/v1/auth/registration/verify-email/';
const auth = useAuth();

const onSubmit = ({ username, password, firstName, lastName, email }) => {
const onSubmit = ({ username, password1, password2, email }) => {
const data = {
username,
password,
email,
first_name: firstName,
last_name: lastName,
password1,
password2,
};
axios
.post('/auth/users/', data)
.post(`${config.API_URL}/api/v1/auth/registration/`, data)
.then(res => {
auth.setAuthTokens(res.data);
setIsLoggedIn(true);
setErrorMessage('');
})
.catch(err => {
console.error(err);
Expand Down Expand Up @@ -58,24 +57,6 @@ const SignUpForm = ({ toggleActiveForm }) => {
Create an account
</Box>

<Field
as={TextField}
fullWidth
variant="outlined"
margin="dense"
name="firstName"
label="First Name*"
id="first-name"
/>
<Field
as={TextField}
fullWidth
variant="outlined"
margin="dense"
name="lastName"
label="Last Name"
id="last-name"
/>
<Field
as={TextField}
fullWidth
Expand All @@ -99,10 +80,20 @@ const SignUpForm = ({ toggleActiveForm }) => {
fullWidth
variant="outlined"
margin="dense"
name="password"
name="password1"
label="Password*"
type="password"
id="password"
id="password1"
/>
<Field
as={TextField}
fullWidth
variant="outlined"
margin="dense"
name="password2"
label="Confirm Password*"
type="password"
id="password2"
/>

{errorMessage && <Box color="error.main"> {errorMessage}</Box>}
Expand Down
22 changes: 10 additions & 12 deletions src/components/Auth/SignUpForm.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ import Joi from '@hapi/joi';
import { createValidationResolver } from '../form';

const schema = Joi.object({
firstName: Joi.string()
.required()
.trim()
.label('First Name'),
lastName: Joi.string()
.allow('')
.trim()
.label('Last Name'),
username: Joi.string()
.alphanum()
.min(3)
Expand All @@ -22,17 +14,23 @@ const schema = Joi.object({
.required()
.trim()
.label('Email'),
password: Joi.string()
password1: Joi.string()
.required()
.label('Password'),
password2: Joi.any()
.valid(Joi.ref('password1'))
.required()
.label('Confirm Password')
.options({ messages: { 'any.only': 'Passwords do not match' } }),
});

const defaultValues = {
firstName: '',
lastName: '',
// firstName: '',
// lastName: '',
username: '',
email: '',
password: '',
password1: '',
password2: '',
};

const validationResolver = createValidationResolver(schema);
Expand Down
51 changes: 51 additions & 0 deletions src/components/Auth/VerifyEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';
import { config } from '../../helpers/constants';

const VerifyEmail = () => {
const [verifyStatus, setVerifyStatus] = useState('');
const [error, setError] = useState('');
const urlParams = new URLSearchParams(window.location.search);
const key = urlParams.get('key');

useEffect(() => {
if (key) {
axios
.post(`${config.API_URL}/api/v1/auth/registration/verify-email/`, {
key,
})
.then(resp => {
if (resp.status === 200) {
setVerifyStatus('Your email has been verified!');
}
})
.catch(e => {
console.error(e);
setError(e.message);
});
} else {
setError('There is no key in the URL.');
}
}, [key]);

return (
<div>
<div>
{verifyStatus ? (
<span>{`${verifyStatus}`}</span>
) : (
<p>
Thank you for signing up! Please check your email to verify your
account.
</p>
)}
{error && <span style={{ color: 'red' }}>{`${error}`}</span>}
<br />
<Link to="/">Home</Link>
</div>
</div>
);
};

export default VerifyEmail;
Loading

0 comments on commit 9112cc3

Please sign in to comment.