diff --git a/.gitignore b/.gitignore
index 63aacd7..a5b09c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,6 @@
lib/*.map
lib/api-functions.js
lib/auth.js
-lib/config.js
lib/cwmp.js
lib/db.js
lib/nbi.js
diff --git a/lib/config.coffee b/lib/config.coffee
deleted file mode 100644
index 37aa60e..0000000
--- a/lib/config.coffee
+++ /dev/null
@@ -1,209 +0,0 @@
-###
-# Copyright 2013-2017 Zaid Abdulla
-#
-# This file is part of GenieACS.
-#
-# GenieACS is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# GenieACS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with GenieACS. If not, see .
-###
-
-path = require 'path'
-common = require './common'
-
-options = {
- CONFIG_DIR : {type : 'path', default : 'config'},
- MONGODB_CONNECTION_URL : {type : 'string', default : 'mongodb://127.0.0.1/genieacs'},
- REDIS_PORT : {type : 'int', default : 6379},
- REDIS_HOST : {type : 'string', default : ''},
- REDIS_DB : {type : 'int', default : 0},
-
- CWMP_WORKER_PROCESSES : {type : 'int', default : 0},
- CWMP_PORT : {type : 'int', default : 7547},
- CWMP_INTERFACE : {type : 'string', default : '0.0.0.0'},
- CWMP_SSL : {type : 'bool', default : false},
- CWMP_LOG_FILE : {type: 'path', default : ''},
- CWMP_ACCESS_LOG_FILE : {type : 'path', default : ''},
-
- NBI_WORKER_PROCESSES : {type : 'int', default : 0},
- NBI_PORT : {type : 'int', default : 7557},
- NBI_INTERFACE : {type : 'string', default : '0.0.0.0'},
- NBI_SSL : {type : 'bool', default : false},
- NBI_LOG_FILE : {type: 'path', default : ''},
- NBI_ACCESS_LOG_FILE : {type : 'path', default : ''},
-
- FS_WORKER_PROCESSES : {type : 'int', default : 0},
- FS_PORT : {type : 'int', default : 7567},
- FS_INTERFACE : {type : 'string', default : '0.0.0.0'},
- FS_SSL : {type : 'bool', default : false},
- FS_HOSTNAME : {type : 'string', default : 'acs.example.com'},
- FS_LOG_FILE : {type: 'path', default : ''},
- FS_ACCESS_LOG_FILE : {type : 'path', default : ''},
-
- UDP_CONNECTION_REQUEST_PORT : {type : 'int', default : 0},
-
- DOWNLOAD_TIMEOUT: {type : 'int', default : 3600},
- EXT_TIMEOUT: {type: 'int', default: 3000},
- MAX_CACHE_TTL : {type : 'int', default : 86400},
- DEBUG : {type : 'bool', default : false},
- RETRY_DELAY : {type : 'int', default : 300},
- SESSION_TIMEOUT : {type : 'int', default : 30},
- CONNECTION_REQUEST_TIMEOUT : {type : 'int', default: 2000},
- GPN_NEXT_LEVEL : {type : 'int', default : 0},
- GPV_BATCH_SIZE : {type : 'int', default : 32},
- MAX_DEPTH : {type: 'int', default : 16},
- COOKIES_PATH : {type : 'string'},
- LOG_FORMAT : {type : 'string', default : 'simple'},
- ACCESS_LOG_FORMAT : {type : 'string', default : ''},
- MAX_CONCURRENT_REQUESTS : {type : 'int', default: 20},
- DATETIME_MILLISECONDS : {type: 'bool', default: true},
- BOOLEAN_LITERAL : {type: 'bool', default: true},
- CONNECTION_REQUEST_ALLOW_BASIC_AUTH: {type: 'bool', default: false},
- MAX_COMMIT_ITERATIONS : {type : 'int', default: 32},
-
- # XML configuration
- XML_RECOVER : {type : 'bool', default : false},
- XML_IGNORE_ENC : {type : 'bool', default : false},
- XML_FORMAT : {type : 'bool', default : false},
- XML_NO_DECL : {type : 'bool', default : false},
- XML_NO_EMPTY : {type : 'bool', default : false},
- XML_IGNORE_NAMESPACE : {type : 'bool', default : false},
-
- # Should probably never be changed
- DEVICE_ONLINE_THRESHOLD : {type : 'int', default : 4000}
-}
-
-allConfig = {}
-
-
-setConfig = (name, value, commandLineArgument) ->
- return true if allConfig[name]?
-
- # For compatibility with v1.0
- if name in ['PRESETS_CACHE_DURATION', 'presets-cache-duration']
- setConfig('MAX_CACHE_TTL', value)
-
- if name in ['GET_PARAMETER_NAMES_DEPTH_THRESHOLD', 'get-parameter-names-depth-threshold']
- setConfig('GPN_NEXT_LEVEL', value)
-
- if name in ['TASK_PARAMETERS_BATCH_SIZE', 'task-parameters-batch-size']
- setConfig('GPV_BATCH_SIZE', value)
-
- if name in ['IGNORE_XML_NAMESPACES', 'ignore-xml-namespaces']
- setConfig('XML_IGNORE_NAMESPACE', value)
-
- if name in ['XML_PARSE_IGNORE_ENC', 'xml-parse-ignore-enc']
- setConfig('XML_IGNORE_ENC', value)
-
- if name in ['XML_PARSE_RECOVER', 'xml-parse-recover']
- setConfig('XML_RECOVER', value)
-
- if name in ['FS_IP', 'fs-ip']
- setConfig('FS_HOSTNAME', value)
-
- cast = (val, type) ->
- switch type
- when 'int'
- Number(val)
- when 'bool'
- String(val).trim().toLowerCase() in ['true', 'on', 'yes', '1']
- when 'string'
- String(val)
- when 'path'
- if val then path.resolve(val) else ''
- else
- null
-
- _value = null
-
- for optionName, optionDetails of options
- n = optionName
- if commandLineArgument
- n = n.toLowerCase().replace(/_/g, '-')
-
- if name == n
- _value = cast(value, optionDetails.type)
- n = optionName
- else if name.startsWith("#{n}-")
- _value = cast(value, optionDetails.type)
- n = "#{optionName}-#{name[optionName.length+1..]}"
-
- if _value?
- allConfig[n] = _value
- # Save as environmnet variable to pass on to any child processes
- process.env["GENIEACS_#{n}"] = _value
- return true
-
- return false
-
-
-# Command line arguments
-argv = process.argv[2..]
-while argv.length
- arg = argv.shift()
- if arg[0] == '-'
- v = argv.shift()
- setConfig(arg[2..], v, true)
-
-
-# Environment variable
-for k, v of process.env
- continue if k.lastIndexOf('GENIEACS_', 0) != 0
- k = k[9..] # remove "GENIEACS_" prefix
- setConfig(k, v)
-
-
-# Use default config dir if none defined
-setConfig('CONFIG_DIR', options['CONFIG_DIR'].default)
-
-# Configuration file
-for k, v of require(path.resolve(allConfig.CONFIG_DIR, 'config'))
- if not setConfig(k, v)
- # Pass as environment variable to be accessable by extensions
- process.env["GENIEACS_#{k}"] = v
-
-
-# Defaults
-for k, v of options
- setConfig(k, v.default) if v.default?
-
-
-get = (option, deviceId) ->
- if deviceId?
- name = "#{option}-#{deviceId}"
- v = allConfig[name]
- return v if v?
- i = name.lastIndexOf('-')
- v = allConfig[name[0...i]]
- return v if v?
- i = name.lastIndexOf('-', i-1)
- v = allConfig[name[0...i]]
- return v if v? or i == -1
-
- return allConfig[option]
-
-
-getDefault = (optionName) ->
- option = options[optionName]
- return null if not option
- val = option.default
- if val and option.type == 'path'
- val = path.resolve(val)
- return val
-
-
-# load authentication scripts
-try
- exports.auth = require(path.resolve(allConfig.CONFIG_DIR, 'auth'))
-
-exports.get = get
-exports.getDefault = getDefault
diff --git a/lib/config.js b/lib/config.js
new file mode 100644
index 0000000..6c59021
--- /dev/null
+++ b/lib/config.js
@@ -0,0 +1,238 @@
+/**
+ * Copyright 2013-2018 Zaid Abdulla
+ *
+ * This file is part of GenieACS.
+ *
+ * GenieACS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * GenieACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with GenieACS. If not, see .
+ */
+"use strict";
+
+const path = require("path");
+
+const options = {
+ CONFIG_DIR: {type: "path", "default": "config"},
+ MONGODB_CONNECTION_URL: {type: "string", "default": "mongodb://127.0.0.1/genieacs"},
+ REDIS_PORT: {type: "int", "default": 6379},
+ REDIS_HOST: {type: "string", "default": ""},
+ REDIS_DB: {type: "int", "default": 0},
+
+ CWMP_WORKER_PROCESSES: {type: "int", "default": 0},
+ CWMP_PORT: {type: "int", "default": 7547},
+ CWMP_INTERFACE: {type: "string", "default": "0.0.0.0"},
+ CWMP_SSL: {type: "bool", "default": false},
+ CWMP_LOG_FILE: {type: "path", "default": ""},
+ CWMP_ACCESS_LOG_FILE: {type: "path", "default": ""},
+
+ NBI_WORKER_PROCESSES: {type: "int", "default": 0},
+ NBI_PORT: {type: "int", "default": 7557},
+ NBI_INTERFACE: {type: "string", "default": "0.0.0.0"},
+ NBI_SSL: {type: "bool", "default": false},
+ NBI_LOG_FILE: {type: "path", "default": ""},
+ NBI_ACCESS_LOG_FILE: {type: "path", "default": ""},
+
+ FS_WORKER_PROCESSES: {type: "int", "default": 0},
+ FS_PORT: {type: "int", "default": 7567},
+ FS_INTERFACE: {type: "string", "default": "0.0.0.0"},
+ FS_SSL: {type: "bool", "default": false},
+ FS_HOSTNAME: {type: "string", "default": "acs.example.com"},
+ FS_LOG_FILE: {type: "path", "default": ""},
+ FS_ACCESS_LOG_FILE: {type: "path", "default": ""},
+
+ UDP_CONNECTION_REQUEST_PORT: {type: "int", "default": 0},
+
+ DOWNLOAD_TIMEOUT: {type: "int", "default": 3600},
+ EXT_TIMEOUT: {type: "int", "default": 3000},
+ MAX_CACHE_TTL: {type: "int", "default": 86400},
+ DEBUG: {type: "bool", "default": false},
+ RETRY_DELAY: {type: "int", "default": 300},
+ SESSION_TIMEOUT: {type: "int", "default": 30},
+ CONNECTION_REQUEST_TIMEOUT: {type: "int", "default": 2000},
+ GPN_NEXT_LEVEL: {type: "int", "default": 0},
+ GPV_BATCH_SIZE: {type: "int", "default": 32},
+ MAX_DEPTH: {type: "int", "default": 16},
+ COOKIES_PATH: {type: "string"},
+ LOG_FORMAT: {type: "string", "default": "simple"},
+ ACCESS_LOG_FORMAT: {type: "string", "default": ""},
+ MAX_CONCURRENT_REQUESTS: {type: "int", "default": 20},
+ DATETIME_MILLISECONDS: {type: "bool", "default": true},
+ BOOLEAN_LITERAL: {type: "bool", "default": true},
+ CONNECTION_REQUEST_ALLOW_BASIC_AUTH: {type: "bool", "default": false},
+ MAX_COMMIT_ITERATIONS: {type: "int", "default": 32},
+
+ // XML configuration
+ XML_RECOVER: {type: "bool", "default": false},
+ XML_IGNORE_ENC: {type: "bool", "default": false},
+ XML_FORMAT: {type: "bool", "default": false},
+ XML_NO_DECL: {type: "bool", "default": false},
+ XML_NO_EMPTY: {type: "bool", "default": false},
+ XML_IGNORE_NAMESPACE: {type: "bool", "default": false},
+
+ // Should probably never be changed
+ DEVICE_ONLINE_THRESHOLD: {type: "int", "default": 4000}
+};
+
+const allConfig = {};
+
+function setConfig(name, value, commandLineArgument) {
+ if (allConfig[name] != null)
+ return true;
+
+ // For compatibility with v1.0
+ if (name === "PRESETS_CACHE_DURATION" || name === "presets-cache-duration")
+ setConfig("MAX_CACHE_TTL", value);
+
+ if (name === "GET_PARAMETER_NAMES_DEPTH_THRESHOLD" || name === "get-parameter-names-depth-threshold")
+ setConfig("GPN_NEXT_LEVEL", value);
+
+ if (name === "TASK_PARAMETERS_BATCH_SIZE" || name === "task-parameters-batch-size")
+ setConfig("GPV_BATCH_SIZE", value);
+
+ if (name === "IGNORE_XML_NAMESPACES" || name === "ignore-xml-namespaces")
+ setConfig("XML_IGNORE_NAMESPACE", value);
+
+ if (name === "XML_PARSE_IGNORE_ENC" || name === "xml-parse-ignore-enc")
+ setConfig("XML_IGNORE_ENC", value);
+
+ if (name === "XML_PARSE_RECOVER" || name === "xml-parse-recover")
+ setConfig("XML_RECOVER", value);
+
+ if (name === "FS_IP" || name === "fs-ip")
+ setConfig("FS_HOSTNAME", value);
+
+ function cast(val, type) {
+ switch (type) {
+ case "int":
+ return Number(val);
+ case "bool":
+ return ["true", "on", "yes", "1"].includes(String(val).trim().toLowerCase());
+ case "string":
+ return String(val);
+ case "path":
+ if (!val)
+ return "";
+ return path.resolve(val);
+ default:
+ return null;
+ }
+ }
+
+ let _value = null;
+ for (let [optionName, optionDetails] of Object.entries(options)) {
+ let n = optionName;
+ if (commandLineArgument)
+ n = n.toLowerCase().replace(/_/g, "-");
+
+ if (name === n) {
+ _value = cast(value, optionDetails.type);
+ n = optionName;
+ } else if (name.startsWith(`${n}-`)) {
+ _value = cast(value, optionDetails.type);
+ n = `${optionName}-${name.slice(optionName.length + 1)}`;
+ }
+
+ if (_value != null) {
+ allConfig[n] = _value;
+ // Save as environmnet variable to pass on to any child process
+ process.env[`GENIEACS_${n}`] = _value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Command line arguments
+const argv = process.argv.slice(2);
+while (argv.length) {
+ const arg = argv.shift();
+ if (arg[0] === "-") {
+ const v = argv.shift();
+ setConfig(arg.slice(2), v, true);
+ }
+}
+
+// Environment variable
+for (const [k, v] of Object.entries(process.env)) {
+ if (k.startsWith("GENIEACS_"))
+ setConfig(k.slice(9), v);
+}
+
+// Use default config dir if none defined
+setConfig("CONFIG_DIR", options["CONFIG_DIR"]["default"]);
+
+// Configuration file
+const configFile = require(path.resolve(allConfig.CONFIG_DIR, "config"));
+for (const [k, v] of Object.entries(configFile))
+ if (!setConfig(k, v))
+ // Pass as environment variable to be accessable by extensions
+ process.env[`GENIEACS_${k}`] = `${v}`;
+
+// Defaults
+for (const [k, v] of Object.entries(options))
+ if (v["default"] != null)
+ setConfig(k, v["default"]);
+
+function get(optionName, deviceId) {
+ if (!deviceId)
+ return allConfig[optionName];
+
+ optionName = `${optionName}-${deviceId}`;
+ let v = allConfig[optionName];
+ if (v != null)
+ return v;
+
+ let i = optionName.lastIndexOf("-");
+ v = allConfig[optionName.slice(0, i)];
+ if (v != null)
+ return v;
+
+ i = optionName.lastIndexOf("-", i - 1);
+ v = allConfig[optionName.slice(0, i)];
+ if (v != null)
+ return v;
+
+ i = optionName.lastIndexOf("-", i - 1);
+ v = allConfig[optionName.slice(0, i)];
+ if (v != null)
+ return v;
+
+ i = optionName.lastIndexOf("-", i - 1);
+ if (i > 0) {
+ v = allConfig[optionName.slice(0, i)];
+ if (v != null)
+ return v;
+ }
+
+ return null;
+}
+
+function getDefault(optionName) {
+ const option = options[optionName];
+ if (!option)
+ return null;
+
+ let val = option["default"];
+ if (val && option.type === "path")
+ val = path.resolve(val);
+
+ return val;
+}
+
+// Load authentication scripts
+try {
+ exports.auth = require(path.resolve(allConfig.CONFIG_DIR, "auth"));
+} catch (error) {}
+
+exports.get = get;
+exports.getDefault = getDefault;