@slingr/slingr-services 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +373 -0
- package/index.js +432 -0
- package/package.json +32 -0
- package/services/application/application.js +49 -0
- package/services/configuration/configuration.js +171 -0
- package/services/dataStores/dataStores.js +93 -0
- package/services/events/events.js +69 -0
- package/services/files/files.js +114 -0
- package/services/httpModule/httpModule.js +31 -0
- package/services/locks/locks.js +37 -0
- package/services/loggers/appLogs.js +42 -0
- package/services/loggers/logs.js +68 -0
- package/services/settings/settings.js +26 -0
- package/services/users/users.js +112 -0
package/index.js
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
//////////////////
|
|
2
|
+
// Dependencies //
|
|
3
|
+
//////////////////
|
|
4
|
+
//We load env vars from dotenv if we are in local deployment
|
|
5
|
+
//The file loaded will depend on the NODE_ENV var.If not defined, it dafaults to .env
|
|
6
|
+
if (process.env._local_deployment === undefined) {
|
|
7
|
+
let envPath = process.env.NODE_ENV === undefined ? './.env' : `./.${process.env.NODE_ENV}.env`;
|
|
8
|
+
require('dotenv').config({ path: envPath});
|
|
9
|
+
}
|
|
10
|
+
const
|
|
11
|
+
util = require('util'),
|
|
12
|
+
fs = require('fs'),
|
|
13
|
+
http = require('http'),
|
|
14
|
+
https = require('https'),
|
|
15
|
+
axios = require('axios'),
|
|
16
|
+
compression = require('compression'),
|
|
17
|
+
express = require('express'),
|
|
18
|
+
bodyParser = require('body-parser');
|
|
19
|
+
|
|
20
|
+
//The instance of the service.
|
|
21
|
+
let svc = {
|
|
22
|
+
settings: null,
|
|
23
|
+
hooks: {
|
|
24
|
+
onSvcServicesConfigured: null,
|
|
25
|
+
onConfigurationReady: null,
|
|
26
|
+
onWebServicesReady: null,
|
|
27
|
+
onSvcStart: null,
|
|
28
|
+
onSvcStop: null
|
|
29
|
+
},
|
|
30
|
+
functions: {},
|
|
31
|
+
webServices: {},
|
|
32
|
+
dataStores: null,
|
|
33
|
+
logger: null,
|
|
34
|
+
appLogger: null,
|
|
35
|
+
events: null,
|
|
36
|
+
files: null,
|
|
37
|
+
users: null,
|
|
38
|
+
application: null,
|
|
39
|
+
locks: null,
|
|
40
|
+
httpModule: {}
|
|
41
|
+
};
|
|
42
|
+
let settings,
|
|
43
|
+
serviceConfig,
|
|
44
|
+
definitions,
|
|
45
|
+
logger,
|
|
46
|
+
appLogger,
|
|
47
|
+
events,
|
|
48
|
+
files,
|
|
49
|
+
dataStores,
|
|
50
|
+
users,
|
|
51
|
+
application,
|
|
52
|
+
locks,
|
|
53
|
+
httpModule;
|
|
54
|
+
|
|
55
|
+
///////////////////////
|
|
56
|
+
// Svc Services //
|
|
57
|
+
///////////////////////
|
|
58
|
+
const loadSvcServices = async () => {
|
|
59
|
+
logger = require('./services/loggers/logs');
|
|
60
|
+
appLogger = require('./services/loggers/appLogs');
|
|
61
|
+
events = require('./services/events/events');
|
|
62
|
+
files = require('./services/files/files');
|
|
63
|
+
dataStores = require('./services/dataStores/dataStores');
|
|
64
|
+
users = require('./services/users/users');
|
|
65
|
+
application = require('./services/application/application');
|
|
66
|
+
locks = require('./services/locks/locks');
|
|
67
|
+
|
|
68
|
+
httpModule = require('./services/httpModule/httpModule');
|
|
69
|
+
|
|
70
|
+
settings.isUsingProxy = await require('./services/settings/settings').checkProxyStatus();
|
|
71
|
+
|
|
72
|
+
svc.logger = logger;
|
|
73
|
+
svc.appLogger = appLogger;
|
|
74
|
+
svc.events = events;
|
|
75
|
+
svc.files = files;
|
|
76
|
+
svc.dataStores = dataStores;
|
|
77
|
+
svc.users = users;
|
|
78
|
+
svc.application = application;
|
|
79
|
+
svc.locks = locks;
|
|
80
|
+
svc.httpModule = axios;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const convertException = (err, code) => {
|
|
84
|
+
if (!err) {
|
|
85
|
+
return {
|
|
86
|
+
__svc_exception__: true,
|
|
87
|
+
message: 'There is an issue on the service',
|
|
88
|
+
error: !code ? { code: 'general', name: 'General exception' } : code
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
if (typeof err === 'string') {
|
|
92
|
+
return {
|
|
93
|
+
__svc_exception__: true,
|
|
94
|
+
message: err,
|
|
95
|
+
error: !code ? { code: 'general', name: 'General exception' } : code
|
|
96
|
+
}
|
|
97
|
+
} else if (err.__svc_exception__) {
|
|
98
|
+
return err
|
|
99
|
+
} else if (err.message) {
|
|
100
|
+
return {
|
|
101
|
+
__svc_exception__: true,
|
|
102
|
+
message: err.message,
|
|
103
|
+
additionalInfo: err,
|
|
104
|
+
error: !code ? { code: 'general', name: 'General exception' } : code
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
return {
|
|
108
|
+
__svc_exception__: true,
|
|
109
|
+
message: 'There is an issue on the service',
|
|
110
|
+
additionalInfo: err,
|
|
111
|
+
error: !code ? { code: 'general', name: 'General exception' } : code
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
118
|
+
// HTTP service: Service API & Webhooks set-up
|
|
119
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
120
|
+
const webServicesServer = express(),
|
|
121
|
+
apiRouter = express.Router(),
|
|
122
|
+
webhookRouter = express.Router();
|
|
123
|
+
|
|
124
|
+
const loadPlatformWebServices = () => {
|
|
125
|
+
let firstLocalDeploymentWarning = false;
|
|
126
|
+
// process functions
|
|
127
|
+
apiRouter.get('/configuration', (req, res) => {
|
|
128
|
+
logger.info("Configuration request");
|
|
129
|
+
let validToken = false;
|
|
130
|
+
if (settings.token === req?.headers?.token) {
|
|
131
|
+
validToken = true
|
|
132
|
+
}
|
|
133
|
+
if (!validToken && localDeployment) {
|
|
134
|
+
// if the service is running in local environment, pass token validation
|
|
135
|
+
if (!firstLocalDeploymentWarning) {
|
|
136
|
+
firstLocalDeploymentWarning = true;
|
|
137
|
+
logger.info("Invalid or empty token on request. Ignored exceptions of this kind because the service is running in local deployment.");
|
|
138
|
+
}
|
|
139
|
+
validToken = true
|
|
140
|
+
}
|
|
141
|
+
let response = null;
|
|
142
|
+
if (validToken) {
|
|
143
|
+
try {
|
|
144
|
+
response = {
|
|
145
|
+
app: settings.applicationName,
|
|
146
|
+
name: settings.svcName,
|
|
147
|
+
env: settings.environment,
|
|
148
|
+
perUser: definitions.configurationType === 'PER_USER',
|
|
149
|
+
configuration: {
|
|
150
|
+
_svc_name: settings.svcName,
|
|
151
|
+
_app_name: settings.applicationName,
|
|
152
|
+
_pod_id: settings.podId,
|
|
153
|
+
_environment: settings.environment,
|
|
154
|
+
_local_deployment: settings.localDeployment,
|
|
155
|
+
_custom_domain: settings.domainCustom,
|
|
156
|
+
_base_domain: settings.domainBase,
|
|
157
|
+
_webservices_port: settings.webServicesPort,
|
|
158
|
+
_debug: settings.debug,
|
|
159
|
+
_token: '-',
|
|
160
|
+
_profile: settings.profile,
|
|
161
|
+
_svcs_services_api: settings.svcsServicesApi,
|
|
162
|
+
_service_config: settings.serviceConfig
|
|
163
|
+
},
|
|
164
|
+
js: '',
|
|
165
|
+
listeners: '',
|
|
166
|
+
functions: [],
|
|
167
|
+
events: []
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
if (!!definitions.configurationHelpUrl) {
|
|
171
|
+
response.configurationHelpUrl = definitions.configurationHelpUrl;
|
|
172
|
+
}
|
|
173
|
+
if (!!definitions.functions) {
|
|
174
|
+
response.functions = definitions.functions;
|
|
175
|
+
}
|
|
176
|
+
if (!!definitions.events) {
|
|
177
|
+
response.events = definitions.events;
|
|
178
|
+
}
|
|
179
|
+
if (!!definitions.configuration) {
|
|
180
|
+
response.conf = definitions.configuration;
|
|
181
|
+
}
|
|
182
|
+
if (!!definitions.userConfiguration) {
|
|
183
|
+
response.userConf = definitions.userConfiguration;
|
|
184
|
+
}
|
|
185
|
+
if (!!definitions.userConfigurationButtons) {
|
|
186
|
+
response.userConfButtons = definitions.userConfigurationButtons;
|
|
187
|
+
}
|
|
188
|
+
if (!!definitions.listeners) {
|
|
189
|
+
let listeners = '';
|
|
190
|
+
for (let i in definitions.listeners) {
|
|
191
|
+
try {
|
|
192
|
+
let fileContent = fs.readFileSync('./listeners/' + definitions.listeners[i], 'utf8');
|
|
193
|
+
if (fileContent) {
|
|
194
|
+
listeners += '\n/* */\n';
|
|
195
|
+
listeners += fileContent;
|
|
196
|
+
listeners += '\n/* */\n';
|
|
197
|
+
}
|
|
198
|
+
} catch (err) {
|
|
199
|
+
logger.warn('Listeners file [' + definitions.listeners[i] + '] can not be read: ' + convertException(err));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
response.listeners = listeners;
|
|
203
|
+
}
|
|
204
|
+
} catch (err) {
|
|
205
|
+
if (err && err.message) {
|
|
206
|
+
response = convertException(err.message)
|
|
207
|
+
} else {
|
|
208
|
+
err = util.inspect(err, { showHidden: true, depth: null });
|
|
209
|
+
if (err && err.startsWith("'") && err.endsWith("'")) {
|
|
210
|
+
err = err.substring(1, err.length - 1);
|
|
211
|
+
}
|
|
212
|
+
response = convertException(err)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (!response) {
|
|
216
|
+
response = convertException("Empty service response")
|
|
217
|
+
}
|
|
218
|
+
logger.info("Configuration response from service");
|
|
219
|
+
res.send(response);
|
|
220
|
+
} else {
|
|
221
|
+
logger.info("Invalid token when try to get configuration");
|
|
222
|
+
res.status(401).send('Invalid token')
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
//add await on function if async
|
|
226
|
+
apiRouter.post('/function', async (req, res, next) => {
|
|
227
|
+
|
|
228
|
+
firstLocalDeploymentWarning = false;
|
|
229
|
+
let validToken = false;
|
|
230
|
+
if (req?.headers?.token === settings.token) {
|
|
231
|
+
validToken = true
|
|
232
|
+
}
|
|
233
|
+
if (!validToken && settings.localDeployment) {
|
|
234
|
+
// if the service is running in local environment, pass token validation
|
|
235
|
+
if (!firstLocalDeploymentWarning) {
|
|
236
|
+
firstLocalDeploymentWarning = true;
|
|
237
|
+
logger.warn("Invalid or empty token on request. Ignored exceptions of this kind because the service is running in local deployment.");
|
|
238
|
+
}
|
|
239
|
+
validToken = true
|
|
240
|
+
}
|
|
241
|
+
let response = null;
|
|
242
|
+
let responseCode = 200;
|
|
243
|
+
if (!validToken) {
|
|
244
|
+
logger.info("Invalid token when try to get configuration");
|
|
245
|
+
res.status(401).send('Invalid token')
|
|
246
|
+
} else {
|
|
247
|
+
let body = req.body || {};
|
|
248
|
+
let functionName = body.function;
|
|
249
|
+
|
|
250
|
+
if (!functionName) {
|
|
251
|
+
response = convertException('Empty function name', { code: 'argumentException', name: 'Argument invalid' });
|
|
252
|
+
responseCode = 404;
|
|
253
|
+
} else {
|
|
254
|
+
if (svc.functions[functionName]) {
|
|
255
|
+
try {
|
|
256
|
+
if (body.params?.__request_params__) body.params = body.params.__request_params__;
|
|
257
|
+
response = await svc.functions[functionName](body);
|
|
258
|
+
} catch (err) {
|
|
259
|
+
if (!!err && !!err.message) {
|
|
260
|
+
if (!!err.__svc_exception__) {
|
|
261
|
+
response = convertException(err)
|
|
262
|
+
} else {
|
|
263
|
+
response = convertException(err.message)
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
err = util.inspect(err, { showHidden: true, depth: null });
|
|
267
|
+
if (!!err && err.startsWith("'") && err.endsWith("'")) {
|
|
268
|
+
err = err.substring(1, err.length - 1);
|
|
269
|
+
}
|
|
270
|
+
response = convertException(err);
|
|
271
|
+
}
|
|
272
|
+
responseCode = 500;
|
|
273
|
+
}
|
|
274
|
+
if (!response) {
|
|
275
|
+
response = convertException("Empty service response");
|
|
276
|
+
responseCode = 400;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
res.status(responseCode).send({
|
|
280
|
+
date: +new Date(),
|
|
281
|
+
data: response
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
} else {
|
|
285
|
+
next(new Error('Cannot find function [' + functionName + '] on service [' + svcName + ']'));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
apiRouter.get('/system/alive', (req, res) => {
|
|
293
|
+
validToken = false;
|
|
294
|
+
if (req?.headers?.token === settings.token) {
|
|
295
|
+
validToken = true;
|
|
296
|
+
}
|
|
297
|
+
if (!validToken && settings.localDeployment) {
|
|
298
|
+
// if the service is running in local environment, pass token validation
|
|
299
|
+
if (!firstLocalDeploymentWarning) {
|
|
300
|
+
firstLocalDeploymentWarning = true;
|
|
301
|
+
logger.warn("Invalid or empty token on request. Ignored exceptions of this kind because the service is running in local deployment.");
|
|
302
|
+
}
|
|
303
|
+
validToken = true;
|
|
304
|
+
}
|
|
305
|
+
if (!validToken) {
|
|
306
|
+
logger.info("Invalid token when try to check health");
|
|
307
|
+
res.status(401).send('Invalid token');
|
|
308
|
+
} else {
|
|
309
|
+
res.send({ started: true });
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const loadDeveloperWebServices = () => {
|
|
315
|
+
|
|
316
|
+
for (const webService in svc.webServices) {
|
|
317
|
+
if (svc.webServices.hasOwnProperty(webService)) {
|
|
318
|
+
let currentWebService = svc.webServices[webService]
|
|
319
|
+
let webServiceMethod = currentWebService.method.toUpperCase();
|
|
320
|
+
let webServicePath = currentWebService.path;
|
|
321
|
+
let webServiceHandler = currentWebService.handler;
|
|
322
|
+
if (webServiceMethod === '') throw new Error('Method for webhook must not be empty. Please review the webhooks provided.')
|
|
323
|
+
switch (webServiceMethod) {
|
|
324
|
+
case 'GET':
|
|
325
|
+
webhookRouter.get(webServicePath, webServiceHandler);
|
|
326
|
+
break;
|
|
327
|
+
case 'PUT':
|
|
328
|
+
webhookRouter.put(webServicePath, webServiceHandler);
|
|
329
|
+
break;
|
|
330
|
+
case 'PATCH':
|
|
331
|
+
webhookRouter.patch(webServicePath, webServiceHandler);
|
|
332
|
+
break;
|
|
333
|
+
case 'POST':
|
|
334
|
+
webhookRouter.post(webServicePath, webServiceHandler);
|
|
335
|
+
break;
|
|
336
|
+
case 'DELETE':
|
|
337
|
+
webhookRouter.delete(webServicePath, webServiceHandler);
|
|
338
|
+
break;
|
|
339
|
+
case 'HEAD':
|
|
340
|
+
webhookRouter.head(webServicePath, webServiceHandler);
|
|
341
|
+
break;
|
|
342
|
+
case 'OPTIONS':
|
|
343
|
+
webhookRouter.options(webServicePath, webServiceHandler);
|
|
344
|
+
break;
|
|
345
|
+
case 'CONNECT':
|
|
346
|
+
webhookRouter.connect(webServicePath, webServiceHandler);
|
|
347
|
+
break;
|
|
348
|
+
case 'TRACE':
|
|
349
|
+
webhookRouter.trace(webServicePath, webServiceHandler);
|
|
350
|
+
break;
|
|
351
|
+
default:
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const loadSvcWebServices = () => {
|
|
360
|
+
|
|
361
|
+
loadPlatformWebServices();
|
|
362
|
+
loadDeveloperWebServices();
|
|
363
|
+
|
|
364
|
+
webServicesServer.use(compression());
|
|
365
|
+
webServicesServer.use(bodyParser.urlencoded({ extended: true })); // configure app to use bodyParser()
|
|
366
|
+
webServicesServer.use(bodyParser.json()); // this will let us get the data from a POST
|
|
367
|
+
webServicesServer.use('/api', apiRouter); // all of our routes will be prefixed with /api
|
|
368
|
+
webServicesServer.use('/', webhookRouter); // all of our routes will be prefixed with nothing
|
|
369
|
+
|
|
370
|
+
if (settings.useSsl) {
|
|
371
|
+
// start https service
|
|
372
|
+
const sslCredentials = {
|
|
373
|
+
key: settings.sslKey,
|
|
374
|
+
cert: settings.sslCert
|
|
375
|
+
};
|
|
376
|
+
https.createServer(sslCredentials, webServicesServer).listen(settings.webServicesPort, function () {
|
|
377
|
+
logger.info('Https service ready on port [' + settings.webServicesPort + ']');
|
|
378
|
+
});
|
|
379
|
+
} else {
|
|
380
|
+
// start http service
|
|
381
|
+
http.createServer(webServicesServer).listen(settings.webServicesPort, function () {
|
|
382
|
+
logger.info('Http service ready on port [' + settings.webServicesPort + ']');
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const startSvc = async () => {
|
|
389
|
+
|
|
390
|
+
; ({ settings, serviceConfig: serviceConfig, definitions } = require('./services/configuration/configuration'));
|
|
391
|
+
|
|
392
|
+
svc.settings = settings;
|
|
393
|
+
svc.serviceConfig = serviceConfig;
|
|
394
|
+
svc.definitions = definitions;
|
|
395
|
+
if (svc.hooks.onConfigurationReady) hooks.onConfigurationReady();
|
|
396
|
+
|
|
397
|
+
await loadSvcServices();
|
|
398
|
+
if (svc.hooks.onSvcServicesConfigured) hooks.onSvcServicesConfigured();
|
|
399
|
+
|
|
400
|
+
loadSvcWebServices();
|
|
401
|
+
if (svc.hooks.onWebServicesReady) hooks.onWebServicesReady();
|
|
402
|
+
|
|
403
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
404
|
+
// node.js related events
|
|
405
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
406
|
+
|
|
407
|
+
process.on('exit', code => logger.info('Service stopped - exit code [' + code + ']'));
|
|
408
|
+
process.on('SIGINT', () => {
|
|
409
|
+
logger.info('Service stopped');
|
|
410
|
+
process.exit(0)
|
|
411
|
+
});
|
|
412
|
+
process.on('beforeExit', code => {
|
|
413
|
+
hooks.onSvcStop(code);
|
|
414
|
+
logger.info('Stopping service - exit code [' + code + ']')
|
|
415
|
+
});
|
|
416
|
+
process.on('warning', warning => logger.warn('Warning [' + util.inspect(warning, { showHidden: true, depth: null }) + ']'));
|
|
417
|
+
|
|
418
|
+
appLogger.info('Service [' + settings.svcName + '] is being initialized');
|
|
419
|
+
|
|
420
|
+
logger.info(">>> Memory initial usage: " + util.inspect(process.memoryUsage(), { showHidden: true, depth: null }));
|
|
421
|
+
|
|
422
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
423
|
+
// Service Started
|
|
424
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
425
|
+
appLogger.info('Service [' + settings.svcName + '] started');
|
|
426
|
+
svc.hooks.onSvcStart();
|
|
427
|
+
|
|
428
|
+
if (settings.isUsingProxy) require('./services/settings/settings').refreshCache();
|
|
429
|
+
};
|
|
430
|
+
svc.start = startSvc;
|
|
431
|
+
|
|
432
|
+
module.exports = svc;
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@slingr/slingr-services",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "Nodejs SDK to create Slingr Services",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/slingr-stack/platform-sdk-services/tree/master/service-nodejs-sdk"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"slingr",
|
|
12
|
+
"nodejs",
|
|
13
|
+
"services",
|
|
14
|
+
"framework",
|
|
15
|
+
"sdk"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"axios": "^0.26.1",
|
|
19
|
+
"axios-retry": "^3.2.4",
|
|
20
|
+
"body-parser": "^1.17.2",
|
|
21
|
+
"compression": "^1.7.0",
|
|
22
|
+
"dayjs": "^1.11.0",
|
|
23
|
+
"dotenv": "^16.0.1",
|
|
24
|
+
"express": "^4.15.3",
|
|
25
|
+
"form-data": "^4.0.0",
|
|
26
|
+
"locks": "^0.2.2",
|
|
27
|
+
"moment": "^2.18.1",
|
|
28
|
+
"util": "^0.10.3"
|
|
29
|
+
},
|
|
30
|
+
"author": "Slingr",
|
|
31
|
+
"license": "MIT"
|
|
32
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const logger = require('../loggers/logs');
|
|
2
|
+
const httpModule = require('../httpModule/httpModule');
|
|
3
|
+
|
|
4
|
+
const getUserInformationByToken = async (token) => {
|
|
5
|
+
if(!token) {
|
|
6
|
+
throw new Error('User token can\'t be empty.');
|
|
7
|
+
}
|
|
8
|
+
let userInfo;
|
|
9
|
+
try {
|
|
10
|
+
userInfo = await httpModule.get('/users',{
|
|
11
|
+
params: {
|
|
12
|
+
userToken: token
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
} catch (error) {
|
|
16
|
+
logger.error('Error while triying to get information by token for token ['+token+'].')
|
|
17
|
+
throw new Error('Error while triying to get information by token for token ['+token+'].')
|
|
18
|
+
}
|
|
19
|
+
if (!userInfo) {
|
|
20
|
+
logger.error('No user found with token ['+token+']');
|
|
21
|
+
throw new Error('No user found with token ['+token+']');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const getUserInformationByEmail = async (email) => {
|
|
26
|
+
if(!email) {
|
|
27
|
+
throw new Error('User email can\'t be empty.');
|
|
28
|
+
}
|
|
29
|
+
let userInfo;
|
|
30
|
+
try {
|
|
31
|
+
userInfo = await httpModule.get('/users',{
|
|
32
|
+
params: {
|
|
33
|
+
userEmail: email
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.error('Error while triying to get information by email for email ['+email+'].')
|
|
38
|
+
throw new Error('Error while triying to get information by email for email ['+email+'].')
|
|
39
|
+
}
|
|
40
|
+
if (!userInfo) {
|
|
41
|
+
logger.error('No user found with email ['+email+']');
|
|
42
|
+
throw new Error('No user found with email ['+email+']');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
getUserInformationByToken,
|
|
48
|
+
getUserInformationByEmail,
|
|
49
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
//////////////////////////////////////
|
|
3
|
+
// Load Configuration from env vars //
|
|
4
|
+
//////////////////////////////////////
|
|
5
|
+
const {
|
|
6
|
+
// Service constants
|
|
7
|
+
_svc_name: svcName,
|
|
8
|
+
_app_name: applicationName,
|
|
9
|
+
_pod_id: _podId,
|
|
10
|
+
_environment: environment,
|
|
11
|
+
_local_deployment: _localDeployment,
|
|
12
|
+
_debug: _debug,
|
|
13
|
+
// HTTP services properties
|
|
14
|
+
_webservices_port: webServicesPort,
|
|
15
|
+
_token: token,
|
|
16
|
+
_profile: profile,
|
|
17
|
+
_extension_broker_api: _extension_broker_api,
|
|
18
|
+
_useSsl: _useSsl,
|
|
19
|
+
SSL_KEY: sslKey,
|
|
20
|
+
SSL_CERT: sslCert,
|
|
21
|
+
// System properties
|
|
22
|
+
_custom_domain: domainCustom,
|
|
23
|
+
_base_domain: domainBase,
|
|
24
|
+
// Service specific properties
|
|
25
|
+
_service_config: _service_config
|
|
26
|
+
} = { ...process.env };
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
const podId = _podId.length > 5 ? _podId.substring(_podId.length - 5) : _podId;
|
|
30
|
+
const localDeployment = _localDeployment !== 'false' && !!_localDeployment;
|
|
31
|
+
const debug = _debug !== 'false' && !!_debug;
|
|
32
|
+
const useSsl = !localDeployment || _useSsl;
|
|
33
|
+
const serviceConfig = JSON.parse(_service_config);
|
|
34
|
+
|
|
35
|
+
const maskToken = token => {
|
|
36
|
+
if (!token) {
|
|
37
|
+
return '-';
|
|
38
|
+
}
|
|
39
|
+
return token.length < 10 ? '.'.repeat(token.length) :
|
|
40
|
+
token.length < 20 ? token.substr(0, 2) + '.'.repeat(token.length - 4) + token.substr(token.length - 2) :
|
|
41
|
+
token.substr(0, 4) + '.'.repeat(token.length - 8) + token.substr(token.length - 4)
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const maskedToken = maskToken(token);
|
|
45
|
+
|
|
46
|
+
let cDomain = domainCustom;
|
|
47
|
+
if (cDomain) {
|
|
48
|
+
cDomain = (localDeployment ? 'http' : 'https') + '://' + cDomain
|
|
49
|
+
} else {
|
|
50
|
+
cDomain = (localDeployment ? 'http' : 'https') + '://' + applicationName + '.' + domainBase + '/' + environment
|
|
51
|
+
}
|
|
52
|
+
const domain = cDomain.toLowerCase();
|
|
53
|
+
const secondaryDomain = ((localDeployment ? 'http' : 'https') + '://' + domainBase + '/' + applicationName + '/' + environment).toLowerCase();
|
|
54
|
+
|
|
55
|
+
const webhookUrl = domain + '/services/' + svcName;
|
|
56
|
+
|
|
57
|
+
const proto = useSsl ? 'https' : 'http';
|
|
58
|
+
console.log('Configured service [' + svcName + ']: ' +
|
|
59
|
+
proto + ' [0.0.0.0:' + webServicesPort + '], ' +
|
|
60
|
+
'webhook [' + webhookUrl + '], ' +
|
|
61
|
+
'token [' + maskedToken + '], ' +
|
|
62
|
+
(localDeployment ? ', local deployment' : '')
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const settings = {
|
|
66
|
+
svcName,
|
|
67
|
+
applicationName,
|
|
68
|
+
podId,
|
|
69
|
+
environment,
|
|
70
|
+
localDeployment,
|
|
71
|
+
webServicesPort,
|
|
72
|
+
token,
|
|
73
|
+
maskedToken,
|
|
74
|
+
profile,
|
|
75
|
+
_extension_broker_api,
|
|
76
|
+
webhookUrl,
|
|
77
|
+
useSsl,
|
|
78
|
+
sslKey,
|
|
79
|
+
sslCert,
|
|
80
|
+
domainCustom,
|
|
81
|
+
secondaryDomain,
|
|
82
|
+
domainBase,
|
|
83
|
+
debug,
|
|
84
|
+
serviceConfig: serviceConfig
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
settings,
|
|
89
|
+
serviceConfig: settings.serviceConfig
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
//Some definitions constants
|
|
93
|
+
const USER_CONNECTED_EVENT = 'userConnected',
|
|
94
|
+
USER_DISCONNECTED_EVENT = 'userDisconnected',
|
|
95
|
+
USER_CONNECT_FUNCTION = 'connectUser',
|
|
96
|
+
USER_DISCONNECT_FUNCTION = 'disconnectUser';
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
const logger = require('../loggers/logs');
|
|
100
|
+
let definitions;
|
|
101
|
+
try {
|
|
102
|
+
definitions = JSON.parse(fs.readFileSync('./appService.json', 'utf8'));
|
|
103
|
+
} catch (error) {
|
|
104
|
+
logger.error('Service definitions could not be loaded from \'appService.json\' file: ',error);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//If the service is a PER-USER service, we have to load the user datastore, and the user related events
|
|
108
|
+
if (definitions.configurationType === 'PER_USER') {
|
|
109
|
+
|
|
110
|
+
// add the USERS data store if this is not defined
|
|
111
|
+
definitions.stores.push({name: '__svc_users__'});
|
|
112
|
+
|
|
113
|
+
// add PER USER events if these are not defined
|
|
114
|
+
const hasUserConnectedEvent = definitions.events.some((event)=>{event.name===USER_CONNECTED_EVENT});
|
|
115
|
+
if (!hasUserConnectedEvent) {
|
|
116
|
+
definitions.events.push({
|
|
117
|
+
label: 'User connected',
|
|
118
|
+
name: USER_CONNECTED_EVENT,
|
|
119
|
+
eventType: 'PER_USER',
|
|
120
|
+
description: 'Event triggered when the current user is connected to the service.'
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
const hasUserDisconnectedEvent = definitions.events.some((event)=>{event.name===USER_DISCONNECTED_EVENT});
|
|
124
|
+
if (!hasUserDisconnectedEvent) {
|
|
125
|
+
definitions.events.push({
|
|
126
|
+
label: 'User disconnected',
|
|
127
|
+
name: USER_DISCONNECTED_EVENT,
|
|
128
|
+
eventType: 'PER_USER',
|
|
129
|
+
description: 'Event triggered when the current user is disconnected from the service.'
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// add PER USER functions if these are not defined
|
|
134
|
+
const hasUserConnectedFunction = definitions.functions.some((func)=>{func.name===USER_CONNECT_FUNCTION});
|
|
135
|
+
if (!hasUserConnectedFunction) {
|
|
136
|
+
definitions.functions.push({
|
|
137
|
+
label: 'Connect User',
|
|
138
|
+
name: USER_CONNECT_FUNCTION,
|
|
139
|
+
eventType: 'PER_USER',
|
|
140
|
+
description: 'Connects the user to the service.',
|
|
141
|
+
callbacks: [
|
|
142
|
+
{
|
|
143
|
+
name: USER_CONNECTED_EVENT,
|
|
144
|
+
maxWaitingTime: 60000,
|
|
145
|
+
maxExpectedResponses: 1
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
const hasUserDisconnectFunction = definitions.functions.some((func)=>{func.name===USER_DISCONNECT_FUNCTION});
|
|
151
|
+
if (!hasUserDisconnectFunction) {
|
|
152
|
+
definitions.functions.push({
|
|
153
|
+
label: 'Disconnect User',
|
|
154
|
+
name: USER_DISCONNECT_FUNCTION,
|
|
155
|
+
eventType: 'PER_USER',
|
|
156
|
+
description: 'Disconnects the user from the service.',
|
|
157
|
+
callbacks: [
|
|
158
|
+
{
|
|
159
|
+
name: USER_DISCONNECTED_EVENT,
|
|
160
|
+
maxWaitingTime: 60000,
|
|
161
|
+
maxExpectedResponses: 1
|
|
162
|
+
},
|
|
163
|
+
]
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
module.exports.definitions = definitions;
|
|
171
|
+
|