We worked on registration in the previous module, introducing a POST call to the /api/auth/register URL in the file pages/api/auth/register.js.

Let’s move that functionality from that file to the server.js file. We centralize our API.

The pages/api/auth/register.js file now contains this code:

import { User } from '../../../model.js'

export default async (req, res) => {
  if (req.method !== 'POST') {
    res.status(405).end() //Method Not Allowed
    return
  }

  const { email, password, passwordconfirmation } = req.body

  if (password !== passwordconfirmation) {
    res.end(
      JSON.stringify({ status: 'error', message: 'Passwords do not match' })
    )
    return
  }

  try {
    const user = await User.create({ email, password })
    res.end(JSON.stringify({ status: 'success', message: 'User added' }))
  } catch (error) {
    res.statusCode = 500
    let message = 'An error occurred'
    if (error.name === 'SequelizeUniqueConstraintError') {
      message = 'User already exists'
    }
    res.end(JSON.stringify({ status: 'error', message }))
  }
}

In server.js, after the server.use() block, create this endpoint:

server.post('/api/auth/register', async (req, res) => {

})

and inside it past the code that we had in the other file:

server.js

server.post('/api/auth/register', async (req, res) => {
	const { email, password, passwordconfirmation } = req.body

	if (password !== passwordconfirmation) {
		res.end(
			JSON.stringify({ status: 'error', message: 'Passwords do not match' })
		)
		return
	}

	try {
		const user = await User.create({ email, password })
    res.end(JSON.stringify({ status: 'success', message: 'User added' }))
	} catch (error) {
		res.statusCode = 500
		let message = 'An error occurred'
		if (error.name === 'SequelizeUniqueConstraintError') {
			message = 'User already exists'
		}
		res.end(JSON.stringify({ status: 'error', message }))
	}
})

Right now when we receive this POST request, we invoke User.create() to add a new user to the database.

Let’s do one more thing: we want to create a session.

After the User.create() call, we call res.login(). This method makes Passport log in the user:

server.js

req.login(user, err => {
	if (err) {
		res.statusCode = 500
		res.end(JSON.stringify({ status: 'error', message: err }))
		return
	}

	return res.end(
		JSON.stringify({ status: 'success', message: 'Logged in' })
	)
})

and doing so, we immediately log in the users after they register.

Here’s the full endpoint code right now:

server.js

server.post('/api/auth/register', async (req, res) => {
	const { email, password, passwordconfirmation } = req.body

	if (password !== passwordconfirmation) {
		res.end(
			JSON.stringify({ status: 'error', message: 'Passwords do not match' })
		)
		return
	}

	try {
		const user = await User.create({ email, password })

		req.login(user, err => {
			if (err) {
				res.statusCode = 500
				res.end(JSON.stringify({ status: 'error', message: err }))
				return
			}

			return res.end(
				JSON.stringify({ status: 'success', message: 'Logged in' })
			)
		})
	} catch (error) {
		res.statusCode = 500
		let message = 'An error occurred'
		if (error.name === 'SequelizeUniqueConstraintError') {
			message = 'User already exists'
		}
		res.end(JSON.stringify({ status: 'error', message }))
	}
})

This function is going to run the logic we defined previously in the passport.use(new LocalStrategy()) call. We return an error if things go wrong during the login process, so let’s handle this possibility in the components/RegistrationModal.js component, showing the error message in an alert() box if something happens.:

components/RegistrationModal.js

try {
  const response = await axios.post('auth/register', { email, password, passwordconfirmation })
  if (response.data.status === 'error') {
    alert(response.data.message)
    return
  }
} catch (error) {
  alert(error.response.data.message)
  return
}

Go to the next lesson