<commit_before>var _ = require('underscore');
var bcrypt = require('bcrypt');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var jwt = require('jsonwebtoken');  //https://npmjs.org/package/node-jsonwebtoken
var async = require('async');

var molecuel;
var elements;

/**
 * This module serves user database element
 * @todo implement dynamic user authentication registration.
 * @constructor
 */

var user = function() {
  var self = this;

  // Add libraries
  this.jwt = jwt;

  // secret
  this.secret = molecuel.config.user.secret;

  //  define default roles
  var roles = ['admin','editor'];
  // check if there are roles defined by the configuration of the current project
  if(molecuel.config && molecuel.config.user && molecuel.config.user.roles) {
    roles = molecuel.config.user.roles;
  }

  this.passport = passport;

  // Definition of the user schema
  this.userSchema =  {
    // Definition of the username
    username: { type: String, list: true, required: true, trim: true, unique: true, index: true },
    // Define the email address
    email: { type: String, list: true, trim: true, lowercase: true, required: true},

    // save the date and time of the last login
    lastlogin: { type: Date, 'default': Date.now, form: {readonly: true}},
    // save date and time of the last logon error
    lasterror: { type: Date, form: {readonly: true}},
    // save the creation date of the user
    creation: { type: Date, 'default': Date.now, form: {readonly: true}},
    // count the visits of the user
    visits: {type: Number, 'default': 0, form: {readonly: true}},

    // Password
    // these two fields are fake fields only and will be deleted
    password: {type: String},
    passwordConfirmation: {type: String, form:{ secure: true}},

    // password save
    salt: { type: String, required: false, form: {hidden:true }},
    hash: { type: String, required: false, form: {hidden: true}},

    name: {
      first: { type: String, required: false, trim: true },
      last: { type: String, required: false, trim: true }
    },
    authtype: {type: String, 'default': 'local'},
    active: { type: Boolean, 'default': true, index: true},
    roles: [{
      type: String,
      enum: roles,
      required: false,
      form:{
        formStyle: 'inline',
        placeHolder: 'Select roles'
      }
    }]
  };

  molecuel.once('mlcl::elements::registrations:pre', function(module) {
    elements = module;
    // module == elements module
    var schemaDefinition = {
      schemaName: 'user',
      schema: self.userSchema,
      options: {indexable: true, avoidTranslate: true, avoidUrl: true}
    };
    elements.registerSchemaDefinition(schemaDefinition);
  });

  // on elements registration of user schema
  molecuel.on('mlcl::elements::registerSchema:post::user', function(module, schemaRegistryEntry) {
    self.schema = schemaRegistryEntry.schema;
    //module.addToBaseSchema({createdby: {type: elements.ObjectId, ref: 'user', form:{hidden:true}}});
    self.schema.plugin(self._registerDefaultschemaFunctions);
  });

  // schema registration event
  molecuel.on('mlcl::elements::registerSchema:post', function(module, schemaname, schemaRegistryEntry) {
    schemaRegistryEntry.schema.plugin(self._defaultSchemaPlugin);
  });


  molecuel.on('mlcl::elements::setElementType:post::user', function(module, model) {
    self.model = model;
    self._registerDefaultPassportFunctions(model);
    molecuel.emit('mlcl::user::init:post', self);
  });

  molecuel.once('mlcl::elements::init:post', function(elements) {
    elements.registerPostApiHandler(self._postApiHandler);
  });
  return this;
};

/*************************************************************************
 SINGLETON CLASS DEFINITION
 *************************************************************************/
var instance = null;

/**
 * Singleton getInstance definition
 * @return singleton class
 */
var getInstance = function () {
  if (instance === null) {
    instance = new user();
  }
  return instance;
};

user.prototype.middleware = function middleware(config, app) {
  if(molecuel.config && molecuel.config.user.secret) {
    app.use(passport.initialize());
    app.use(getInstance().initUser);
    app.post('/login/jwt', passport.authenticate('local', { session: false }), getInstance().userLogin);
  }
};

/**
 * Middleware function to register the current user on the request
 * @todo: Is this the right place?
 * @param req
 * @param res
 * @param next
 */
