jabali
v4.3.2
Published
Simple and flexible authentication workflows for nodejs and mongodb
Downloads
30
Maintainers
Readme
Jabali
Jabali is the mongoose plugin used as the flexible authentication solution. Jabali when plugged into mongoose schema, it extends the schema with some fields based on OpenID connect specification.
Modules
Jabali is organized on modularity architecture. Jabali modules consists of;
- Registerable Module responsible for user sign up.
- Authenticable Module to handle authentication flow.
- Confirmable Module responsible to manage email or phone confirmation.
- Recoverable Module responsible for resetting account password
Features
- User signup
- User login using email, phone number or any other preferred user field together with password. See
aliases
options - Email and phone number validation
- Password validation using configurable policies such as minimum length, presence of number, capital letter etc
- Account confirmation work flow using email or phone number(You need to have your own setup to send token to phone or email)
- Password reset work flow
- Ability to configure time period to allow user to access resources without account confirmation. After the period expired user will not be able to authenticate without account confirmation.
Prerequisites
Installing
npm i --save jabali
Usage
Sample example
const jabali = require('jabali')
// user schema
const UserSchema = new Schema({
...
})
// plugin jabali default module
UserSchema.plugin(jabali, options)
// register user schema
mongoose.model('User', UserSchema)
Options
Jabali's options can be declared as an object with key names corresponding to modules and key values equal to object contain options of the specified module. Below are the options available in each module.
Registerable
email_required
{Boolean} - set if email is required.phone_required
{Boolean} - set if phone is required.password_policies
{Object} - Object with password policiespassword_policies.min_length
{Number} - Set the minimum number of character passwor should havepassword_policies.number
{Boolean} - Set if atleast one number should be present in the passwordpassword_policies.lowercase
{Boolean} - Set if atleast one lowercase character should be present in passwordpassword_policies.uppercase
{Boolean} - Set if atleast one uppercase character should be present in password
Authenticable
aliases
{String[]} - an array of fields names to use together with password for authentication. Example ['email', 'employeeId'], this will allow to authenticate using email or employeedId as username. EmployeeId is user schema defined field not specific for jabali. Email field is the default field for authentication
Confirmable
token_life
{Number} - Number of days it will take before confirmation token expire. Default is 1 dayallow_unconfirmed_access_for
{Number} - Number of days to allow user to authenticate and use the resource before confirming the account. If it is set to zero it means user will not be allowed to authenticate at all before confirming the account. The default is zero
Recoverable
Options
token_life
{Number} - Number of days it will take before recoverable token expire. Default is 1 day.aliases
{String[]} - Array of field names to use during password reset.
Sample example
const jabali = require('jabali')
// user schema
const UserSchema = new Schema({
...
})
const options = {
// options for authenticable module
authenticable:{
aliases: ['email']
},
// options for confirmable module
confirmable: {
token_life: 7
}
}
// plugin jabali default module
UserSchema.plugin(jabali, options)
// register user schema
mongoose.model('User', UserSchema)
API
Model.register(payload)
- It register an account, the different between this method and normal mongoose create method is the fact that this method register user and set password and other fields as per jabali specification.Model.unregister(criteria)
- It unregister accountModel.authenticate(alias, password)
Instance.changePassword(newPassword)
Model.confirm(username, confirmationToken)
- It calls account confirmation, username can either be email or phone numberModel.sendConfirmationInstructions(username)
- It send out account confirmtion instructions.Instance.sendConfirmationInstructions
- It send out account confirmtion instructions.Model.passwordReset(alias, newPassword, recoveryToken)
- It reset passwordInstance.sendPasswordResetInstructions()
- It send out password reset instructions.
Account Confirmation Instructions
By default, account/user registeration action automatically send account confirmation instructions. This behaviour can be disabled per user instance if autoSendConfirmationInstructions
user property is set to false
. When set to false, you will need to send confirmation instructions manual by calling static method Model.sendConfirmationInstructions(username)
.
Hooks
Jabali also support hooks which are functions used to add custom behaviours prior or post certain actions as follows;
sendJabaliNotification
This is the hook that is triggered post certain events that requires user to be notified such as on password reset request and other event as explained below. This function when called, will be passed two parameters, the first parameter will be event/notification type and the second parameter will be an accompanied event data.
Notification types so far includes but not limited to the followings;
CONFIRMATION_INSTRUCTIONS
- Triggered during user registration or when callingsendConfirmationInstructions
method. An accompanied data will be schema instancePASSWORD_RESET_INSTRUCTIONS
- Triggered when password reset is executed. An accompanied data will be schema instance
Note
This function must return promise and should never reject if you don't want notification to affect the prior action that triggered the notification send**. If failure of notification should roll back the prior actions then you can actual reject the promise otherwise always resolve the promise.
Example
schema.methods.sendJabaliNotification = function(NOTIFICATION_TYPE, instance){
if(NOTIFICATION_TYPE === 'CONFIRMATION_INSTRUCTIONS'){
return Mailer
.sendEmail(instance.email, instance.confirmationToken)
.catch(error => {
// Always resolve because this notification should not roll
// back registration action which triggered it.
return Promise.resolve();
})
}
return Promise.resolve();
}
preSignup
This schema instance method will be triggered prior to user signup/registration and It must return this instance otherwise it break registeration. It can be used forexample to automatically confirm user from a particular domain as follows;
Example
schema.methods.preSignup = function(){
const user = this;
const addresses = user.email.split('@');
if(/mydomain/i.test(addresses[1])){
user.autoConfirm = true;
}
return user;
}
Note:
All hooks must be defined after this plugin is attached to the schema for them to be active.
Testing
Clone this repository
Install all development dependencies
$ npm install
- Then run test
$ npm test
Built With
- npm - Used as the project core technology and build tool
Versioning
We use SemVer for versioning. For the versions available, see the tags on this repository.
Authors
- Isaac Kasongoyo - Initial work
License
This project is licensed under the MIT License - see the LICENSE.md file for details
Acknowledgments
The code and some of the concepts of this project has been inspired by the following libraries