Compare View

switch
from
...
to
 
Commits (48)

Changes

Showing 13 changed files Side-by-side Diff

... ... @@ -7,7 +7,7 @@
7 7 "# listen_port": "HTTP port untuk mendapat perintah dari CORE",
8 8 "listen_port": 16480,
9 9  
10   - "handler_callback_server": {
  10 + "apiserver": {
11 11 "# listen_port": "HTTP port untuk mendapat pesan masuk dari modem handler",
12 12 "listen_port": 16481,
13 13 "apikey": "PLEASE_CHANGE_ME"
... ... @@ -35,6 +35,19 @@
35 35 "SMS1"
36 36 ],
37 37  
  38 + "senders_imsi": {
  39 + "prefix_names": {
  40 + "TELKOMSEL": [
  41 + ],
  42 + "XL": [
  43 + ]
  44 + },
  45 + "unknown_prefix": [
  46 + ],
  47 + "default": [
  48 + ]
  49 + },
  50 +
38 51 "redis": {
39 52 "host": "127.0.0.1"
40 53 }
... ... @@ -6,8 +6,13 @@ const fs = require('fs');
6 6 fs.writeFileSync('pid.txt', process.pid);
7 7  
8 8 const config = require('komodo-sdk/config');
9   -process.title = `KOMODO-CENTER@${(config && typeof config.name === 'string') ? config.name.toUpperCase() : 'SMS'}`;
10 9  
  10 +global.KOMODO_LOG_LABEL = `KOMODO-CENTER@${(config && typeof config.name === 'string') ? config.name.toUpperCase() : 'SMS'}`;
  11 +process.title = global.KOMODO_LOG_LABEL;
11 12  
  13 +const logger = require('komodo-sdk/logger');
  14 +global.KOMODO_LOGGER = logger;
  15 +
  16 +require('./lib/prefixes');
12 17 require('./lib/transport');
13   -require('./lib/apiserver');
14 18 \ No newline at end of file
  19 +require('./lib/apiserver');
lib/apiserver/index.js
... ... @@ -18,17 +18,23 @@ const partnerLastSeen = require('../partner-last-seen');
18 18 const history = require('../history');
19 19 // const modems = require('../modems2');
20 20  
  21 +const routerConfigSenders = require('./router-config-senders');
21 22 const routerModems = require('./router-modems');
22 23  
  24 +if (config.handler_callback_server) {
  25 + logger.warn('Deprecated config.handler_callback_server. Please migrate it to config.apiserver!');
  26 +}
  27 +
23 28 const app = express();
24 29 messagingService.setTransport(transport);
25 30  
26 31 function apikeyChecker(req, res, next) {
27   - res.locals.has_valid_apikey = req.params.apikey === config.handler_callback_server.apikey;
  32 + res.locals.has_valid_apikey = req.params.apikey === ((config.apiserver && config.apiserver.apikey ? config.apiserver.apikey : null) || config.handler_callback_server.apikey);
28 33 if (res.locals.has_valid_apikey) {
29 34 next();
30 35 }
31 36 else {
  37 + logger.warn('Invalid apikey', { ip: req.ip });
32 38 res.end('APISERVER: Invalid apikey');
33 39 }
34 40 }
... ... @@ -76,10 +82,10 @@ function onIncomingSms(req, res) {
76 82 partner: numberWithSuffix,
77 83 partner_raw: req.query.number,
78 84 msg: req.query.msg,
79   - origin_label: `IMSI_${req.query.modem_imsi || 'UNKNOWN'}`,
  85 + origin_label: req.query.modem_imsi || 'UNKNOWN',
80 86 origin_transport: 'SMS',
81 87 origin_partner: req.query.number,
82   - do_not_forward_to_core: req.query.number.indexOf('+') !== 0,
  88 + do_not_forward_to_core: (req.query.number.indexOf('+62') !== 0) || (req.query.number.length <= 8),
83 89 });
84 90 }
85 91  
... ... @@ -109,8 +115,15 @@ app.get(&#39;/apikey/:apikey/inbox&#39;, onIncomingSms);
109 115 app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms);
110 116 app.get('/apikey/:apikey/history', pageHistory);
111 117 app.use('/apikey/:apikey/modems', routerModems);
  118 +app.use('/apikey/:apikey/config/senders', routerConfigSenders);
  119 +
  120 +const listenPort = (config && config.apiserver && config.apiserver.listen_port ? config.apiserver.listen_port : null)
  121 + || (config && config.handler_callback_server ? config.handler_callback_server.listen_port : null);
112 122  
113   -const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null;
114   -listenPort && app.listen(listenPort, () => {
115   - logger.info('HTTP Handler Callback server listening on port ' + listenPort);
116   -})
117 123 \ No newline at end of file
  124 +if (listenPort) {
  125 + app.listen(listenPort, () => {
  126 + logger.info('HTTP Handler Callback server listening on port ' + listenPort);
  127 + });
  128 +} else {
  129 + logger.warn('Undefined config.apiserver.listen_port for APISERVER. Not listening for command.');
  130 +}
