0
votes

I'm making a simple Express server with authentication and I hit a bump on the road when making a form to upload an avatar on signup. I want an user to be able to input an username, email, password and image when signing up, and for the image to be stored in the server, and the relative path to be stored on a property of the user object. There are several posts on similar issues, but I cannot find what's wrong with my code.

Routes:

const passport = require('passport')
const router = express.Router()
const { ensureLoggedIn, ensureLoggedOut } = require('connect-ensure-login')

const multer = require('multer')
const Image = require('./../models/Image.model')
const upload = multer({ dest: './../public/uploads', storage: './../public/uploads' })

  '/signup',
  upload.single('avatar'),
  ensureLoggedOut(),
  (req, res) => {

    console.log(req.file)

    const avatarPath = `/uploads/${req.file.filename}`

    Image.create({
      name: req.file.originalname,
      path: avatarPath
    })

    passport.authenticate('local-signup', {
      successRedirect: '/profile',
      failureRedirect: '/signup',
      failureFlash: true,
    })
  }
)

Passport configuration:

  'local-signup',
  new LocalStrategy(
    { passReqToCallback: true },
    (req, username, password, avatarPath, next) => {
      const { email } = req.body

      bcrypt
        .hash(password, 10)
        .then((hash) => {
          return User.create({
            username,
            email,
            password: hash,
            avatar: avatarPath,
          })
        })
        .then((user) => next(null, user))
        .catch((err) => next(err))
    }
  )
)

HTML:

        <div class="form-group">
          <label for="username">Username</label>
          <input type="text" name="username" class="form-control">
        </div>
        <div class="form-group">
          <label for="email">Email</label>
          <input type="text" name="email" class="form-control">
        </div>
        <div class="form-group">
          <label for="password">Password</label>
          <input type="password" name="password" class="form-control">
        </div>
        <div class="form-group">
          <label for="avatar">Avatar</label>
          <input type="file" name="avatar" class="form-control" enctype="multipart/form-data">
        </div>
        <button type="submit">Signup</button>
      </form>```



1

1 Answers

0
votes

Nevermind, I fixed it. There were several errors - first of them I should be defining the enctype at the start of the form, like;

<form action="/signup" method="post" enctype="multipart/form-data">

then, while I have to call Multer on the POST route to upload the file, it is the Passport middleware which picks up the request. If i do a console.log(req.file) there, it is picked up with no problems.