Passport local auth and front end for registration, functioning but needs work

This commit is contained in:
Mike Rode
2019-09-05 00:39:05 -05:00
parent 7730e9554f
commit d0fd8ad27f
9 changed files with 267 additions and 78 deletions

View File

@@ -13,6 +13,7 @@ import PopularList from './PopularList';
import PlexTokenForm from './plex/PlexTokenForm';
import TopRatedList from './TopRatedList';
import SignUp from './auth/SignUp';
import Login from './auth/Login';
class App extends Component {
componentDidMount() {
@@ -29,6 +30,7 @@ class App extends Component {
<Route exact path="/" component={Hero} />
<Route exact path="/sonarr" component={PlexTokenForm} />
<Route exact path="/sign-up" component={SignUp} />
<Route exact path="/login" component={Login} />
<Route exact path="/plex-pin" component={PlexPin} />
<Route path="/admin" component={Admin} />
<Route path="/most-watched" component={Plex} />

View File

@@ -52,6 +52,14 @@ class Hero extends Component {
<i className="material-icons left">group</i> Login with Google
</a>
</div>
<div className="row">
<Link
to="/login"
className="waves-effect waves-light btn-large min-button-width"
>
<i className="material-icons left">show_chart</i>Login
</Link>
</div>
<div className="row">
<Link
to="/sign-up"

View File

@@ -0,0 +1,118 @@
import React from 'react';
import axios from 'axios';
import {Redirect} from 'react-router-dom';
import PropTypes from 'prop-types';
import CssBaseline from '@material-ui/core/CssBaseline';
import {connect} from 'react-redux';
import {withStyles} from '@material-ui/core/styles';
import '../../css/materialize.css';
import TextHeader from '../helpers/Header';
import styles from '../../css/materialize.css';
class Login extends React.Component {
state = {
email: '',
password: '',
};
onFormSubmit = event => {
event.preventDefault();
console.log('loginuserstate', this.state);
this.loginUser(this.state);
};
loginUser = async params => {
console.log('params', params);
const res = await axios({
method: 'post',
url: '/api/auth/login',
data: params,
});
console.log('login response', res.data);
window.location.reload();
};
render() {
const {classes} = this.props;
if (this.props.auth) {
return <Redirect to="/" />;
} else if (!this.props.auth) {
return (
<React.Fragment>
<CssBaseline />
<div className={classes.heroUnit}>
<div className={classes.heroContentSmall}>
<div className="section center-align">
<div className={classes.shrinkTopMargin}>
<TextHeader text="Login" />
</div>
<hr />
<div className="flex-center">
<h5 className="robots center ">{this.state.errorMessage}</h5>
</div>
</div>
<div className="section center-align">
<div className="row">
<form onSubmit={this.onFormSubmit} className="col s12">
<div className="row no-bottom-margin">
<div className="input-field col m8 offset-m2 s12">
<p>Email</p>
<input
id="email"
type="text"
className="validate center-align"
value={this.state.email}
onChange={e => this.setState({email: e.target.value})}
/>
</div>
</div>
<div className="row no-bottom-margin">
<div className="input-field col m8 offset-m2 s12">
<p>Password</p>
<input
id="password"
type="password"
className="validate center-align"
value={this.state.password}
onChange={e =>
this.setState({password: e.target.value})
}
/>
</div>
</div>
<div className="row">
<div className="col s12">
<div className="center-align">
<button
className="btn-large waves-effect waves-light center-align"
type="submit"
name="action"
>
Login
<i className="material-icons right">send</i>
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</React.Fragment>
);
}
}
}
Login.propTypes = {
classes: PropTypes.object.isRequired,
};
function mapStateToProps({auth}) {
return {auth};
}
export default connect(mapStateToProps)(withStyles(styles)(Login));

View File

@@ -13,8 +13,6 @@ class SignUp extends React.Component {
state = {
email: '',
password: '',
errorMessage: '',
redirect: false,
};
onFormSubmit = event => {
@@ -25,14 +23,13 @@ class SignUp extends React.Component {
signUpUser = async params => {
console.log('params', params);
const res = await axios.post('/api/auth/login', {params});
if (res.data.includes('Invalid')) {
console.log('signup response', res);
this.setState({errorMessage: res.data});
} else {
console.log('signup response', res);
window.location.reload();
}
const res = await axios({
method: 'post',
url: '/api/auth/sign-up',
data: params,
});
console.log('signup response', res);
window.location.reload();
};
render() {

View File

@@ -13,29 +13,34 @@ router.get(
},
);
router.post(
'/login',
function(req, res, next) {
console.log('Request params', req.params);
console.log('Request body', req.body);
console.log('Request query', req.query);
next();
},
passport.authenticate('local', {
failureRedirect: '/sign-up',
failureFlash: true,
}),
function(req, res) {
console.log('res', res.body);
res.redirect('/');
},
);
router.post('/sign-up', function(req, res, next) {
passport.authenticate('local-signup', function(err, user, info) {
if (err) {
console.log('sign up error', err);
return next(err);
}
if (!user) {
console.log('no user returned', info);
return res.json({message: info.message});
}
console.log('user found', user);
res.json(user);
})(req, res, next);
});
router.post('/login', passport.authenticate('local-login'), function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
console.log('User in session', req.user);
res.redirect('/');
});
router.get('/google/callback', passport.authenticate('google'), (req, res) => {
res.redirect('/plex-pin');
});
router.get('/current_user', (req, res) => {
console.log('current user', req.user);
res.send(req.user);
});

View File

@@ -0,0 +1,11 @@
module.exports = {
up: function(queryInterface, Sequelize) {
// logic for transforming into the new state
return queryInterface.addColumn('Users', 'password', Sequelize.STRING);
},
down: function(queryInterface, Sequelize) {
// logic for reverting the changes
return queryInterface.removeColumn('Users', 'password');
},
};

View File

@@ -14,6 +14,7 @@ module.exports = (sequelize, DataTypes) => {
sonarrUrl: DataTypes.STRING,
sonarrApiKey: DataTypes.STRING,
admin: DataTypes.BOOLEAN,
password: DataTypes.STRING,
},
{},
);

View File

@@ -85,9 +85,9 @@ export default () => {
});
};
process.on('uncaughtException', error => {
console.log('Unhandled Exception due to:', error);
process.exit(1);
process.on('SIGINT', function() {
console.log('SIGINT');
process.exit();
});
process.on('unhandledRejection', (reason, p) => {

View File

@@ -7,62 +7,114 @@ import keys from '../../../config';
import models from '../../db/models';
passport.serializeUser((user, done) => {
console.log('serial', user);
done(null, user.id);
});
passport.deserializeUser((id, done) => {
console.log('deserial', id);
models.User.findByPk(id).then(user => {
done(null, user);
});
});
// passport.use(
// new LocalStrategy(
// {usernameField: 'email', passwordField: 'password'},
// async (email, password, done) => {
// try {
// console.log('Made it to passport', email);
// const existingUser = await User.findOne({email: email});
// if (existingUser) {
// done(null, existingUser);
// }
// if (!user) {
// done(null, false, {message: 'Incorrect username.'});
// }
// if (!user.validPassword(password)) {
// done(null, false, {message: 'Incorrect password.'});
// }
// const hashedPassword = generateHash(password);
// const user = await models.User.create({
// email: email,
// password: hashedPassword,
// });
// done(null, user);
// } catch (error) {
// console.log('passport error', error);
// done(error);
// }
// },
// ),
// );
const generateHash = password => {
return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
};
passport.use(
'local-signup',
new LocalStrategy(
{usernameField: 'email', passwordField: 'password'},
function(username, password, done) {
User.findOne({email: email}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {message: 'Incorrect email.'});
}
if (!user.validPassword(password)) {
return done(null, false, {message: 'Incorrect password.'});
}
return done(null, user);
{
usernameField: 'email',
passwordField: 'password',
},
async function(email, password, done) {
console.log('passport - signup', email);
const exisitingUser = await models.User.findOne({
where: {email: email},
returning: true,
plain: true,
raw: true,
});
if (exisitingUser) {
return done(null, false, {
message: 'That email is already taken',
});
}
const userPassword = generateHash(password);
const data = {
email: email,
password: userPassword,
};
console.log('user data before save', data);
const newUser = models.User.create(data, {
returning: true,
plain: true,
raw: true,
}).then(function(newUser, created) {
if (!newUser) {
return done(null, false);
}
if (newUser) {
console.log('new user created', newUser);
return done(null, newUser);
}
});
},
),
);
//LOCAL SIGNIN
passport.use(
'local-login',
new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
},
function(email, password, done) {
var isValidPassword = function(userpass, password) {
return bCrypt.compareSync(password, userpass);
};
models.User.findOne({
where: {
email: email,
},
returning: true,
plain: true,
raw: true,
})
.then(function(user) {
if (!user) {
return done(null, false, {
message: 'Email does not exist',
});
}
if (!isValidPassword(user.password, password)) {
return done(null, false, {
message: 'Incorrect password.',
});
}
console.log('user sent to serialize', user.id);
return done(null, user);
})
.catch(function(err) {
console.log('Error:', err);
return done(null, false, {
message: 'Something went wrong with your Signin',
});
});
},
),
);
@@ -96,8 +148,3 @@ passport.use(
},
),
);
// should export to commonUtils file
const generateHash = string => {
return bCrypt.hashSync(string, bCrypt.genSaltSync(8), null);
};