lib/apiserver/router-config-senders.js
... ... @@ -0,0 +1,255 @@
  1 +'use strict';
  2 +
  3 +const fs = require('fs');
  4 +const express = require('express');
  5 +
  6 +const config = require('komodo-sdk/config');
  7 +const logger = require('komodo-sdk/logger');
  8 +
  9 +const locks = require('locks');
  10 +const mutexSave = locks.createMutex();
  11 +
  12 +const router = express.Router();
  13 +module.exports = router;
  14 +
  15 +function saveConfig() {
  16 + return new Promise((resolve) => {
  17 + mutexSave.lock(() => {
  18 + fs.writeFile(global.KOMODO_SDK_CONFIG_FILENAME, JSON.stringify(config, null, 4), (err) => {
  19 + if (err) {
  20 + logger.warn(`APISERVER: ERROR writing config file. ${err.toString()}`);
  21 + }
  22 + mutexSave.unlock();
  23 + resolve();
  24 + });
  25 + });
  26 + });
  27 +}
  28 +
  29 +function initConfig(req, res, next) {
  30 + if (typeof config.senders_imsi !== 'object') {
  31 + config.senders_imsi = {
  32 + prefix_names: {},
  33 + unknown_prefix: [],
  34 + default: [],
  35 + };
  36 + }
  37 +
  38 + if (typeof config.senders_imsi.prefix_names !== 'object') {
  39 + config.senders_imsi.prefix_names = {};
  40 + }
  41 +
  42 + if (!Array.isArray(config.senders_imsi.unknown_prefix)) {
  43 + config.senders_imsi.unknown_prefix = [];
  44 + }
  45 +
  46 + if (!Array.isArray(config.senders_imsi.default)) {
  47 + config.senders_imsi.default = [];
  48 + }
  49 +
  50 + next();
  51 +}
  52 +
  53 +function pageIndex(req, res) {
  54 + res.json(config.senders_imsi);
  55 +}
  56 +
  57 +async function delImsi(data, imsi, cleanup) {
  58 + const idx = data.indexOf(imsi);
  59 + if (idx < 0) return;
  60 +
  61 + data.splice(idx, 1);
  62 +
  63 + if (cleanup) {
  64 + Object.keys(config.senders_imsi.prefix_names).forEach((key) => {
  65 + if (!config.senders_imsi.prefix_names[key]) return;
  66 +
  67 + if (!Array.isArray(config.senders_imsi.prefix_names[key])) return;
  68 +
  69 + if (config.senders_imsi.prefix_names[key].length === 0) {
  70 + delete config.senders_imsi.prefix_names[key];
  71 + }
  72 + });
  73 + }
  74 +
  75 + await saveConfig();
  76 +}
  77 +
  78 +async function addImsi(data, imsi) {
  79 + if (data.indexOf(imsi) >= 0) {
  80 + return false;
  81 + }
  82 +
  83 + data.push(imsi);
  84 + await saveConfig();
  85 +
  86 + return true;
  87 +}
  88 +
  89 +function addImsiResponse(req, res) {
  90 + if (res.locals.add_imsi_success) {
  91 + res.json({
  92 + status: 'OK',
  93 + message: 'IMSI berhasil didaftarkan',
  94 + });
  95 + } else {
  96 + res.json({
  97 + status: 'NOT OK',
  98 + message: 'IMSI sudah terdaftar',
  99 + });
  100 + }
  101 +}
  102 +
  103 +/**
  104 + * Menambahkan IMSI pada list sender by prefix
  105 + *
  106 + * @param {object} req - Express request object
  107 + * @param {object} req.query - query string object
  108 + * @param {string} req.query.prefix - nama prefix
  109 + * @param {string} req.query.imsi - nomor imsi
  110 + * @param {object} res - Express result object
  111 + */
  112 +async function pageAddForPrefix(req, res, next) {
  113 + if (!req.query.prefix) {
  114 + res.json({
  115 + status: 'NOT-OK',
  116 + message: 'Undefined prefix',
  117 + });
  118 +
  119 + return;
  120 + }
  121 +
  122 + if (!req.query.imsi) {
  123 + res.json({
  124 + status: 'NOT-OK',
  125 + message: 'Undefined IMSI',
  126 + });
  127 +
  128 + return;
  129 + }
  130 +
  131 + req.query.prefix = req.query.prefix.toUpperCase();
  132 +
  133 + if (!config.senders_imsi.prefix_names[req.query.prefix]) {
  134 + config.senders_imsi.prefix_names[req.query.prefix] = [];
  135 + }
  136 +
  137 + res.locals.add_imsi_success = await addImsi(config.senders_imsi.prefix_names[req.query.prefix], req.query.imsi);
  138 + next();
  139 +}
  140 +
  141 +async function pageDelForPrefix(req, res) {
  142 + if (!req.query.prefix) {
  143 + res.json({
  144 + status: 'NOT-OK',
  145 + message: 'Undefined prefix',
  146 + });
  147 +
  148 + return;
  149 + }
  150 +
  151 + if (!req.query.imsi) {
  152 + res.json({
  153 + status: 'NOT-OK',
  154 + message: 'Undefined IMSI',
  155 + });
  156 +
  157 + return;
  158 + }
  159 +
  160 + await delImsi(config.senders_imsi.prefix_names[req.query.prefix], req.query.imsi, true);
  161 +
  162 + res.json({
  163 + status: 'OK',
  164 + message: 'IMSI berhasil dihapus',
  165 + });
  166 +}
  167 +
  168 +/**
  169 + * Menambahkan IMSI pada list sender untuk prefix tidak dikenal
  170 + *
  171 + * @param {object} req - Express request object
  172 + * @param {object} req.query - query string object
  173 + * @param {string} req.query.imsi - nomor imsi
  174 + * @param {object} res - Express result object
  175 + */
  176 +async function pageAddForUnknownPrefix(req, res, next) {
  177 + if (!req.query.imsi) {
  178 + res.json({
  179 + status: 'NOT-OK',
  180 + message: 'Undefined IMSI',
  181 + });
  182 +
  183 + return;
  184 + }
  185 +
  186 + res.locals.add_imsi_success = await addImsi(config.senders_imsi.unknown_prefix, req.query.imsi);
  187 + next();
  188 +}
  189 +
  190 +async function pageDelForUnknownPrefix(req, res) {
  191 + if (!req.query.imsi) {
  192 + res.json({
  193 + status: 'NOT-OK',
  194 + message: 'Undefined IMSI',
  195 + });
  196 +
  197 + return;
  198 + }
  199 +
  200 + await delImsi(config.senders_imsi.unknown_prefix, req.query.imsi);
  201 + res.json({
  202 + status: 'OK',
  203 + message: 'IMSI berhasil dihapus',
  204 + });
  205 +}
  206 +
  207 +/**
  208 + * Menambahkan IMSI pada list sender default
  209 + *
  210 + * @param {object} req - Express request object
  211 + * @param {object} req.query - query string object
  212 + * @param {string} req.query.imsi - nomor imsi
  213 + * @param {object} res - Express result object
  214 + */
  215 +async function pageAddForDefault(req, res, next) {
  216 + if (!req.query.imsi) {
  217 + res.json({
  218 + status: 'NOT-OK',
  219 + message: 'Undefined IMSI',
  220 + });
  221 +
  222 + return;
  223 + }
  224 +
  225 + res.locals.add_imsi_success = await addImsi(config.senders_imsi.default, req.query.imsi);
  226 + next();
  227 +}
  228 +
  229 +async function pageDelForDefault(req, res) {
  230 + if (!req.query.imsi) {
  231 + res.json({
  232 + status: 'NOT-OK',
  233 + message: 'Undefined IMSI',
  234 + });
  235 +
  236 + return;
  237 + }
  238 +
  239 + await delImsi(config.senders_imsi.default, req.query.imsi);
  240 + res.json({
  241 + status: 'OK',
  242 + message: 'IMSI berhasil dihapus',
  243 + });
  244 +}
  245 +
  246 +router.use(initConfig);
  247 +router.get('/', initConfig, pageIndex);
  248 +
  249 +router.get('/add-for-prefix', pageAddForPrefix, addImsiResponse);
  250 +router.get('/add-for-unknown-prefix', pageAddForUnknownPrefix, addImsiResponse);
  251 +router.get('/add-for-default', pageAddForDefault, addImsiResponse)
  252 +
  253 +router.get('/del-for-prefix', pageDelForPrefix);
  254 +router.get('/del-for-unknown-prefix', pageDelForUnknownPrefix);
  255 +router.get('/del-for-default', pageDelForDefault);
