So I converted the .hbs template to .ejs template and try to see the difference. I thought converting would be same, but it turns out it doesn't.
My code is working. I can register a user, but no error shows up. The error display is the main problem in my code.
Error-looping of .ejs
This is the .HBS version of Error
{{#if message}}
<h4 class="alert alert-danger mt-4">{{message}}</h4>
{{/if}}
This is the .EJS version of Error
//SignUp.js / SignIn.js
<% if (error) { %>
<h4 class="alert alert-danger mt-4">{{message}}</h4>
<% } %>
Another version of Error in .EJS
<% if (hasErrors) {%>
<div class="alert alert-danger">
<% messages.forEach(function(message){ %>
<p><%= message %></p>
<% });%>
</div>
<% }%>
This is the Controllers folder - auth.js
exports.signin = async (req, res) => {
try {
const {email, password} = req.body;
if(!email || !password) {
return res.status(400).render('shop/signin', {
message: 'Please provide an email and/or password'
});
}
con.query('SELECT * FROM users WHERE email = ?', [email], async (error, results) => {
console.log(results);
if(!results || !(await bcrypt.compare(password, results[0].password))) {
res.status(401).render('shop/signin', {
message: 'Email or Password is incorrect'
});
}
else {
const id = results[0].id;
const token = jwt.sign({ id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN
});
console.log("The token is: " + token);
const cookieOptions = {
expires: new Date(
Date.now() = process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true
}
res.cookie('jwt', token, cookieOptions);
res.status(200).redirect("shop/profile");
}
});
}
catch(error) {
console.log(error);
}
}
exports.signup = (req, res) => {
console.log(req.body);
const {name, email, password, passwordConfirm} = req.body;
con.query('SELECT email FROM users WHERE email = ?', [email], async (error, results) => {
if(error) {
console.log(error);
}
if(results.length > 0) {
return res.render('shop/signup', {
message: 'That email is already in use!'
});
}
else if(password !== passwordConfirm) {
return res.render('shop/signup', {
message: 'Passwords do not match!'
});
}
let hashedPassword = await bcrypt.hash(password, 8);
console.log(hashedPassword);
con.query('INSERT INTO users SET ?', {name: name, email: email, password: hashedPassword}, (error, results) => {
if(error) {
console.log(error);
}
else {
console.log(results);
return res.render('shop/signup', {
message: 'User Registered!'
});
}
});
});
}
This is the Routes folder - user.js
router.post('/signup', authController.signup);
router.post('/signin', authController.signin);
module.exports = router;
Lord
You can solve this job in two ways.
1-Local Message
return res.send("<script> alert('Error Message'); window.location = 'shop/signin'; </script>")
2- If you don't want to use local messages Use 'flash' and 'session' packages
Related
I am using MongoDB and I installed react toastify to show errors from my backend for sign in but I can not seem to show them. How do I fix this issue? because I can output toast messages but not the custom errors I have.
js file where my toast messages are accessed
const handleSubmit = async (e) => {
e.preventDefault();
try {
const {data} = await axios.post(process.env.REACT_APP_LOGIN, {
username, password
});
if (data.success === true) {
setValues({username: '', password: ''})
toast.success("Sign in successfully");
//save user in local storage
if (typeof window !== "undefined") {
localStorage.setItem("token", JSON.stringify(data));
}
navigate("/map");
}
} catch (err) {
//logs undefined
console.log(`This is the error: ${err.response.data.error}`);
toast.error(`There is an error: ${err.response.data.error}`);
}
}
return (
<div className='loginContainer'>
<div className='logo'></div>
<AddLocationAltIcon/>
Pin
<form className='loginForm'>
<input type='text' className='usernameE' placeholder='username' onChange={handleChange('username')}/>
<input type='password' className='passwordE' placeholder='password' onChange={handleChange('password')} />
<button className='loginBtn' onClick={handleSubmit} type="submit">Login</button>
<button onClick={() => navigate('/register')} className="loginRegister">
Sign Up
</button>
</form>
</div>
)
js file with my custom errors
exports.signin = async (req, res, next)=> {
try {
const {username, password} = req.body;
//if no username and password
if (!username || !password) {
return next(new ErrorResponse(`Username and password are required`, 404))
}
//check username
const user = await User.findOne({username});
if (!user) {
return next(new ErrorResponse(`Invalid credentials`, 404))
}
//verify user password
const isMatched = await user.comparePassword(password);
if (!isMatched) {
return next(new ErrorResponse(`Cannot log in, check your credentials`, 404))
}
generateToken(user, 200, res);
} catch (error) {
console.log(error);
return next(new ErrorResponse(`Cannot log in, check your credentials`, 404))
}
}
ErrorResponse Class
class ErrorResponse extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
module.exports = ErrorResponse;
So, here's what I am doing. When the user logs in, the JWT token is set in localStorage. I am trying to persist user login. After logging in, logout button shows on the header but if I refresh, I think the redux store gets cleared up. I read some articles on how to use jwt token verification in react and the /me route or componentDidMount() in App.js itself, but I couldn't understand. Any help would be appreciated.
LoginForm.js
import React, { Component } from "react"
import validator from "validator"
import { loginUser } from "../actions/index"
import { connect } from "react-redux"
class LoginForm extends Component {
constructor(props) {
super(props)
this.state = {
email: "",
password: ""
}
}
handleChange = (event) => {
const { name, value } = event.target
this.setState({
[name]: value
})
}
handleSubmit = (event) => {
event.preventDefault();
const { email, password } = this.state;
const loginData = {
email: this.state.email,
password: this.state.password
}
if (!email || !password) {
return alert('Email and password are must.');
}
if (password.length < 6) {
return alert('Password must contain 6 characters.');
}
if (!validator.isEmail(email)) {
return alert('Invalid email.');
}
this.props.dispatch(loginUser(loginData))
this.props.history.push("/")
}
render() {
const isAuthInProgress = this.props.auth.isAuthInProgress
return (
<div>
<div className="field">
<p className="control has-icons-left has-icons-right">
<input className="input" onChange={this.handleChange} name="email" value={this.state.email} type="email" placeholder="Email" />
<span className="icon is-small is-left">
<i className="fas fa-envelope"></i>
</span>
<span className="icon is-small is-right">
<i className="fas fa-check"></i>
</span>
</p>
</div>
<div className="field">
<p className="control has-icons-left">
<input className="input" onChange={this.handleChange} name="password" value={this.state.password} type="password" placeholder="Password" />
<span className="icon is-small is-left">
<i className="fas fa-lock"></i>
</span>
</p>
<p className="has-text-danger">Forgot password?</p>
</div>
<div className="field">
<p className="control">
{
isAuthInProgress ? <p>Logging in...</p>
:
<button onClick={this.handleSubmit} className="button is-success">
Login
</button>
}
</p>
</div>
</div >
)
}
}
const mapStateToProps = (state) => {
return state
}
export default connect(mapStateToProps)(LoginForm)
actions/index.js
import axios from "axios"
export const registerUser = (registrationData) => {
console.log("inside register action")
return async dispatch => {
dispatch({ type: "REGISTRATION_STARTS" })
try {
const res = await axios.post("http://localhost:3000/api/v1/users/register", registrationData)
dispatch({
type: "REGISTRATION_SUCCESS",
data: { user: res.data },
})
} catch (err) {
dispatch({
type: "REGISTRATION_ERROR",
data: { error: "Something went wrong" }
})
}
}
}
export const loginUser = (loginData) => {
console.log("inside login action")
return async dispatch => {
dispatch({ type: "AUTH_STARTS" })
try {
const res = await axios.post("http://localhost:3000/api/v1/users/login", loginData)
dispatch({
type: "AUTH_SUCCESS",
data: { user: res.data }
})
localStorage.setItem("authToken", res.data.token)
} catch (err) {
dispatch({
type: "AUTH_ERROR",
data: { error: "Something went wrong" }
})
}
}
}
routes/users.js
router.post("/register", userController.registerUser)
router.post("/login", userController.loginUser)
router.get("/:userId", userController.getUser)
router.get("/list", userController.listUsers)
userController.js
const User = require("../models/User")
const auth = require("../utils/auth")
const validator = require("validator")
module.exports = {
registerUser: (req, res, next) => {
const { username, email, password } = req.body
User.create(req.body, (err, createdUser) => {
if (err) {
return next(err)
} else if (!username || !email || !password) {
return res.status(400).json({ message: "Username, email and password are must" })
} else if (!validator.isEmail(email)) {
return res.status(400).json({ message: "Invaid email" })
} else if (password.length < 6) {
return res.status(400).json({ message: "Password should be of at least 6 characters" })
}
else {
return res.status(200).json({ user: createdUser })
}
})
},
loginUser: (req, res, next) => {
const { email, password } = req.body
if (!email || !password) {
return res.status(400).json({message: "Email and password are must"})
}
User.findOne({ email }, (err, user) => {
if (err) {
return next(err)
} else if (!validator.isEmail(email)) {
return res.status(400).json({ message: "Invalid email" })
} else if (!user) {
return res.status(402).json({ error: "User not found" })
} else if (!user.confirmPassword(password)) {
return res.status(402).json({ error: "Incorrect password" })
}
// generate token here
const token = auth.signToken(email)
res.status(200).json({ user, token })
})
},
getUser: (req, res, next) => {
User.findById(req.params.userId, (err, user) => {
if (err) {
return next(err)
} else if (!user) {
return res.status(404).json({ message: "User not found" })
} else {
return res.status(200).json({ user: user })
}
})
},
listUsers: (req, res) => {
User.find({}, (err, users) => {
if (err) {
return res.status(404).json({ error: "No users found" })
} else {
return res.status(200).json({ user: user })
}
})
}
}
utils/auth.js
const jwt = require("jsonwebtoken")
function signToken(payload) {
return jwt.sign(payload, process.env.JWTSECRET)
}
function verifyToken(req, res, next) {
const token = req.headers.Authorization || req.headers.authorization || ""
if (!token) {
return res.status(403).json({ error: "Not authorized"})
}
jwt.verify(token, process.env.JWTSECRET, (err, decoded) => {
if (err) {
return res.status(403).json({ error: "Not authorized" })
}
req.user = decoded
next()
})
}
module.exports = { signToken, verifyToken }
I think the best way would be to use cookies.
Set the cookie in the login route
res.cookie("authToken", auth.signToken(email), {
httpOnly: false,
})
And then on the react side you can use js-cookie package to retrieve it and use in subsequent authenticated requests
import Cookies from 'js-cookie';
class SomeComponent extends Component {
constructor(props) {
super(props)
this.state = {
email: "",
password: "",
cookie: Cookies.get('authToken')
}
}
}
The server is keep getting crashed whenever i typed the wrong email address, i understood the problem, but can anyone tell me how to solve this.
Problem:Here the authentication is done for password only, if the password is wrong it is giving me the right error which is "Incorrect email or address", but not give this one when i try with wrong email address.
so i need the authentication for the email address also from my understanding this much i summarized.
Logins.js(API)
var oracledb = require('oracledb');
var bcrypt = require('bcrypt');
var jwt = require('jsonwebtoken');
var config = require(__dirname + '../../config.js');
import { Redirect } from 'react-router'
// var redirect = require("express-redirect");
// var express = require("express");
//var passport = require('passport');
//var LocalStrategy = require('passport-local').Strategy;
//var history = require('history');
//import post from './users';
//var cors = require('cors');
// var history = require('browser-history');
// var app = express();
// redirect(app);
// const targetBaseUrl = '/Signup';
function post(req, res, next) {
console.log('oye')
oracledb.getConnection(
config.database,
function(err, connection){
if (err) {
console.log('haha')
return next(err);
// console.log(err);
}
console.log('fuha')
connection.execute(
'select id as "id", ' +
' email as "email", ' +
' password as "password", ' +
' role as "role" ' +
'from jsao_users ' +
'where email = :email',
{
email: req.body.email.toLowerCase()
},
{
outFormat: oracledb.OBJECT
},
function(err, results){
var user;
console.log('huo')
console.log(err)
//console.log(results)
console.log(results.rows[0])
``````````````````````````````````````````````````````````````````````
if (results.rows[0] === undefined) {
console.log('hiiiiiii')
return <Redirect to='/Signup' />
// app.redirect(targetBaseUrl);
// history.push("/Main");
}
``````````````````````````````````````````````````````````````````
// else {connection.release(function(err) {
// console.log('hy')
// if (err) {
// console.log('joker')
// console.error(err.message);
// }
// });
// return next(err);
// // console.log(err);
// }
user = results.rows[0];
//debugger;
console.log(user)
bcrypt.compare(req.body.password,user.password, function(err, pwMatch) {
var payload;
if (err) {
console.log('wrong');
return next(err);
}
/*if (result == true) {
//res.redirect('http://localhost:3000/Main');
//res.end();
}
else {
res.send('Incorrect password');
//res.redirect('/Signin');
//res.end();
}
/*if(req.body.password != user.password){
res.json({success: false, message: 'passwords do not match'});
}*/
/*if(req.body.password == user.password) {
this.props.history.push("/Main");
}*/
if(pwMatch) {
//this.props.history.push("/Main");
console.log("password matched");
}
else {
res.status(401).send({message: 'Invalid email or password.'});
return;
}
payload = {
sub: user.email,
role: user.role
};
res.status(200).json({
user: user,
token: jwt.sign(payload, config.jwtSecretKey, {expiresIn: "60m" }),
});
});
//res.status(404).end();
connection.release(function(err) {
if (err) {
console.error(err.message);
}
});
});
}
);
}
module.exports.post = post;
Signin.js (Front-end)
import React, { Component } from "react";
import { Button, FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import axios from 'axios';
import "./Signin.css";
class Signin extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: ""
};
}
validateForm() {
return this.state.email.length > 0 && this.state.password.length > 0;
}
handleChange = event => {
this.setState({
[event.target.id]: event.target.value
});
}
```````````````````````````````````````````````````````````````
handleSubmit = event => {
event.preventDefault();
const user = {
email: this.state.email,
password : this.state.password
};
// API CALL
axios.post(`http://localhost:4000/api/logins`, user)
.then(res => {
console.log(res);
console.log(res.data);
//console.log("successful");
})
//this.props.history.push("/Main");
}
`````````````````````````````````````````````````````````````````````
render() {
return (
<div className="Login">
<form onSubmit={this.handleSubmit}>
<FormGroup controlId="email" bsSize="large">
<ControlLabel>Email</ControlLabel>
<FormControl
autoFocus
type="email"
value={this.state.email}
onChange={this.handleChange}
/>
</FormGroup>
<FormGroup controlId="password" bsSize="large">
<ControlLabel>Password</ControlLabel>
<FormControl
value={this.state.password}
onChange={this.handleChange}
type="password"
/>
</FormGroup>
<Button
block
bsSize="large"
disabled={!this.validateForm()}
type="submit"
>
Login
</Button>
</form>
</div>
);
}
}
export default Signin;
The expected result for the wrong email address is "Invalid email or password"
But instead getting this error:
C:\Users\anura\Desktop\reactApp\eclaims\src\Backend\routes\logins.js:49
bcrypt.compare(req.body.password,user.password, function(err, pwMatch) {
^
TypeError: Cannot read property 'password' of undefined
at C:\Users\anura\Desktop\reactApp\eclaims\src\Backend\routes\logins.js:49:59
at fetchRowsCb (C:\Users\anura\Desktop\reactApp\eclaims\src\Backend\node_modules\oracledb\lib\connection.js:109:7)
[nodemon] app crashed - waiting for file changes before starting...
The app crashed because you didn't throw exception and return immediately when getting user not found err, because the email is invalid, user variable is null, you cannot read property password of null or undefined
if (err) {
connection.release(function(err) {
if (err) {
console.error(err.message);
}
});
// MUST RETURN HERE !!!
//return next(err);
console.log(err);
}
user = results.rows[0];
// user IS NULL HERE, CANNOT READ PROPERTY OF NULL OR UNDERFINED
//debugger;
bcrypt.compare(req.body.password,user.password, function(err, pwMatch) {
In your callback check for empty values when no entry in db found.
function(err, results){
var user;
...
// put check for empty value if no entries found
if (results.length === 0) {
res.status(401).send({message: 'Invalid email or password.'});
} else {
// rest of your code
user = results.rows[0];
//debugger;
bcrypt.compare(req.body.password,user.password, function(err, pwMatch) {
var payload;
}
...
}
}
I am trying to set up a password-reset route inside my node application, which is suppose to send an email to the user with a password reset link.
The issue that I am having is that I keep receiving the error TypeError: cannot read property json of undefined. To my understanding this means that I am not passing the email correctly to my server side code.
I am having troubles locating the exact place of my bug. I've followed this example, however I've changed it to a more of a MVC architecture. Meaning that I've split the Node code into a service and a controller.
Here is my ReactJS code:
class PasswordResetComponent extends Component {
constructor(props){
super(props);
this.state = {
email:'',
showError:false,
messageFromServer:''
}
}
handleChange = name => event => {
this.setState({
[name]: event.target.value
});
}
sendEmail = e => {
e.preventDefault();
if(this.state.email == ' '){
this.setState({
showError: false,
messageFromServer:' ',
});
}else{
(async () => {
const rawResponse = await fetch(process.env.REACT_APP_SERVER_URI + '/user/password-reset', {
method: 'POST',
body: this.state.email
});
const response = await rawResponse.json();
console.log(response)
})();
}
}
render(){
console.log(this.state.email)
const {email, messageFromServer, showError, showNullError} = this.state;
return(
<div className="container-fluid no-gutters page-login">
<div className="row">
<div className="login-wrapper">
<form onSubmit={this.sendEmail} method="POST">
<div className="form-row">
<div className="form-group col-md-12">
<input type="email" name="email" className="form-control" value={email} onChange={this.handleChange('email')} placeholder="Email" required/>
</div>
</div>
<button type="submit" className="btn btn-primary btn-lg btn-block">Send Confirmation</button>
</form>
<Link to="/login"><button className="mt-4 btn btn-info">Back to Login</button></Link>
</div>
</div>
</div>
);
}
}
Inside my React code, I manage to successfully print out the value of this.state.email meaning that it should be passing fine. I also receive a 200 status on the request.
Here is my Service for password reset:
exports.passwordResetService = async function(email,res, req){
try{
User.findOne({
email: email
}).then(user => {
if( user == null){
res.json('email not in db');
}else{
const token = crypto.randomBytes(20).toString('hex');
console.log(token);
user.update({
resetPasswordToken: token,
resetPasswordExpires: Date.now() + 360000,
});
const transporter = nodemailer.createTransport({
service: 'gmx',
host: 'mail.gmx.com',
port: 587,
secure: true,
auth: {
user: `${process.env.EMAIL_ADDRESS}`,
pass: `${process.env.EMAIL_PASSWORD}`,
},
});
const mailOptions = {
from:'testaccount9909#gmx.com',
to: `${user.email}`,
subject: `Password Reset Email Broh'`,
text:
`Please click the following link to reset your account's password:`+
`http://localhost:3003/reset/${token}\n\n`+
`If you simply ignore the link, your password will remain unchanged!`
}
console.log('sending email...');
transporter.sendMail(mailOptions, function(err, response){
if(err){
console.error('there was an error: ', err);
} else {
console.log('here is the resposne:', response);
res.status(200).json('recovery email sent');
}
})
}
}).catch(error =>
console.log(error)
);
}catch(e){
throw Error("And Error occured while resetting the password");
}
}
Here is my Controller for password reset:
exports.passwordReset = async function(req, res, next){
try{
let passwordResetValue = await UserService.passwordResetService(req.body.email);
return res.status(200).json({status:200, data: passwordResetValue, error:"false", message:"Password reset email has been sent!"})
}catch(e){
console.log(e, "Wopsie wopsie email reset error!");
res.status(400);
}
};
The Place where I am getting the error is inside the Service, more specifically:
if( user == null){
res.json('email not in db');
}
Why am I not passing the user email to the NodeJS service?
The reason you're getting cannot read property json of undefined is because res is not available to passwordResetService since you've not passed it from the route callback and since it's not a middleware
Since all that you're doing with passwordResetService is do some validation and send email you can make few changes to your code like:
// Since you want to send the some success message, you can make a promise wrapper
// to return a promise which you can later await to get status or failure
function mailSender(mailOptions) {
return new Promise((resolve, reject) => {
transporter.sendMail(mailOptions, function(err, response){
if(err){
// could just reject(err) instead
reject('there was an error: ', err);
} else {
console.log('here is the resposne:', response);
resolve('recovery email sent');
}
});
});
}
exports.passwordResetService = async function(email){
let mailStatus;
try{
const user = User.findOne({ email });
if (user === null) {
return ({ message: "email not in db" });
}
const token = crypto.randomBytes(20).toString('hex');
console.log(token);
user.update({
resetPasswordToken: token,
resetPasswordExpires: Date.now() + 360000,
});
const transporter = nodemailer.createTransport({
service: 'gmx',
host: 'mail.gmx.com',
port: 587,
secure: true,
auth: {
user: `${process.env.EMAIL_ADDRESS}`,
pass: `${process.env.EMAIL_PASSWORD}`,
},
});
const mailOptions = {
from:'testaccount9909#gmx.com',
to: `${user.email}`,
subject: `Password Reset Email Broh'`,
text:
`Please click the following link to reset your account's password:`+
`http://localhost:3003/reset/${token}\n\n`+
`If you simply ignore the link, your password will remain unchanged!`
}
console.log('sending email...');
// wait for promise to resolve, if promise is rejected, catch block will catch the error
mailStatus = await mailSender(mailOptions);
} catch(e) {
throw Error("And Error occured while resetting the password");
}
return mailStatus;
}
I have node.js backend that has a login/signup and couple of urls that are accessed by their respective role. For example I have tested this url http://localhost:5000/api/deleteuser:user_id and this url is only accessed by a user that has role "ADMIN" and other routes with the same access control
in my react-redux application I managed to create login/register that uses jwt however after the user login with his username and password the system only direct him to the dashboard. i want to check the user role when the user attempt to login so that if he was admin then the system directs him to the admin page or if he is a teacher also to the teacher's page and so on.
at the moment i am struggling to figure how can I solve this problem.
i tried to used CASL for react but i just could not understand it so can you help me with this please
thanks in advance
I have tried to use CASL https://www.npmjs.com/package/#casl/react but I just could not understand it.
export const userSignin = (userData, history) => {
return dispatch => {
axios.post('/api/signin', userData)
.then(res => {
//success message
toastr.success('Welcome')
//redirect to dashboard
//save token to location storage
const { token } = res.data;
localStorage.setItem('jwtToken', token);
//set token to auth header
setAuthToken(token);
//decode token
const jwtDecoded = jwtDecode(token);
if(res.data.role === 'admin'){
history.push('/admin');
}else{
history.push('/dashboard');
}
//set current user
dispatch(setCurrentUser(jwtDecoded));
})
.catch(error => dispatch({
type: GET_ERRORS,
payload: error.response.data
}))
}
}
class Signin extends React.Component {
state = {
username: '',
password: '',
usernameError: '',
passwordError: '',
errors: {}
}
handleUsername = (e) => {
this.setState({ username: e.target.value }, () => { this.validateUsername() });
}
handlePassword = (e) => {
this.setState({ password: e.target.value }, () => { this.validatePassword() });
}
validateUsername = () => {
const { username } = this.state;
let usernameError;
if (username === '') {
usernameError = 'Username is required';
}
this.setState({ usernameError });
return !usernameError;
}
validatePassword = () => {
const { password } = this.state;
let passwordError;
if (password === '') {
passwordError = 'Password is required';
}
this.setState({ passwordError });
return !passwordError;
}
handleSubmit = (e) => {
e.preventDefault();
const validUsername = this.validateUsername();
const validPassword = this.validatePassword();
if (validUsername && validPassword) {
const userData = {
username: this.state.username,
password: this.state.password
}
this.props.userSignin(userData, this.props.history);
}
}
componentDidMount() {
if (this.props.auth.isAuthenticated) {
// const role = this.props.role;
// if (role === "Admin") {
// this.props.history.push('/admin');
// } else {
// this.props.history.push('/dashboard');
// }
this.props.history.push('/dashboard');
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated === true) {
this.props.history.push('/dashboard');
}
if (nextProps.errors) {
this.setState({ errors: nextProps.errors })
}
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-sm-4 col-sm-offset-4">
{
this.state.errors.success === false ? <p className="text-danger text-center">{this.state.errors.message}</p> : null
}
</div>
<div className="col-sm-4 col-sm-offset-4">
<h3 className='text-center'>Login</h3>
<form onSubmit={this.handleSubmit}>
<div className={classnames('form-group', { 'has-error': this.state.usernameError })}>
<input
type="text"
className="form-control"
value={this.state.username}
onChange={this.handleUsername}
placeholder="Username"
/>
<span className="help-block">{this.state.usernameError}</span>
</div>
<div className={classnames('form-group', { 'has-error': this.state.passwordError })}>
<input
type="password"
className="form-control"
value={this.state.password}
onChange={this.handlePassword}
placeholder="Password"
/>
<span className="help-block">{this.state.passwordError}</span>
</div>
<button className="btn btn-success btn-sm">Login</button>
</form>
</div>
</div>
</div>
);
}
}
Signin.propTypes = {
auth: PropTypes.object.isRequired,
userSignin: PropTypes.func.isRequired
}
const mapStateToProps = (state) => {
return {
auth: state.auth,
errors: state.errors
}
}
export default connect(mapStateToProps, { userSignin })(withRouter(Signin));
exports.signin = (req, res) => {
User.findOne({ username: req.body.username }, function (err, user) {
if (err) throw err;
if (!user) {
res.status(401).json({ success: false, message: 'Auth failed,User not found' });
} else if (user) {
var validPassword = user.comparePassword(req.body.password);
if (!validPassword) {
res.status(401).json({ success: false, message: 'Auth failed,wrong password' });
} else {
var token = jwt.sign({
id: user._id,
username: user.username,
email: user.email,
password: user.password,
profileImage: user.profileImage,
created_at: user.created_at
}, config.secret, { expiresIn: '1h' });
res.status(200).json({ success: true, message: 'Authenticated', token: 'Bearer ' + token });
}
}
});
}
at the moment this only direct the user to dashboard, i think i am missing something here
In the last line of exports.signin you need to include the role in the object you're sending back. for example you're sending this:
res.status(200).json({ success: true, message: 'Authenticated', token: 'Bearer ' + token })
but it needs to be something like this:
res.status(200).json({ success: true, message: 'Authenticated', role: 'admin', token: 'Bearer ' + token })
Then in React, make sure you're accessing the correct element in that if statement to push to the proper route.