0

We take the signup values from the form(at the signup component) and send them to both my controller and store them in the context, use that information in the context to make the signup process and then redirect them to another page.

//signup-card component

import React, { useState } from 'react';
import { Space, Button, Form, Input, Checkbox } from 'antd';
import { signupFunc, loginFunc } from '../services/auth';
import { useContextInfo } from '../hooks/context';


const layout = {
    labelCol: { span: 8 },
    wrapperCol: { span: 16 },
};
const tailLayout = {
    wrapperCol: { offset: 8, span: 16 },
};


const SignupCard = ({ history }) => {
    //const [form] = Form.useForm();
    const { signup } = useContextInfo();
    const [error, setError] = useState(null);

    async function onFinish(values) { //traemos valores del form despues de dar SUBMIT
        try {
            await signupFunc(values)//hacemos signup con los servicios
            console.log('Success:', values);
            const { data } = await loginFunc(values);//hacemos login justo
            signup(data);//usamos la data del context para hacer signhup
            history.push("/MainHub")// redirigimos al MainHub
        }
        catch (e) {
            console.log(e);
            setError(e.response.data.message)
        } finally {

        }
    };

    const onFinishFailed = (errorInfo) => {
        console.log('Failed:', errorInfo);
    };

    return (
        <Form
            {...layout}
            name="basic"
            initialValues={{ remember: true }}
            onFinish={onFinish}
            onFinishFailed={onFinishFailed}
        >
            <Form.Item
                label="name"
                name="name"
                rules={[{ required: true, message: 'Please input your name' }]}
            >
                <Input />
            </Form.Item>

            <Form.Item
                label="email"
                email="email"
                rules={[{ required: true, message: 'Please input your email!' }]}
            >
                <Input />
            </Form.Item>

            <Form.Item
                label="Password"
                name="password"
                rules={[{ required: true, message: 'Please input your password!' }]}
            >
                <Input.Password />
            </Form.Item>


            <Form.Item {...tailLayout} name="remember" valuePropName="checked">
                <Checkbox>Remember me</Checkbox>
            </Form.Item>

            <Form.Item {...tailLayout}>
                <Button type="primary" htmlType="submit">
                    Submit
        </Button>
            </Form.Item>
        </Form>
    )
}

export default SignupCard;

Here's my controller

//Auth controller
const bcrypt = require('bcrypt')
User = require('../models/User') //asking for a model
passport = require('../config/passport')


//SIGN UP CONTROL-------------------------------------------------------------------
exports.signupProcessUser = async (req, res) => {
    try {
        const { email, password, name } = req.body
        if (!email || !password) {
            return res.status(403).json({ message: "Please provide an email and a password" })
            //validates data being written or not ^
        }
        const user = await User.findOne({
            email,
        })
        if (user) {
            return res.status(401).json({ message: 'user already exists' })
        }
        const salt = bcrypt.genSaltSync(12)//HASHING PASSWORD LENGTH
        const hashPass = bcrypt.hashSync(password, salt)
        const newUser = await User.create({
            email,
            password: hashPass,
            name,

        })

        if (newUser) res.status(201).json(newUser)
        //if the user is geniune,we're good to go
    } catch (e) {
        console.log(e)
        res.status(401).json({ message: e })
    } finally {
        console.log('CONTROLLER signupProcessUser')
    }
}

//LOGIN CONTROL-------------------------------------------------------
exports.loginProcess = async (req, res, next) => {
    passport.authenticate('local', (err, user, failureDetails) => {
        if (err) {
            return res.status(500).json({ message: err })
        }
        if (!user) {
            return res.status(401).json({ message: 'no user with that credentials' })
        }
        req.login(user, (err) => {
            if (err) {
                return res.status(500).json({ message: err })
            }
            user.password = null
            res.status(200).json(user)
        })
    })(req, res, next)
}

//---logout---
exports.logout = (req, res) => {
    req.session.destroy()
    req.logout()
    res.status(200).json({ message: 'logged out' })
}


exports.currentUser = (req, res) => {
    // console.log('currentUser', req.user);
    res.json(req.user || null);
};

//VIEW PROFILE-----------------------------

exports.profileView = async (req, res) => {
    try {
        const id = req.session.passport.user
        const user = Await.User.findById(id)
        res.send('profile', user)
    } catch (e) {
        console.error(e)
        res.status(401).json({ message: e })
    }
}

//EDIT PROFILE------------------------------

exports.editProfile = async (req, res) => {
    try {
        //traemos la info del form
        const { email, password, name } = req.body
        //obtenemos el USER ID
        const userId = req.session.passport.user

        //actualizamos el email
        if (email) {
            const user = Await.User.findByIdAndUpdate(
                userId,
                {
                    email,
                },
                {
                    new: true
                }
            )
            res.status(202).json(user)
        }

        //Actualizamos el nombre
        if (name) {
            const user = await User.findByIdAndUpdate(
                userId,
                {
                    name: name,
                },
                {
                    new: true,
                }
            )
            res.status(202).json(user)
        }

        //Update PASSWORD
        if (password) {
            const salt = bcrypt.genSaltSync(12)
            const hashPass = bcrypt.hashSync(password, salt)
            const user = Await.User.findByIdAndUpdate(
                userId,
                {
                    password: hashPass,
                },
                {
                    new: true,
                }
            )
            res.status(202).json(user)
        }
    } catch (e) {
        console.log(e.message)
        res.status(500).json({ message: e.message })
    } finally {
        console.log('CONTROLLER Route edit')
    }
}