... ... @@ -0,0 +1,6 @@
  1 +'use strict';
  2 +
  3 +exports.removeSuffixFromNumber = function removeSuffixFromNumber(number, suffix) {
  4 + const re = new RegExp((suffix || '@.*') + '$');
  5 + return number.replace(re, '');
  6 +}
lib/modem-chooser.js
... ... @@ -0,0 +1,68 @@
  1 +'use strict';
  2 +
  3 +const prefixes = require('./prefixes');
  4 +const modems = require('./modems2');
  5 +const partnerLastSeen = require('./partner-last-seen');
  6 +
  7 +function filterOutCandidates(candidates) {
  8 + if (!Array.isArray(candidates)) {
  9 + return [];
  10 + }
  11 +
  12 + if (!candidates.length) return [];
  13 +
  14 + return candidates.filter((item) => {
  15 + if (typeof item !== 'string') return false;
  16 + if (item.indexOf('#') >= 0) return false;
  17 +
  18 + const modem = modems.get('imsi', item);
  19 + if (!modem) return false;
  20 +
  21 + return true;
  22 + });
  23 +}
  24 +
  25 +exports.chooser = async function chooser(destination, config) {
  26 + const logger = global.KOMODO_LOGGER;
  27 +
  28 + let prefixName = await prefixes.lookup(destination);
  29 + if (typeof prefixName === 'string') {
  30 + prefixName = prefixName.toUpperCase();
  31 + }
  32 +
  33 + if (logger) logger.verbose('MODEM-CHOOSER: Choosing suitable senders', { destination, prefixName });
  34 +
  35 + let sendersImsi = [];
  36 + if (config.senders_imsi && prefixName && config.senders_imsi.prefix_names && config.senders_imsi.prefix_names[prefixName]) {
  37 + sendersImsi = filterOutCandidates(config.senders_imsi.prefix_names[prefixName]);
  38 + if (logger) logger.verbose('MODEM-CHOOSER: Try to use imsi senders by prefix name', { destination, prefixName, sendersImsi, candidates: config.senders_imsi.prefix_names[prefixName] });
  39 + }
  40 +
  41 + if (!sendersImsi.length && config.senders_imsi && config.senders_imsi.unknown_prefix) {
  42 + sendersImsi = filterOutCandidates(config.senders_imsi.unknown_prefix);
  43 + if (logger) logger.verbose('MODEM-CHOOSER: Try to use senders for unknown prefix', { destination, prefixName, sendersImsi, candidates: config.senders_imsi.unknown_prefix });
  44 + }
  45 +
  46 + if (!sendersImsi.length) {
  47 + sendersImsi = filterOutCandidates([ await partnerLastSeen.get(destination) ]);
  48 + if (logger) logger.verbose('MODEM-CHOOSER: Try to use sender by last seen', { destination, prefixName, sendersImsi });
  49 + }
  50 +
  51 + if (!sendersImsi.length && config.senders_imsi && config.senders_imsi.default) {
  52 + sendersImsi = filterOutCandidates(config.senders_imsi.default);
  53 + if (logger) logger.verbose('MODEM-CHOOSER: Try to use default senders', { destination, prefixName, sendersImsi, candidates: config.senders_imsi.default });
  54 + }
  55 +
  56 + if (!sendersImsi.length) {
  57 + if (logger) logger.warn('MODEM-CHOOSER: No suitable sender found', { destination, prefixName });
  58 + return;
  59 + }
  60 +
  61 + const count = sendersImsi.length;
  62 + const idx = Math.round(Math.random() * (count - 1));
  63 + const imsiChoosed = sendersImsi[idx];
  64 +
  65 + if (logger) logger.verbose(`MODEM-CHOOSER: gonna use modem with IMSI ${imsiChoosed}`, { destination, prefixName, imsiSenders: sendersImsi });
  66 +
  67 + return imsiChoosed;
  68 +}