user.prototype.initUser = function(req, res, next) {
  if(req.headers.authorization) {
    jwt.verify(req.headers.authorization, molecuel.config.user.secret, function(err, decoded) {
      if(err && !decoded) {
        next();
      } else {
        req.user = decoded;
        next();
      }
    });
  } else {
    next();
  }
};

user.prototype.getTokenFromRequest = function(req) {
    var expiresInMinutes = 60*4;
    // Check if there is a session expiration defined
    if(molecuel.config.user && molecuel.config.user.session_expiration) {
      expiresInMinutes = molecuel.config.user.session_expiration;
    }
    var token = jwt.sign(JSON.parse(JSON.stringify(req.user)), molecuel.config.user.secret, { expiresInMinutes: expiresInMinutes });
    return token;
}

user.prototype.getUserObjectFromRequest = function(req) {
  var token = this.getTokenFromRequest(req);
  var user = {name: req.user.name, _id: req.user._id, authtype: req.user.authtype, username: req.user.username, email: req.user.email, token: token }
  return user;
}

/**
 * userLogin - description
 *
 * @param  {type} req description
 * @param  {type} res description
 * @return {type}     description
 */
user.prototype.userLogin = function userLogin(req, res) {
  // We are sending the profile inside the token
  var expiresInMinutes = 60*4;
  // Check if there is a session expiration defined
  if(molecuel.config.user && molecuel.config.user.session_expiration) {
    expiresInMinutes = molecuel.config.user.session_expiration;
  }
  var token = jwt.sign(JSON.parse(JSON.stringify(req.user)), molecuel.config.user.secret, { expiresInMinutes: expiresInMinutes });
  res.json({name: user.name, _id: user._id, username: user.username, email: user.email, token: token });
};

user.prototype.debugHeader = function debugHeader(req, res, next) {
  console.log(req.headers);
  console.log(req.body);
  next();
};
<commit_msg>fixed jshint<commit_after>var _ = require('underscore');
var bcrypt = require('bcrypt');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var jwt = require('jsonwebtoken');  //https://npmjs.org/package/node-jsonwebtoken
var async = require('async');

var molecuel;
var elements;

/**
 * This module serves user database element
 * @todo implement dynamic user authentication registration.
 * @constructor
 */

var user = function() {
  var self = this;

  // Add libraries
  this.jwt = jwt;

  // secret
  this.secret = molecuel.config.user.secret;

  //  define default roles
  var roles = ['admin','editor'];
  // check if there are roles defined by the configuration of the current project
  if(molecuel.config && molecuel.config.user && molecuel.config.user.roles) {
    roles = molecuel.config.user.roles;
  }

  this.passport = passport;

  // Definition of the user schema
  this.userSchema =  {
    // Definition of the username
    username: { type: String, list: true, required: true, trim: true, unique: true, index: true },
    // Define the email address
    email: { type: String, list: true, trim: true, lowercase: true, required: true},

    // save the date and time of the last login
    lastlogin: { type: Date, 'default': Date.now, form: {readonly: true}},
    // save date and time of the last logon error
    lasterror: { type: Date, form: {readonly: true}},
    // save the creation date of the user
    creation: { type: Date, 'default': Date.now, form: {readonly: true}},
    // count the visits of the user
    visits: {type: Number, 'default': 0, form: {readonly: true}},

    // Password
    // these two fields are fake fields only and will be deleted
    password: {type: String},
    passwordConfirmation: {type: String, form:{ secure: true}},

    // password save
    salt: { type: String, required: false, form: {hidden:true }},
    hash: { type: String, required: false, form: {hidden: true}},

    name: {
      first: { type: String, required: false, trim: true },
      last: { type: String, required: false, trim: true }
    },
    authtype: {type: String, 'default': 'local'},
    active: { type: Boolean, 'default': true, index: true},
    roles: [{
      type: String,
      enum: roles,
      required: false,
      form:{
        formStyle: 'inline',
        placeHolder: 'Select roles'
      }
    }]
  };

  molecuel.once('mlcl::elements::registrations:pre', function(module) {
    elements = module;
    // module == elements module
    var schemaDefinition = {
      schemaName: 'user',
      schema: self.userSchema,
      options: {indexable: true, avoidTranslate: true, avoidUrl: true}
    };
    elements.registerSchemaDefinition(schemaDefinition);
  });

  // on elements registration of user schema
  molecuel.on('mlcl::elements::registerSchema:post::user', function(module, schemaRegistryEntry) {
    self.schema = schemaRegistryEntry.schema;
    //module.addToBaseSchema({createdby: {type: elements.ObjectId, ref: 'user', form:{hidden:true}}});
    self.schema.plugin(self._registerDefaultschemaFunctions);
  });

  // schema registration event
  molecuel.on('mlcl::elements::registerSchema:post', function(module, schemaname, schemaRegistryEntry) {
    schemaRegistryEntry.schema.plugin(self._defaultSchemaPlugin);
  });


  molecuel.on('mlcl::elements::setElementType:post::user', function(module, model) {
    self.model = model;
    self._registerDefaultPassportFunctions(model);
    molecuel.emit('mlcl::user::init:post', self);
  });

  molecuel.once('mlcl::elements::init:post', function(elements) {
    elements.registerPostApiHandler(self._postApiHandler);
  });
  return this;
};

