110 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const fs = require('fs');
 | |
| const path = require('path');
 | |
| const { Sequelize, Utils } = require('sequelize');
 | |
| const process = require('process');
 | |
| const basename = path.basename(__filename);
 | |
| const env = process.env.NODE_ENV || 'development';
 | |
| const config = require(__dirname + '/config/config.js');
 | |
| const db = {};
 | |
| 
 | |
| let sequelize;
 | |
| 
 | |
| // Connect sequelize models to LDAP models
 | |
| const ldapModels = require('../ldap');
 | |
| 
 | |
| function getFieldWithLdap(attributes){
 | |
|   let out = [];
 | |
| 
 | |
|   for (const [attribute, options] of Object.entries(attributes)) {
 | |
|     if(options.ldapModel) out.push(attribute)
 | |
|   }
 | |
|   
 | |
|   return out;
 | |
| }
 | |
| 
 | |
| const sequilze_conf = {
 | |
|   define: {
 | |
|     hooks: {
 | |
|       async afterValidate(instance) {
 | |
|         let hasError = false;
 | |
|         function itemError(key, validator, message){
 | |
|           let error = new Sequelize.ValidationErrorItem(message);
 | |
|           error.type = 'Validation error';
 | |
|           error.path = key;
 | |
|           error.origin = 'FUNCTION';
 | |
|           error.instance = instance;
 | |
|           error.validatorKey = 'validator';
 | |
|           error.validatorName = 'validator';
 | |
|           error.validatorArgs = [];
 | |
|           error.original = [];
 | |
| 
 | |
|           throw new Sequelize.ValidationError(null, [error]);
 | |
|         }
 | |
| 
 | |
|         for(let attribute of getFieldWithLdap(this.getAttributes())){
 | |
|           let externalModel = ldapModels[this.getAttributes()[attribute].ldapModel];
 | |
|         
 | |
|           if(!externalModel) itemError(attribute, 'modelExists', `LDAP model ${this.getAttributes()[attribute].ldapModel} not found.`);
 | |
| 
 | |
|           if(!hasError && !(await externalModel.exists(instance[attribute])) ) itemError(attribute, 'foreignKey', `LDAP model has no object ${instance[attribute]}`);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| class _Model extends Sequelize.Model{
 | |
|   constructor(...args){
 | |
|     super(...args)
 | |
|     let hasLdap = getFieldWithLdap(this.constructor.getAttributes())
 | |
|     for(let attribute of hasLdap){
 | |
|       let externalModelName = this.constructor.getAttributes()[attribute].ldapModel;
 | |
|       this[`get${externalModelName}`] = async function(){
 | |
|         return await ldapModels[externalModelName].get(this[attribute]);
 | |
|       } 
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Backward compatible with my LDAP and Redis models.
 | |
|   // I will update the LDAP and Redis stuff to have method interfaces inline with sequilze
 | |
|   static async get(token){
 | |
|     return await this.findByPk(token);
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| if (config.use_env_variable) {
 | |
|   sequelize = new Sequelize(process.env[config.use_env_variable], config);
 | |
| } else {
 | |
|   sequelize = new Sequelize(config.database, config.username, config.password, {...config, ...sequilze_conf});
 | |
| }
 | |
| 
 | |
| 
 | |
| fs
 | |
|   .readdirSync(__dirname)
 | |
|   .filter(file => {
 | |
|     return (
 | |
|       file.indexOf('.') !== 0 &&
 | |
|       file !== basename &&
 | |
|       file.slice(-3) === '.js' &&
 | |
|       file.indexOf('.test.js') === -1
 | |
|     );
 | |
|   })
 | |
|   .forEach(file => {
 | |
|     const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes, _Model);
 | |
|     db[model.name] = model;
 | |
|   });
 | |
| 
 | |
| Object.keys(db).forEach(modelName => {
 | |
|   if (db[modelName].associate) {
 | |
|     db[modelName].associate(db);
 | |
|   }
 | |
| });
 | |
| 
 | |
| db.sequelize = sequelize;
 | |
| db.Sequelize = Sequelize;
 | |
| 
 | |
| module.exports = db;
 |