const Ajv = require("ajv") const confSchema = require('./configSchema.json') let DynamoDBClient, GetItemCommand, marshall, unmarshall module.exports = class configHelper { constructor(options){ this.config = {} if(options.onAws) { DynamoDBClient = require("@aws-sdk/client-dynamodb").DynamoDBClient GetItemCommand = require("@aws-sdk/client-dynamodb").GetItemCommand marshall = require("@aws-sdk/util-dynamodb").marshall unmarshall = require("@aws-sdk/util-dynamodb").unmarshall this. dynamoClient = new DynamoDBClient({ region: options.awsRegion }) this.awsTable = options.awsTable this.awsServiceName = options.awsServiceName this.fetchConfig = this.fetchConfigDynamo this.refreshAccessRights = this.refreshAccessRightsDynamo } else { this.localfile = options.localfile this.fetchConfig = this.fetchConfigFile this.refreshAccessRights = this.refreshAccessRightsFile } const ajv = new Ajv({ allowUnionTypes: true }) this.configValidator = ajv.compile(confSchema) } isValidConfig(conf){ if(this.configValidator(conf)) return(true) console.error('Invalid configuration: ', this.configValidator.errors) return(false) } async dynamoGet(subKey = null){ let params = new GetItemCommand({ TableName: this.awsTable, Key: { serviceName: marshall(this.awsServiceName), }, }) let result = await this.dynamoClient.send(params) let obj = unmarshall(result.Item) if((typeof(subKey)=='string') && (subKey in obj)) return(obj[subKey]) return(obj) } async fetchConfigDynamo(){ let curConfig = this.config this.config = await this.dynamoGet() if(process.env.UNSECURE) this.config.server.unsecure = Boolean(process.env.UNSECURE); if(process.env.REDIS_HOST) this.config.redis.host = process.env.REDIS_HOST; if(process.env.REDIS_TLS) this.config.redis.tls = Boolean(process.env.REDIS_TLS); if(process.env.REDIS_PORT) this.config.redis.port = Number(process.env.REDIS_PORT); if(process.env.REDIS_USER) this.config.redis.user = process.env.REDIS_USER; if(process.env.REDIS_PASSWORD) this.config.redis.pass = process.env.REDIS_PASSWORD; if(this.isValidConfig(this.config)) return(this.config) console.error(this.isValidConfig.errors) //revert if invalid conf this.config = curConfig } async fetchConfigFile(){ let curConfig = this.config this.config = await require(this.localfile) if(this.isValidConfig(this.config)) return(this.config) console.error(this.isValidConfig.errors) //revert if invalid conf this.config = curConfig } async refreshAccessRightsDynamo(){ let ar = await this.dynamoGet('accessRights') this.config.accessRights = ar } async refreshAccessRightsFile(){ delete require.cache[require.resolve(this.localfile)] let tmp try { tmp = require(this.localfile) } catch(err) { console.error('Error Reloading config !! (bad json?) => Keeping current accessRights !') return } if(!tmp.accessRights) { console.error('Error Reloading config !! (no accessRights !) => Keeping current accessRights !') return } this.config.accessRights = tmp.accessRights } }