/*************************************************************************
 SINGLETON CLASS DEFINITION
 *************************************************************************/
var instance = null;

/**
 * Singleton getInstance definition
 * @return singleton class
 */
var getInstance = function () {
  if (instance === null) {
    instance = new user();
  }
  return instance;
};

user.prototype.middleware = function middleware(config, app) {
  if(molecuel.config && molecuel.config.user.secret) {
    app.use(passport.initialize());
    app.use(getInstance().initUser);
    app.post('/login/jwt', passport.authenticate('local', { session: false }), getInstance().userLogin);
  }
};

/**
 * Middleware function to register the current user on the request
 * @todo: Is this the right place?
 * @param req
 * @param res
 * @param next
 */
user.prototype.initUser = function(req, res, next) {
  if(req.headers.authorization) {
    jwt.verify(req.headers.authorization, molecuel.config.user.secret, function(err, decoded) {
      if(err && !decoded) {
        next();
      } else {
        req.user = decoded;
        next();
      }
    });
  } else {
    next();
  }
};

user.prototype.getTokenFromRequest = function(req) {
    var expiresInMinutes = 60*4;
    // Check if there is a session expiration defined
    if(molecuel.config.user && molecuel.config.user.session_expiration) {
      expiresInMinutes = molecuel.config.user.session_expiration;
    }
    var token = jwt.sign(JSON.parse(JSON.stringify(req.user)), molecuel.config.user.secret, { expiresInMinutes: expiresInMinutes });
    return token;
};

user.prototype.getUserObjectFromRequest = function(req) {
  var token = this.getTokenFromRequest(req);
  var user = {
    name: req.user.name,
    _id: req.user._id,
    authtype: req.user.authtype,
    username: req.user.username,
    email: req.user.email, token: token
  };
  return user;
};

/**
 * userLogin - description
 *
 * @param  {type} req description
 * @param  {type} res description
 * @return {type}     description
 */
user.prototype.userLogin = function userLogin(req, res) {
  // We are sending the profile inside the token
  var expiresInMinutes = 60*4;
  // Check if there is a session expiration defined
  if(molecuel.config.user && molecuel.config.user.session_expiration) {
    expiresInMinutes = molecuel.config.user.session_expiration;
  }
  var token = jwt.sign(JSON.parse(JSON.stringify(req.user)), molecuel.config.user.secret, { expiresInMinutes: expiresInMinutes });
  res.json({name: user.name, _id: user._id, username: user.username, email: user.email, token: token });
};

user.prototype.debugHeader = function debugHeader(req, res, next) {
  console.log(req.headers);
  console.log(req.body);
  next();
};

{'fraction_non_alphanumeric': 0.1580010880547136, 'fraction_numerical': 0.0010880547136084557, 'mean_word_length': 3.750092284976006, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '840312', 'n_tokens_mistral': 3936, 'n_tokens_neox': 3849, 'n_words': 995}