Home > database >  Authentication App - Get logged in user profile info - error
Authentication App - Get logged in user profile info - error

Time:12-03

I am working through the full stack certification on devchallenges.io and I'm doing the authentication app challenge. So far I have been able to create the login and register functionality and have been able to set up the functionality to get the logged in user and display their information and also the functionality for the user to update their profile however, when registering or logging in a user, the profile information of the same one user is displayed regardless of which user is logged in. I have attached a link to a loom video to demonstrate the issue. Furthermore,. I have attached the github source code link.

https://www.loom.com/share/c464f456751a45068110e699f796e11d

https://github.com/gbopola/Auth-App

Profile.js

import React, { useEffect, useState } from 'react';
import { Navbar } from './Navbar';
import { useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
import { loadUser } from '../redux/actions/auth';
import { Link } from 'react-router-dom';
import { store } from '../store';
export const Profile = () => {
  const [hover, setHover] = useState(false);
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(loadUser());
  }, []);
  const state = useSelector((state) => state.auth);

  let styles = {
    width: '72px',
    height: '72px',
    borderRadius: '8px',
    background: `url(${
      state && state.user && state.user.avatar
    }) center center/cover`,
  };

  return (
    <div className="Profile">
      <Navbar />
      <div className="profile-personal-info">
        <h1>Personal Info</h1>
        <p className="personal-info-text">
          Basic info, like your name and photo
        </p>
      </div>
      <div className="profile-wrapper">
        <div className="profile-heading">
          <div>
            <h2>Profile</h2>
            <p className="personal-info-grey">
              Some info may be visible to other people
            </p>
          </div>
          <Link to={`/profile/edit/${state && state.user && state.user._id}`}>
            <button className="edit-btn">Edit</button>
          </Link>
        </div>
        <div className="divider"></div>
        <div className="profile-photo">
          <p className="personal-info-grey">PHOTO</p>
          <div className="profile-img" style={styles}></div>
        </div>
        <div className="divider"></div>
        <div className="name">
          <p className="personal-info-grey">NAME</p>
          <p className="name-text">{state && state.user && state.user.name}</p>
        </div>
        <div className="divider"></div>
        <div className="bio">
          <p className="personal-info-grey">BIO</p>
          <p className="bio-text">{state && state.user && state.user.bio}</p>
        </div>
        <div className="divider"></div>
        <div className="phone">
          <p className="personal-info-grey">PHONE</p>
          <p className="phone-text">
            {state && state.user && state.user.phone}
          </p>
        </div>
        <div className="divider"></div>
        <div className="email">
          <p className="personal-info-grey">EMAIL</p>
          <p className="email-text">
            {state && state.user && state.user.email}
          </p>
        </div>
        <div className="divider"></div>
        <div className="password">
          <p className="personal-info-grey">PASSWORD</p>
          <p className="password-text">***********</p>
        </div>
      </div>
    </div>
  );
};

Server.js

const express = require('express');
const connectDB = require('./config/db');
const app = express();
const { check, validationResult } = require('express-validator');
const User = require('./models/User');
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const auth = require('./middleware/auth');
const cloudinary = require('./utils/cloudinary');
const upload = require('./utils/multer');

// Connect database
connectDB();

// Init Middleware
app.use(express.json({ extended: false }));

// @route    POST /register
// @desc     Register user
// @access   Public
app.post(
  '/register',
  [
    check('email', 'Please include a valid email').isEmail(),
    check('password', 'Please enter a password').notEmpty(),
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    const { email, password } = req.body;

    try {
      // See if user exists
      let user = await AuthUser.findOne({ email });

      if (user) {
        return res
          .status(400)
          .json({ errors: [{ msg: 'User already exists' }] });
      }
      // Get users gravatar
      const avatar = gravatar.url(email, {
        s: '200',
        r: 'pg',
        d: 'mm',
      });

      user = new AuthUser({
        email,
        avatar,
        password,
      });

      // Encrypt password
      const salt = await bcrypt.genSalt(10);

      user.password = await bcrypt.hash(password, salt);

      await user.save();

      // Return jsonwebtoken
      const payload = {
        user: {
          id: user.id,
        },
      };

      jwt.sign(
        payload,
        config.get('jwtSecret'),
        { expiresIn: '5 days' },
        (err, token) => {
          if (err) throw err;
          res.json({ token });
        }
      );
    } catch (error) {
      console.error(error.message);
      res.status(500).send('Server error');
    }
  }
);

// @route    POST /login
// @desc     Authenticate user & get token
// @access   Public

app.post(
  '/login',
  check('email', 'Please include a valid email').isEmail(),
  check('password', 'Password is required').exists(),
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        errors: errors.array(),
      });
    }

    const { email, password } = req.body;

    try {
      // See if user exists
      let user = await User.findOne({ email });

      if (!user) {
        return res
          .status(400)
          .json({ errors: [{ msg: 'Invalid credentials' }] });
      }

      const isMatch = await bcrypt.compare(password, user.password);

      if (!isMatch) {
        return res
          .status(400)
          .json({ errors: [{ msg: 'Invalid credentials' }] });
      }

      // Return jsonwebtoken
      const payload = {
        user: {
          id: user.id,
        },
      };

      jwt.sign(
        payload,
        config.get('jwtSecret'),
        { expiresIn: '5 days' },
        (err, token) => {
          if (err) throw err;
          res.json({ token });
        }
      );
    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server error');
    }
  }
);

// @route    GET /profile
// @desc     Get full user profile
// @access   Private

app.get('/profile', auth, async (req, res) => {
  try {
    let user = await User.findOne({ user: req.user.id }).select('-password');

    res.json(user);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server error');
  }
});

// @route    POST /profile/edit/:id
// @desc     edit profile
// @access   Private

app.put('/profile/edit/:id', upload.single('image'), auth, async (req, res) => {
  const { name, bio, email, phone, password } = req.body;

  try {
    let user = await AuthUser.findById(req.params.id);

    // Delete image from cloudinary
    if (user.cloudinary_id !== '')
      await cloudinary.uploader.destroy(user.cloudinary_id);

    // Upload image to cloudinary
    let result;
    if (req.file) {
      result = await cloudinary.uploader.upload(req.file.path);
    }

    const data = {
      name: name || user.name,
      avatar: (result && result.secure_url) || user.avatar,
      bio: bio || user.bio,
      email: email || user.email,
      phone: phone || user.phone,
      password: password || user.password,
      cloudinary_id: (result && result.public_id) || user.cloudinary_id,
    };

    if (password !== '') {
      // Encrypt password
      const salt = await bcrypt.genSalt(10);

      data.password = await bcrypt.hash(password, salt);
    }

    //   Update
    user = await User.findByIdAndUpdate(req.params.id, data, { new: true });

    return res.json(data);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server error');
  }
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

CodePudding user response:

On the /profile route, what is

await User.findOne({ user: req.user.id }).select('-password');

returning?

It looks to me as if your are trying to find a user whose "user" property is the id, but your User model has no such property. So try replacing that with

await User.findById(req.user.id);

I'm assuming mongoose creates ObjectIDs for your documents.

  • Related