-1

I'm learning NodeJS coming from Laravel. I've setup a basic validation for user registration in the hook provided by the Feathers generator.

How would I use the user service to check if an email address already exists in the DB? I'm using MongoDB as the database for the service

const {authenticate} = require('@feathersjs/authentication').hooks;
const validator = require('validator');

const {
    hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;

module.exports = {
    before: {
        all: [],
        find: [authenticate('jwt')],
        get: [authenticate('jwt')],
        create: [hashPassword(),
        function(context) {
            let input = context.data;
            const userService = app.service('users');

            if (validator.isEmpty(input.name)) {
                throw new Error('Please enter your name.');
            }
            if (validator.isEmpty(input.email)) {
                throw new Error('Please enter your email address.');
            } else if (!validator.isEmail(input.email)) {
                throw new Error('Please enter a valid email address.');
            }
            if (validator.isEmpty(input.password)) {
                throw new Error('Please enter a password for your account.');
            }

            userService.find({
                query: {
                    email: input.email
                }
            }).then((users) => {
                console.log(users);
            })
        }
        ],
        update: [hashPassword(), authenticate('jwt')],
        patch: [hashPassword(), authenticate('jwt')],
        remove: [authenticate('jwt')]
    },

    after: {
        all: [
            // Make sure the password field is never sent to the client
            // Always must be the last hook
            protect('password')
        ],
        find: [],
        get: [],
        create: [],
        update: [],
        patch: [],
        remove: []
    },

    error: {
        all: [],
        find: [],
        get: [],
        create: [

        ],
        update: [],
        patch: [],
        remove: []
    }
};
Josh
  • 2,430
  • 4
  • 18
  • 30

1 Answers1

1

The context object allows access to the service of the hook. (This is the solution to the question) Therefore, the following code can be used to determine if an email address of a user exists in the DB.

Additionally, the duplicate email check will execute AFTER the user is inserted to the DB, as it is a promise. Therefore, async and await are used to wait for the promise to resolve before continuing.

module.exports = {
    before: {
        all: [],
        find: [authenticate('jwt')],
        get: [authenticate('jwt')],
        create: [hashPassword(),
        async context => {
            let input = context.data;
            //const userService = app.service('users');

            if (validator.isEmpty(input.name)) {
                throw new Error('Please enter your name.');
            }
            if (validator.isEmpty(input.email)) {
                throw new Error('Please enter your email address.');
            } else if (!validator.isEmail(input.email)) {
                throw new Error('Please enter a valid email address.');
            }
            if (validator.isEmpty(input.password)) {
                throw new Error('Please enter a password for your account.');
            }

            await context.service.find({
                query: {
                    email: input.email
                }
            }).then((data) => {
                 if (data.data.length) {
                throw new Error('This email address is already in use by somebody else.');
            }
            });

        }
        ],
        update: [hashPassword(), authenticate('jwt')],
        patch: [hashPassword(), authenticate('jwt')],
        remove: [authenticate('jwt')]
    },
Josh
  • 2,430
  • 4
  • 18
  • 30