//DELETE profile

exports.deleteProfile = async (req, res) => {
    const userId = req.session.passport.user
    const user = await User.findById(userId)
    let userDeleted = await User.deleteOne({
        _id: userId,
    })
    res.status(200).json({ message: 'Profile deleted' })
}

exports.currentUser = (req, res) => {
    res.json(req.user || null)
}

Here's my context file


import React, { useState, createContext, useContext, useEffect } from 'react';

import { currentUserFunc } from '../services/auth';

export const AppContext = createContext();

export const AppCtxProvider = (props) => {

    const [user, setUser] = useState(null)

    const [userUpdate, setUsrUpdate] = useState(false)


    useEffect(() => {
        async function getSessionData() {
            const { data } = await currentUserFunc()
            login(data)
        }
        getSessionData()
        setUsrUpdate(false)

    }, [userUpdate])

    const login = (userInf) => {
        setUser(userInf)
    }

    const signup = (userInf) => {
        setUser(userInf)
    }

    const logout = () => {
        setUser(null)
    }

    const value = { user, login, logout, signup, setUsrUpdate }

    return <AppContext.Provider {...props} value={value} />
}

export const useContextInfo = () => useContext(AppContext)

I already checked up the routes with postman and they work as they should,I can signup the user ,log it in and out, but I can't do that from the browser,I get a 401 error, so, it's either a problem within the controller or the data within the context is not being accepted, but I have no clue why.

here are my router and services(frontend)

//router

import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Home from './components/home/Home';
import NotFound from './components/404/NotFound.js';
import MainHub from './pages/MainHub';
import LoginPage from './pages/LoginPage';
import LoginCard from './components/LogCard';
import SignupCard from './components/SignCard';


const Router = () => (
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route exact path="/signup" component={SignupCard} />
      <Route exact path="/MainHub" component={MainHub} />
      <Route exact path="/login" component={LoginCard} />
      <Route component={NotFound} />
    </Switch>
  </BrowserRouter>
);

export default Router;

//services
import axios from 'axios';
let baseURL;

process.env.NODE_ENV === 'production'
  ? (baseURL = 'here should be your production endpoint')
  : (baseURL = 'http://localhost:3001');

const authService = axios.create({ withCredentials: true, baseURL });

export const signupFunc = (userInf) => authService.post('/signup', userInf);

export const loginFunc = (userInf) => authService.post('/login', userInf);

export const currentUserFunc = () => authService.get('/current-user')

export const logoutFunc = () => authService.get('/logout')

export const deleteFunc = () => authService.get('/deleteProfile')

export const editProfFunc = (userInf) => authService.put('./editProfile', userInf)

Here´s my app.js file

//App.js wirth configured CORS

require('dotenv').config();

const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const express = require('express');
const mongoose = require('mongoose');
const logger = require('morgan');
const path = require('path');
const cors = require('cors');
const session = require('express-session');
const passport = require('./config/passport');

mongoose
  .connect(process.env.DB, { useNewUrlParser: true, useUnifiedTopology: true })
  .then((x) => console.log(`Connected to Mongo! Database name: "${x.connections[0].name}"`))
  .catch((err) => console.error('Error connecting to mongo', err));

const app_name = require('./package.json').name;
const debug = require('debug')(`${app_name}:${path.basename(__filename).split('.')[0]}`);

const app = express();

app.use(
  cors({
    credentials: true,
    origin: [
      'http://localhost:3001',
      'http://localhost:3000',
      'http://localhost:3000/current-user',
      process.env.FRONTENDPOINT,
      "*"]
  })
);

app.use(
  session({
    resave: false,
    saveUninitialized: true,
    secret: process.env.SECRET,
    cookie: { maxAge: 1000 * 60 * 60 }
  })
);

app.use(passport.initialize());
app.use(passport.session());

app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(logger('dev'));

const index = require('./routes/index');
const auth = require('./routes/auth');
app.use('/', index);
app.use('/', auth);

// Uncomment this line for production
// app.get('/*', (req, res) => res.sendFile(__dirname + '/public/index.html'));

module.exports = app;
  • Which is exactly the problem? You can't log in users or you can't continue with the sign up process? – Ktoxcon Apr 05 '21 at 18:13
  • It seems like if it's a CORS error, check out this solution and see if it works for you too: https://stackoverflow.com/questions/47645533/fetch-in-reactjs-with-basic-auth-return-401-unauthorized-preflight-request-do – Ktoxcon Apr 05 '21 at 18:17
  • @KToxcon both, I get a 401 error, Like I explained in the post, I checked with postman to see if the endpoints have a problem,I can successfully create the user and log it, but since I'm manouvering the data between my context,controller and a middleware I don´t get where the problem relies. "I just added my app.js" – Carlos Riojas Apr 05 '21 at 21:16

0 Answers0