0 69 \ No newline at end of file
1 1 'use strict';
2 2  
  3 +const logger = global.KOMODO_LOGGER;
  4 +
  5 +if (logger) {
  6 + logger.verbose('MODEMS: logger set using global logger');
  7 +}
  8 +
3 9 const modemList = {
4 10 by_name: {},
5 11 by_imsi: {},
... ... @@ -46,8 +52,26 @@ function touchByIMSI(val) {
46 52 if (typeof val.imsi !== 'string') return;
47 53 if (!val.imsi.trim()) return;
48 54  
  55 + if (logger && !modemList.by_imsi[val.imsi]) {
  56 + logger.verbose(`New IMSI registration`, {
  57 + imsi: val.imsi,
  58 + name: val.name,
  59 + ip: val.reportIp,
  60 + device: val.device,
  61 + imsi_registered: Object.keys(modemList.by_imsi).length + 1,
  62 + });
  63 + }
  64 +
49 65 const oldName = modemList.by_imsi[val.imsi] ? modemList.by_imsi[val.imsi].name : null;
50 66 if (oldName && oldName !== val.name && modemList.by_name[oldName]) {
  67 + logger.info(`Modem with IMSI ${val.imsi} move detected`, {
  68 + old_name: oldName,
  69 + old_ip: modemList.by_name[oldName].reportIp,
  70 + old_device: modemList.by_name[oldName].device,
  71 + new_name: val.name,
  72 + new_ip: val.reportIp,
  73 + new_device: val.device,
  74 + });
51 75 delete modemList.by_name[oldName];
52 76 }
53 77  
lib/prefixes/index.js
... ... @@ -0,0 +1,41 @@
  1 +'use strict';
  2 +
  3 +const TTL_SECS = 30;
  4 +
  5 +const coreapi = require('komodo-sdk/coreapi');
  6 +const NodeCache = require( "node-cache" );
  7 +
  8 +const cache = new NodeCache({
  9 + stdTTL: TTL_SECS,
  10 +});
  11 +
  12 +async function lookup(number) {
  13 + if (!number) return;
  14 +
  15 + if (cache.get(number)) {
  16 + return cache.get(number);
  17 + }
  18 +
  19 + const [err, lookupResult] = await coreapi({
  20 + path: '/prefixes/lookup',
  21 + method: 'GET',
  22 + qs: {
  23 + number,
  24 + }
  25 + });
  26 +
  27 + if (err || !lookupResult || lookupResult.error) {
  28 + cache.del(number);
  29 + return;
  30 + }
  31 +
  32 + if (lookupResult.prefix) {
  33 + cache.set(number, lookupResult.prefix);
  34 + } else {
  35 + cache.del(number);
  36 + }
  37 +
  38 + return lookupResult.prefix;
  39 +}
  40 +
  41 +exports.lookup = lookup;
1 1 "use strict";
2 2  
  3 +const MAX_SMS_LENGTH = 160;
  4 +
3 5 const url = require('url');
4 6 const request = require('request');
5 7 const uuidv4 = require('uuid/v4');
... ... @@ -10,18 +12,20 @@ const logger = require(&#39;komodo-sdk/logger&#39;);
10 12  
11 13 const messagingService = require('komodo-center-messaging-client-lib');
12 14  
13   -const modemSelect = require('./modemSelect');
  15 +const common = require('./common');
14 16 const modems = require('./modems2');
15   -const partnerLastSeen = require('./partner-last-seen');
  17 +const modemChooser = require('./modem-chooser');
  18 +// const partnerLastSeen = require('./partner-last-seen');
16 19 const history = require('./history');
  20 +const prefixes = require('./prefixes');
17 21  
18 22 function _send(destinationNumber, msg, handlerIMSI) {
19 23  
20 24 if (msg.length > 160) {
21 25 logger.info('Splitting message');
22 26  
23   - const newMsg = msg.slice(0, 160);
24   - const remainingMsg = msg.slice(160);
  27 + const newMsg = msg.slice(0, MAX_SMS_LENGTH);
  28 + const remainingMsg = msg.slice(MAX_SMS_LENGTH);
25 29  
26 30 _send(destinationNumber, newMsg, handlerIMSI);
27 31 setTimeout(() => {
... ... @@ -62,7 +66,7 @@ function _send(destinationNumber, msg, handlerIMSI) {
62 66 partner: destinationNumber,
63 67 partner_raw: `+${destinationNumber}`.replace(/^\++/, '+'),
64 68 msg: msg,
65   - origin_label: `IMSI_${modem.imsi || 'UNKNOWN'}`,
  69 + origin_label: modem.imsi || 'UNKNOWN',
66 70 origin_transport: 'SMS',
67 71 origin_partner: destinationNumber,
68 72 do_not_forward_to_core: true,
... ... @@ -111,10 +115,13 @@ async function send(partner, msg) {
111 115 msg = msg.trim();
112 116 if (!msg) return;
113 117  
114   - const destinationNumber = modemSelect.removeSuffixFromNumber(partner, config);
  118 + const destinationNumber = common.removeSuffixFromNumber(partner, config.number_suffix);
  119 + const prefixName = await prefixes.lookup(destinationNumber);
  120 + logger.verbose('Destination number prefix lookup', {partner: destinationNumber, prefix: prefixName});
115 121  
116 122 // logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin });
117   - const handlerIMSI = await partnerLastSeen.get(destinationNumber) ;
  123 + // const handlerIMSI = await partnerLastSeen.get(destinationNumber) ;
  124 + const handlerIMSI = await modemChooser.chooser(destinationNumber, config);
118 125  
119 126 if (!handlerIMSI) {
120 127 logger.warn(`Unknown handler for sending message to partner`, { partner, destinationNumber });
1 1 {
2 2 "name": "komodo-center-sms",
3   - "version": "0.9.33",
  3 + "version": "0.9.34",
4 4 "lockfileVersion": 1,
5 5 "requires": true,
6 6 "dependencies": {
... ... @@ -186,9 +186,12 @@
186 186 "dev": true
187 187 },
188 188 "async": {
189   - "version": "1.0.0",
190   - "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
191   - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
  189 + "version": "2.6.3",
  190 + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
  191 + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
  192 + "requires": {
  193 + "lodash": "^4.17.14"
  194 + }
192 195 },
193 196 "async-each": {
194 197 "version": "1.0.3",
... ... @@ -449,9 +452,9 @@
449 452 "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
450 453 },
451 454 "chokidar": {
452   - "version": "2.1.6",
453   - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
454   - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==",
  455 + "version": "2.1.8",
  456 + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
  457 + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
455 458 "optional": true,
456 459 "requires": {
457 460 "anymatch": "^2.0.0",
... ... @@ -521,6 +524,11 @@
521 524 "wrap-ansi": "^2.0.0"
522 525 }
523 526 },
  527 + "clone": {
  528 + "version": "2.1.2",
  529 + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
  530 + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
  531 + },
524 532 "code-point-at": {
525 533 "version": "1.1.0",
526 534 "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
... ... @@ -536,11 +544,19 @@
536 544 "object-visit": "^1.0.0"
537 545 }
538 546 },
  547 + "color": {
  548 + "version": "3.0.0",
  549 + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
  550 + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
  551 + "requires": {
  552 + "color-convert": "^1.9.1",
  553 + "color-string": "^1.5.2"
  554 + }
  555 + },
539 556 "color-convert": {
540 557 "version": "1.9.3",
541 558 "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
542 559 "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
543   - "dev": true,
544 560 "requires": {
545 561 "color-name": "1.1.3"
546 562 }
... ... @@ -548,13 +564,35 @@
548 564 "color-name": {
549 565 "version": "1.1.3",
550 566 "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
551   - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
552   - "dev": true
  567 + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
  568 + },
  569 + "color-string": {
  570 + "version": "1.5.3",
  571 + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
  572 + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
  573 + "requires": {
  574 + "color-name": "^1.0.0",
  575 + "simple-swizzle": "^0.2.2"
  576 + }
  577 + },
  578 + "colornames": {
  579 + "version": "1.1.1",
  580 + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
  581 + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y="
553 582 },
554 583 "colors": {
555   - "version": "1.0.3",
556   - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
557   - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
  584 + "version": "1.3.3",
  585 + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
  586 + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="
  587 + },
  588 + "colorspace": {
  589 + "version": "1.1.2",
  590 + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz",
  591 + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==",
  592 + "requires": {
  593 + "color": "3.0.x",
  594 + "text-hex": "1.0.x"
  595 + }
558 596 },
559 597 "combined-stream": {
560 598 "version": "1.0.8",
... ... @@ -740,6 +778,16 @@
740 778 "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
741 779 "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
742 780 },
  781 + "diagnostics": {
  782 + "version": "1.1.1",
  783 + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
  784 + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
  785 + "requires": {
  786 + "colorspace": "1.1.x",
  787 + "enabled": "1.0.x",
  788 + "kuler": "1.0.x"
  789 + }
  790 + },
743 791 "diff": {
744 792 "version": "3.5.0",
745 793 "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
... ... @@ -789,6 +837,14 @@
789 837 "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
790 838 "dev": true
791 839 },
  840 + "enabled": {
  841 + "version": "1.0.2",
  842 + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
  843 + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
  844 + "requires": {
  845 + "env-variable": "0.0.x"
  846 + }
  847 + },
792 848 "encodeurl": {
793 849 "version": "1.0.2",
794 850 "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
... ... @@ -803,6 +859,11 @@
803 859 "once": "^1.4.0"
804 860 }
805 861 },
  862 + "env-variable": {
  863 + "version": "0.0.5",
  864 + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz",
  865 + "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA=="
  866 + },
806 867 "es-abstract": {
807 868 "version": "1.13.0",
808 869 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
... ... @@ -829,9 +890,9 @@
829 890 }
830 891 },
831 892 "es6-promisify": {
832   - "version": "6.0.1",
833   - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.1.tgz",
834   - "integrity": "sha512-J3ZkwbEnnO+fGAKrjVpeUAnZshAdfZvbhQpqfIH9kSAspReRC4nJnu8ewm55b4y9ElyeuhCTzJD0XiH8Tsbhlw=="
  893 + "version": "6.0.2",
  894 + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.2.tgz",
  895 + "integrity": "sha512-eO6vFm0JvqGzjWIQA6QVKjxpmELfhWbDUWHm1rPfIbn55mhKPiAa5xpLmQWJrNa629ZIeQ8ZvMAi13kvrjK6Mg=="
835 896 },
836 897 "escape-html": {
837 898 "version": "1.0.3",
... ... @@ -1240,11 +1301,6 @@
1240 1301 "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
1241 1302 "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
1242 1303 },
1243   - "eyes": {
1244   - "version": "0.1.8",
1245   - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
1246   - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A="
1247   - },
1248 1304 "fast-deep-equal": {
1249 1305 "version": "2.0.1",
1250 1306 "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
... ... @@ -1261,6 +1317,16 @@
1261 1317 "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
1262 1318 "dev": true
1263 1319 },
  1320 + "fast-safe-stringify": {
  1321 + "version": "2.0.6",
  1322 + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
  1323 + "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg=="
  1324 + },
  1325 + "fecha": {
  1326 + "version": "2.3.3",
  1327 + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
  1328 + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
  1329 + },
1264 1330 "figures": {
1265 1331 "version": "2.0.0",
1266 1332 "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
... ... @@ -1279,6 +1345,14 @@
1279 1345 "flat-cache": "^2.0.1"
1280 1346 }
1281 1347 },
  1348 + "file-stream-rotator": {
  1349 + "version": "0.4.1",
  1350 + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.4.1.tgz",
  1351 + "integrity": "sha512-W3aa3QJEc8BS2MmdVpQiYLKHj3ijpto1gMDlsgCRSKfIUe6MwkcpODGPQ3vZfb0XvCeCqlu9CBQTN7oQri2TZQ==",
  1352 + "requires": {
  1353 + "moment": "^2.11.2"
  1354 + }
  1355 + },
1282 1356 "fill-range": {
1283 1357 "version": "4.0.0",
1284 1358 "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
... ... @@ -1974,9 +2048,9 @@
1974 2048 "dev": true
1975 2049 },
1976 2050 "graceful-fs": {
1977   - "version": "4.2.1",
1978   - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz",
1979   - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==",
  2051 + "version": "4.2.2",
  2052 + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
  2053 + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
1980 2054 "optional": true
1981 2055 },
1982 2056 "growl": {
... ... @@ -2227,6 +2301,11 @@
2227 2301 }
2228 2302 }
2229 2303 },
  2304 + "is-arrayish": {
  2305 + "version": "0.3.2",
  2306 + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
  2307 + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
  2308 + },
2230 2309 "is-binary-path": {
2231 2310 "version": "1.0.1",
2232 2311 "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
... ... @@ -2364,8 +2443,7 @@
2364 2443 "is-stream": {
2365 2444 "version": "1.1.0",
2366 2445 "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
2367   - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
2368   - "dev": true
  2446 + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
2369 2447 },
2370 2448 "is-symbol": {
2371 2449 "version": "1.0.2",
... ... @@ -2390,8 +2468,7 @@
2390 2468 "isarray": {
2391 2469 "version": "1.0.0",
2392 2470 "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
2393   - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
2394   - "optional": true
  2471 + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
2395 2472 },
2396 2473 "isexe": {
2397 2474 "version": "2.0.0",
... ... @@ -2474,7 +2551,7 @@
2474 2551 "optional": true
2475 2552 },
2476 2553 "komodo-center-messaging-client-lib": {
2477   - "version": "git+http://gitlab.kodesumber.com/komodo/komodo-center-messaging-client-lib.git#6b88a25da5a145256e0192753b4c66814142e2ed",
  2554 + "version": "git+http://gitlab.kodesumber.com/komodo/komodo-center-messaging-client-lib.git#28ac01965f46daf67c36d7a00442934907c849ef",
2478 2555 "from": "git+http://gitlab.kodesumber.com/komodo/komodo-center-messaging-client-lib.git",
2479 2556 "requires": {
2480 2557 "body-parser": "^1.19.0",
... ... @@ -2485,7 +2562,7 @@
2485 2562 }
2486 2563 },
2487 2564 "komodo-sdk": {
2488   - "version": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git#ebacf060c6a191b7dbee88cebbada66080c351da",
  2565 + "version": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git#9240032d855627985eb4044d156f2e377ce72744",
2489 2566 "from": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git",
2490 2567 "requires": {
2491 2568 "array-unique": "^0.3.2",
... ... @@ -2513,9 +2590,17 @@
2513 2590 "string-natural-compare": "^2.0.2",
2514 2591 "uniqid": "^4.1.1",
2515 2592 "uuid": "^3.1.0",
2516   - "winston": "^2.3.1",
  2593 + "winston": "^3.2.1",
2517 2594 "winston-circular-buffer": "^1.0.0",
2518   - "winston-daily-rotate-file": "^1.4.6"
  2595 + "winston-daily-rotate-file": "^3.10.0"
  2596 + }
  2597 + },
  2598 + "kuler": {
  2599 + "version": "1.0.1",
  2600 + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
  2601 + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
  2602 + "requires": {
  2603 + "colornames": "^1.1.1"
2519 2604 }
2520 2605 },
2521 2606 "lcid": {
... ... @@ -2546,11 +2631,15 @@
2546 2631 "path-exists": "^3.0.0"
2547 2632 }
2548 2633 },
  2634 + "locks": {
  2635 + "version": "0.2.2",
  2636 + "resolved": "https://registry.npmjs.org/locks/-/locks-0.2.2.tgz",
  2637 + "integrity": "sha1-JZkz0TJ8uvD9NmL4//3jaAnYTO0="
  2638 + },
2549 2639 "lodash": {
2550 2640 "version": "4.17.15",
2551 2641 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
2552   - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
2553   - "dev": true
  2642 + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
2554 2643 },
2555 2644 "log-symbols": {
2556 2645 "version": "2.2.0",
... ... @@ -2561,6 +2650,25 @@
2561 2650 "chalk": "^2.0.1"
2562 2651 }
2563 2652 },
  2653 + "logform": {
  2654 + "version": "2.1.2",
  2655 + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz",
  2656 + "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==",
  2657 + "requires": {
  2658 + "colors": "^1.2.1",
  2659 + "fast-safe-stringify": "^2.0.4",
  2660 + "fecha": "^2.3.3",
  2661 + "ms": "^2.1.1",
  2662 + "triple-beam": "^1.3.0"
  2663 + },
  2664 + "dependencies": {
  2665 + "ms": {
  2666 + "version": "2.1.2",
  2667 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
  2668 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
  2669 + }
  2670 + }
  2671 + },
2564 2672 "lru-cache": {
2565 2673 "version": "4.1.5",
2566 2674 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
... ... @@ -2681,7 +2789,8 @@
2681 2789 "minimist": {
2682 2790 "version": "0.0.8",
2683 2791 "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
2684   - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
  2792 + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
  2793 + "dev": true
2685 2794 },
2686 2795 "mixin-deep": {
2687 2796 "version": "1.3.2",
... ... @@ -2708,6 +2817,7 @@
2708 2817 "version": "0.5.1",
2709 2818 "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
2710 2819 "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
  2820 + "dev": true,
2711 2821 "requires": {
2712 2822 "minimist": "0.0.8"
2713 2823 }
... ... @@ -2955,6 +3065,15 @@
2955 3065 "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
2956 3066 "dev": true
2957 3067 },
  3068 + "node-cache": {
  3069 + "version": "4.2.1",
  3070 + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.1.tgz",
  3071 + "integrity": "sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==",
  3072 + "requires": {
  3073 + "clone": "2.x",
  3074 + "lodash": "^4.17.15"
  3075 + }
  3076 + },
2958 3077 "node-environment-flags": {
2959 3078 "version": "1.0.5",
2960 3079 "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
... ... @@ -3047,6 +3166,11 @@
3047 3166 }
3048 3167 }
3049 3168 },
  3169 + "object-hash": {
  3170 + "version": "1.3.1",
  3171 + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
  3172 + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA=="
  3173 + },
3050 3174 "object-keys": {
3051 3175 "version": "1.1.1",
3052 3176 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
... ... @@ -3114,6 +3238,11 @@
3114 3238 "wrappy": "1"
3115 3239 }
3116 3240 },
  3241 + "one-time": {
  3242 + "version": "0.0.4",
  3243 + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
  3244 + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
  3245 + },
3117 3246 "onetime": {
3118 3247 "version": "2.0.1",
3119 3248 "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
... ... @@ -3279,8 +3408,7 @@
3279 3408 "process-nextick-args": {
3280 3409 "version": "2.0.1",
3281 3410 "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
3282   - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
3283   - "optional": true
  3411 + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
3284 3412 },
3285 3413 "progress": {
3286 3414 "version": "2.0.3",
... ... @@ -3352,7 +3480,6 @@
3352 3480 "version": "2.3.6",
3353 3481 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
3354 3482 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
3355   - "optional": true,
3356 3483 "requires": {
3357 3484 "core-util-is": "~1.0.0",
3358 3485 "inherits": "~2.0.3",
... ... @@ -3733,6 +3860,14 @@
3733 3860 }
3734 3861 }
3735 3862 },
  3863 + "simple-swizzle": {
  3864 + "version": "0.2.2",
  3865 + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
  3866 + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
  3867 + "requires": {
  3868 + "is-arrayish": "^0.3.1"
  3869 + }
  3870 + },
3736 3871 "slice-ansi": {
3737 3872 "version": "2.1.0",
3738 3873 "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
... ... @@ -4025,7 +4160,6 @@
4025 4160 "version": "1.1.1",
4026 4161 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
4027 4162 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
4028   - "optional": true,
4029 4163 "requires": {
4030 4164 "safe-buffer": "~5.1.0"
4031 4165 }
... ... @@ -4105,6 +4239,11 @@
4105 4239 }
4106 4240 }
4107 4241 },
  4242 + "text-hex": {
  4243 + "version": "1.0.0",
  4244 + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
  4245 + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
  4246 + },
4108 4247 "text-table": {
4109 4248 "version": "0.2.0",
4110 4249 "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
... ... @@ -4187,6 +4326,11 @@
4187 4326 }
4188 4327 }
4189 4328 },
  4329 + "triple-beam": {
  4330 + "version": "1.3.0",
  4331 + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
  4332 + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
  4333 + },
