User model

User model class inherits the User class that provides authentication of user interface, and the areto/db/ActiveRecord class that manages database.

model/User.js

const Base = require('areto/db/ActiveRecord');

module.exports = class User extends Base {
  // place methods here
};
module.exports.init(module);

const SecurityHelper = require('areto/helper/SecurityHelper');

Define static properties of a class in getConstants method.

  • TABLE - is name of table that stores records.
  • ATTRS - this model attributes to be stored in database. The _id attribute is used as a model identifier. It is created by MongoDB for each new record.

Static properties are available both through the class itself, and an instance: User.TABLE === (new User).TABLE === (new User).constructor.TABLE.

The init method is used to initialize static properties. It is called immediately after class definition. Its argument is the current file module Node.js: module.exports.init(module).

model/User.js

static getConstants () {
  return {
    TABLE: 'user',
    ATTRS: [
      'name',
      'email',
      'role',
      'status',
      'passwordHash',
      'authKey'
    ],
    BEHAVIORS: {
      'timestamp': require('areto/behavior/TimestampBehavior')
    },
    STATUS_PENDING: 'penging',
    STATUS_ACTIVE: 'active',
    STATUS_BANNED: 'banned',
    ROLE_READER: 'reader',
    ROLE_AUTHOR: 'author',
    ROLE_EDITOR: 'editor',
    ROLE_MODERATOR: 'moderator',
    ROLE_ADMIN: 'admin',
    AUTH_KEY_LENGTH: 16
  };
}

The findIdentity method searches a database record by ID id and status (status === 'active'). It is necessary to search for authenticated user according to data stored in session.

model/User.js

findIdentity (id) {
 return this.findById(id).and({status: this.STATUS_ACTIVE});
}

The init method is called immediately after you create a model. It provides an initialization of attribute values. If you override it, then call a parent class method to work properly super.init.

model/User.js

constructor (config) {
  super(config);
  this.set('role', this.ROLE_AUTHOR);
  this.set('status', this.STATUS_ACTIVE);
}

The getTitle method returns the name of model to be displayed in different cases. By default, it uses model ID.

model/User.js

getTitle () {
  return this.get('name');
}

The isActive, isBanned methods used to check the current status of user.

model/User.js

isActive () {
  return this.get('status') === this.STATUS_ACTIVE;
}

isBanned () {
  return this.get('status') === this.STATUS_BANNED;
}

The getAssignments method returns a user role stored in the role attribute that is needed to authorize access to resources of blog.

model/User.js

async getAssignments () {
  return [this.get('role')];
}

The beforeSave method is called before saving a model. It is asynchronous, so at the end of work is to be called cb. Also, if you override it, then you must call the super.beforeSave() parent asynchronous method.

model/User.js

async beforeSave (insert) {
  await super.beforeSave(insert);
  this.setPasswordHash();
  if (insert) {
    this.setAuthKey();
  }
}

setAuthKey () {
  this.set('authKey', SecurityHelper.getRandomString(this.AUTH_KEY_LENGTH));
}

The last couple of methods manage user password. To do this, connect the areto/helper/Security helper class after User initialization. Only the sha1 password hash is stored in the database.

model/User.js

checkPassword (password) {
  return SecurityHelper.checkPassword(password, this.get('passwordHash'));
}

setPasswordHash () {
  const password = this.get('password');
  if (password) {
    this.set('passwordHash', SecurityHelper.encryptPassword(password));
  }
}