4190 4334 "tslib": {
4191 4335 "version": "1.10.0",
4192 4336 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
... ... @@ -4339,8 +4483,7 @@
4339 4483 "util-deprecate": {
4340 4484 "version": "1.0.2",
4341 4485 "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
4342   - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
4343   - "optional": true
  4486 + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
4344 4487 },
4345 4488 "utils-merge": {
4346 4489 "version": "1.0.1",
... ... @@ -4403,16 +4546,31 @@
4403 4546 "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
4404 4547 },
4405 4548 "winston": {
4406   - "version": "2.4.4",
4407   - "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz",
4408   - "integrity": "sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q==",
  4549 + "version": "3.2.1",
  4550 + "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz",
  4551 + "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==",
4409 4552 "requires": {
4410   - "async": "~1.0.0",
4411   - "colors": "1.0.x",
4412   - "cycle": "1.0.x",
4413   - "eyes": "0.1.x",
4414   - "isstream": "0.1.x",
4415   - "stack-trace": "0.0.x"
  4553 + "async": "^2.6.1",
  4554 + "diagnostics": "^1.1.1",
  4555 + "is-stream": "^1.1.0",
  4556 + "logform": "^2.1.1",
  4557 + "one-time": "0.0.4",
  4558 + "readable-stream": "^3.1.1",
  4559 + "stack-trace": "0.0.x",
  4560 + "triple-beam": "^1.3.0",
  4561 + "winston-transport": "^4.3.0"
  4562 + },
  4563 + "dependencies": {
  4564 + "readable-stream": {
  4565 + "version": "3.4.0",
  4566 + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
  4567 + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
  4568 + "requires": {
  4569 + "inherits": "^2.0.3",
  4570 + "string_decoder": "^1.1.1",
  4571 + "util-deprecate": "^1.0.1"
  4572 + }
  4573 + }
4416 4574 }
4417 4575 },
4418 4576 "winston-circular-buffer": {
... ... @@ -4423,12 +4581,62 @@
4423 4581 "circular-buffer": "0.0.6"
4424 4582 }
4425 4583 },
  4584 + "winston-compat": {
  4585 + "version": "0.1.4",
  4586 + "resolved": "https://registry.npmjs.org/winston-compat/-/winston-compat-0.1.4.tgz",
  4587 + "integrity": "sha512-mMEfFsSm6GmkFF+f4/0UJtG4N1vSaczGmXLVJYmS/+u2zUaIPcw2ZRuwUg2TvVBjswgiraN+vNnAG8z4fRUZ4w==",
  4588 + "requires": {
  4589 + "cycle": "~1.0.3",
  4590 + "logform": "^1.6.0",
  4591 + "triple-beam": "^1.2.0"
  4592 + },
  4593 + "dependencies": {
  4594 + "logform": {
  4595 + "version": "1.10.0",
  4596 + "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz",
  4597 + "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==",
  4598 + "requires": {
  4599 + "colors": "^1.2.1",
  4600 + "fast-safe-stringify": "^2.0.4",
  4601 + "fecha": "^2.3.3",
  4602 + "ms": "^2.1.1",
  4603 + "triple-beam": "^1.2.0"
  4604 + }
  4605 + },
  4606 + "ms": {
  4607 + "version": "2.1.2",
  4608 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
  4609 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
  4610 + }
  4611 + }
  4612 + },
4426 4613 "winston-daily-rotate-file": {
4427   - "version": "1.7.2",
4428   - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-1.7.2.tgz",
4429   - "integrity": "sha1-ZQK/opeCT9mC2l5WR8dThXjS+aA=",
  4614 + "version": "3.10.0",
  4615 + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-3.10.0.tgz",
  4616 + "integrity": "sha512-KO8CfbI2CvdR3PaFApEH02GPXiwJ+vbkF1mCkTlvRIoXFI8EFlf1ACcuaahXTEiDEKCii6cNe95gsL4ZkbnphA==",
  4617 + "requires": {
  4618 + "file-stream-rotator": "^0.4.1",
  4619 + "object-hash": "^1.3.0",
  4620 + "semver": "^6.2.0",
  4621 + "triple-beam": "^1.3.0",
  4622 + "winston-compat": "^0.1.4",
  4623 + "winston-transport": "^4.2.0"
  4624 + },
  4625 + "dependencies": {
  4626 + "semver": {
  4627 + "version": "6.3.0",
  4628 + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
  4629 + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
  4630 + }
  4631 + }
  4632 + },
  4633 + "winston-transport": {
  4634 + "version": "4.3.0",
  4635 + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
  4636 + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
4430 4637 "requires": {
4431   - "mkdirp": "0.5.1"
  4638 + "readable-stream": "^2.3.6",
  4639 + "triple-beam": "^1.2.0"
4432 4640 }
4433 4641 },
4434 4642 "wordwrap": {
1 1 {
2 2 "name": "komodo-center-sms",
3   - "version": "0.9.33",
  3 + "version": "0.9.34",
4 4 "description": "SMS center for Komodo",
5 5 "main": "index.js",
6 6 "scripts": {
... ... @@ -23,7 +23,9 @@
23 23 "express": "^4.17.1",
24 24 "komodo-center-messaging-client-lib": "git+http://gitlab.kodesumber.com/komodo/komodo-center-messaging-client-lib.git",
25 25 "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git",
  26 + "locks": "^0.2.2",
26 27 "moment": "^2.24.0",
  28 + "node-cache": "^4.2.1",
27 29 "redis": "^2.8.0",
28 30 "request": "^2.88.0",
29 31 "uuid": "^3.3.2"
... ... @@ -0,0 +1,33 @@
  1 +'use strict';
  2 +
  3 +/* global describe it */
  4 +
  5 +global.KOMODO_SDK_NO_LOG_ON_COREAPI = true;
  6 +
  7 +const should = require('should');
  8 +const prefixes = require('../lib/prefixes');
  9 +
  10 +describe('#prefixes', () => {
  11 + describe('#lookup', () => {
  12 + it('should return correct prefix', async () => {
  13 + const lookupResult = await prefixes.lookup('08180000000');
  14 + lookupResult.should.equal('XL');
  15 + });
  16 +
  17 + it('should handle unknown prefix', async () => {
  18 + should.not.exist(await prefixes.lookup());
  19 + should.not.exist(await prefixes.lookup(''));
  20 + should.not.exist(await prefixes.lookup('9'));
  21 + });
  22 +
  23 + it('should handle cache result', async () => {
  24 + const lookupResult = await prefixes.lookup('08180000000');
  25 + await prefixes.lookup('08180000000');
  26 + await prefixes.lookup('08180000000');
  27 + await prefixes.lookup('08180000000');
  28 + await prefixes.lookup('08180000000');
  29 + await prefixes.lookup('08180000000');
  30 + lookupResult.should.equal('XL');
  31 + });
  32 + });
  33 +});
0 34 \ No newline at end of file