soajs.controller 4.2.20 → 4.2.31

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/mw/mt/utils.js CHANGED
@@ -33,11 +33,11 @@ if (process.env.SOAJS_SENSITIVE_ENVS) {
33
33
  }
34
34
  }
35
35
 
36
- const {pathToRegexp} = require("path-to-regexp");
36
+ const { pathToRegexp } = require("path-to-regexp");
37
37
 
38
38
  function constructRegExp(route) {
39
39
  let keys = [];
40
- let out = pathToRegexp(route, keys, {sensitive: true});
40
+ let out = pathToRegexp(route, keys, { sensitive: true });
41
41
  if (out && out.keys && out.keys.length > 0) {
42
42
  out = new RegExp(out.toString());
43
43
  }
@@ -83,54 +83,54 @@ let _api = {
83
83
  "checkPermission": function (system, req, api) {
84
84
  if ('restricted' === system.apisPermission) {
85
85
  if (!api) {
86
- return {"result": false, "error": 159};
86
+ return { "result": false, "error": 159 };
87
87
  }
88
88
  return _api.checkAccess(api.access, req);
89
89
  }
90
90
  if (!api) {
91
- return {"result": true};
91
+ return { "result": true };
92
92
  }
93
93
  return _api.checkAccess(api.access, req);
94
94
  },
95
95
  "checkAccess": function (apiAccess, req) {
96
96
  if (!apiAccess) {
97
- return {"result": true};
97
+ return { "result": true };
98
98
  }
99
99
  if (!_urac.getUser(req)) {
100
- return {"result": false, "error": 161};
100
+ return { "result": false, "error": 161 };
101
101
  }
102
102
  if (apiAccess instanceof Array) {
103
103
  let userGroups = _urac.getGroups(req);
104
104
  if (!userGroups) {
105
- return {"result": false, "error": 160};
105
+ return { "result": false, "error": 160 };
106
106
  }
107
107
  for (let ii = 0; ii < userGroups.length; ii++) {
108
108
  if (apiAccess.indexOf(userGroups[ii]) !== -1) {
109
- return {"result": true};
109
+ return { "result": true };
110
110
  }
111
111
  }
112
- return {"result": false, "error": 160};
112
+ return { "result": false, "error": 160 };
113
113
  } else {
114
- return {"result": true};
114
+ return { "result": true };
115
115
  }
116
116
  }
117
117
  };
118
118
 
119
119
  let utils = {
120
-
120
+
121
121
  "ipWhitelist": (obj, cb) => {
122
-
122
+
123
123
  obj.skipACL = false;
124
124
  obj.skipOAUTH = false;
125
125
  /**
126
126
  * obj.req.soajs.registry.custom.gateway.value.mt
127
127
  * {
128
128
  "mt": {
129
- "whitelist": {
130
- "ips": ["10.0.0.0/8"],
131
- "acl": true,
132
- "oauth": true
133
- }
129
+ "whitelist": {
130
+ "ips": ["10.0.0.0/8"],
131
+ "acl": true,
132
+ "oauth": true
133
+ }
134
134
  }
135
135
  }
136
136
  *
@@ -168,13 +168,13 @@ let utils = {
168
168
  }
169
169
  }
170
170
  }
171
-
171
+
172
172
  return cb(null, obj);
173
173
  } else {
174
174
  return cb(null, obj);
175
175
  }
176
176
  },
177
-
177
+
178
178
  "aclUrackCheck": (obj, cb) => {
179
179
  if (obj.skipOAUTH) {
180
180
  return cb(null, obj);
@@ -190,7 +190,7 @@ let utils = {
190
190
  if (uracACL) {
191
191
  obj.finalAcl = uracACL[obj.req.soajs.controller.serviceParams.name];
192
192
  if (obj.finalAcl) {
193
-
193
+
194
194
  if (!obj.req.soajs.controller.serviceParams.versionRequested) {
195
195
  // get latest from ACL
196
196
  let version = null;
@@ -203,10 +203,10 @@ let utils = {
203
203
  obj.req.soajs.controller.serviceParams.version = version;
204
204
  }
205
205
  }
206
-
206
+
207
207
  let san_v = coreLibs.version.sanitize(obj.req.soajs.controller.serviceParams.version);
208
208
  obj.finalAcl = obj.finalAcl[san_v] || obj.finalAcl;
209
-
209
+
210
210
  let method = obj.req.method.toLocaleLowerCase();
211
211
  if (obj.finalAcl && obj.finalAcl[method] && typeof obj.finalAcl[method] === "object") {
212
212
  let newAclObj = {};
@@ -231,7 +231,7 @@ let utils = {
231
231
  }
232
232
  return cb(null, obj);
233
233
  },
234
-
234
+
235
235
  "aclCheck": (obj, cb) => {
236
236
  obj.finalAcl = null;
237
237
  if (obj.req.soajs.controller.serviceParams.finalAcl) {
@@ -239,7 +239,7 @@ let utils = {
239
239
  }
240
240
  return cb(null, obj);
241
241
  },
242
-
242
+
243
243
  /**
244
244
  * Checks if the requested service is accessible based on the ACL configuration
245
245
  *
@@ -258,7 +258,7 @@ let utils = {
258
258
  return cb(154);
259
259
  }
260
260
  },
261
-
261
+
262
262
  /**
263
263
  * checks the geo location of the ariving request against the key configuration
264
264
  * if there is a conflict, the request is not allowed to proceed
@@ -273,8 +273,8 @@ let utils = {
273
273
  }
274
274
  let clientIp = obj.req.getClientIP();
275
275
  let geoAccess = obj.keyObj.geo; //{"allow": ["127.0.0.1"], "deny": []};
276
- obj.geo = {"ip": clientIp};
277
-
276
+ obj.geo = { "ip": clientIp };
277
+
278
278
  let checkAccess = (geoAccessArr, ip) => {
279
279
  return (geoAccessArr.some(function (addr) {
280
280
  try {
@@ -287,24 +287,24 @@ let utils = {
287
287
  return false;
288
288
  }));
289
289
  };
290
-
290
+
291
291
  if (clientIp && geoAccess && geoAccess.deny && Array.isArray(geoAccess.deny)) {
292
292
  let denied = checkAccess(geoAccess.deny, clientIp);
293
293
  if (denied) {
294
294
  return cb(155);
295
295
  }
296
296
  }
297
-
297
+
298
298
  if (clientIp && geoAccess && geoAccess.allow && Array.isArray(geoAccess.allow)) {
299
299
  let allowed = checkAccess(geoAccess.allow, clientIp);
300
300
  if (!allowed) {
301
301
  return cb(155);
302
302
  }
303
303
  }
304
-
304
+
305
305
  return cb(null, obj);
306
306
  },
307
-
307
+
308
308
  /**
309
309
  * checks the device from whicht the ariving request was sent against the key configuration
310
310
  * if there is a conflict, the request is not allowed to proceed
@@ -320,7 +320,7 @@ let utils = {
320
320
  let clientUA = obj.req.getClientUserAgent();
321
321
  let deviceAccess = obj.keyObj.device; //{"allow": [{"family": "chrome"}], "deny": []};
322
322
  obj.device = clientUA;
323
-
323
+
324
324
  let validateField = (fieldName, uaObj, da) => {
325
325
  if (da[fieldName] && da[fieldName] !== '*' && uaObj[fieldName]) {
326
326
  if (typeof (da[fieldName]) === 'string') {
@@ -342,7 +342,7 @@ let utils = {
342
342
  }
343
343
  return true;
344
344
  };
345
-
345
+
346
346
  let checkAccess = (deviceAccessArr, ua) => {
347
347
  let uaObj = useragent.lookup(ua);
348
348
  //if (uaObj && uaObj.family && uaObj.os && uaObj.os.family) {
@@ -388,24 +388,24 @@ let utils = {
388
388
  }));
389
389
  }
390
390
  };
391
-
391
+
392
392
  if (clientUA && deviceAccess && deviceAccess.deny && Array.isArray(deviceAccess.deny)) {
393
393
  let denied = checkAccess(deviceAccess.deny, clientUA);
394
394
  if (denied) {
395
395
  return cb(156);
396
396
  }
397
397
  }
398
-
398
+
399
399
  if (clientUA && deviceAccess && deviceAccess.allow && Array.isArray(deviceAccess.allow)) {
400
400
  let allowed = checkAccess(deviceAccess.allow, clientUA);
401
401
  if (!allowed) {
402
402
  return cb(156);
403
403
  }
404
404
  }
405
-
405
+
406
406
  return cb(null, obj);
407
407
  },
408
-
408
+
409
409
  /**
410
410
  * Checks if oauth is turned on and the ACL strategy of the API.
411
411
  * If the API is public, the request moves forward
@@ -439,7 +439,7 @@ let utils = {
439
439
  if (error) {
440
440
  return cb(error, obj);
441
441
  } else {
442
-
442
+
443
443
  let pin_allowedAPI_check = () => {
444
444
  // Skip is this is pin login route on oauth
445
445
  // Skip if route on controller
@@ -467,10 +467,10 @@ let utils = {
467
467
  obj.req.soajs.registry.custom.oauth.value &&
468
468
  obj.req.soajs.registry.custom.oauth.value.pinWhitelist &&
469
469
  obj.req.soajs.registry.custom.oauth.value.pinWhitelist[obj.req.soajs.controller.serviceParams.name]) {
470
-
470
+
471
471
  let method = obj.req.method.toLocaleLowerCase();
472
472
  let whitelist = obj.req.soajs.registry.custom.oauth.value.pinWhitelist[obj.req.soajs.controller.serviceParams.name];
473
-
473
+
474
474
  obj.req.soajs.log.debug("pinWhitelist detected for service [" + obj.req.soajs.controller.serviceParams.name + "]");
475
475
  if (whitelist[method]) {
476
476
  if (whitelist[method].apis && Array.isArray(whitelist[method].apis)) {
@@ -488,12 +488,12 @@ let utils = {
488
488
  }
489
489
  }
490
490
  obj.req.soajs.log.debug("pinWhitelist not found for method [" + method + "] and path [" + obj.req.soajs.controller.serviceParams.path + "]");
491
-
491
+
492
492
  }
493
493
  return cb(145, obj);
494
494
  }
495
495
  };
496
-
496
+
497
497
  if (obj.req.oauth && obj.req.oauth.bearerToken && obj.req.oauth.bearerToken.user && (obj.req.oauth.bearerToken.user.loginMode === 'urac') && obj.req.oauth.bearerToken.user.pinLocked) {
498
498
  return pin_allowedAPI_check();
499
499
  } else {
@@ -512,7 +512,7 @@ let utils = {
512
512
  }
513
513
  });
514
514
  };
515
-
515
+
516
516
  let system = _system.getAcl(obj);
517
517
  let api = (system && system.apis ? system.apis[obj.req.soajs.controller.serviceParams.path] : null);
518
518
  if (!api && system && system.apisRegExp && Object.keys(system.apisRegExp).length > 0) {
@@ -522,7 +522,7 @@ let utils = {
522
522
  }
523
523
  }
524
524
  }
525
-
525
+
526
526
  //public means:
527
527
  //-------------
528
528
  //case 0:
@@ -575,7 +575,7 @@ let utils = {
575
575
  return cb(null, obj);
576
576
  }
577
577
  },
578
-
578
+
579
579
  /**
580
580
  * Check if the request contains oauth tokens, and calls the urac Driver to retrieve the corresponding user record
581
581
  * @param {Object} obj
@@ -587,21 +587,21 @@ let utils = {
587
587
  return cb(null, obj);
588
588
  }
589
589
  let callURACDriver = function (roaming) {
590
- obj.req.soajs.uracDriver = new UracDriver({"soajs": obj.req.soajs, "oauth": obj.req.oauth});
590
+ obj.req.soajs.uracDriver = new UracDriver({ "soajs": obj.req.soajs, "oauth": obj.req.oauth });
591
591
  obj.req.soajs.uracDriver.init((error) => {
592
592
  if (error && !roaming) {
593
593
  obj.req.soajs.log.error(error.message);
594
- return cb (146);
594
+ return cb(146);
595
595
  }
596
596
  let userServiceConf = obj.req.soajs.uracDriver.getConfig();
597
597
  userServiceConf = userServiceConf || {};
598
-
598
+
599
599
  let tenantServiceConf = obj.keyObj.config;
600
600
  obj.servicesConfig = merge.recursive(true, tenantServiceConf, userServiceConf);
601
601
  return cb(null, obj);
602
602
  });
603
603
  };
604
-
604
+
605
605
  /**
606
606
  * returns code for the requested tenant.
607
607
  * if tenant is the same in the request, returns tenant from request
@@ -614,7 +614,7 @@ let utils = {
614
614
  obj.req.soajs.log.debug("loading tenant data from req.soajs.tenant.id");
615
615
  return cb(null, obj.req.soajs.tenant);
616
616
  }
617
-
617
+
618
618
  obj.req.soajs.log.debug("loading tenant data from req.oauth.bearerToken.clientId");
619
619
  obj.provision.getTenantData(obj.req.oauth.bearerToken.clientId, function (error, tenant) {
620
620
  if (error || !tenant) {
@@ -624,11 +624,11 @@ let utils = {
624
624
  obj.req.soajs.log.error(error.message);
625
625
  return cb(error);
626
626
  }
627
-
627
+
628
628
  return cb(null, tenant);
629
629
  });
630
630
  };
631
-
631
+
632
632
  /**
633
633
  * load the registry of the requested environment.
634
634
  * if environment is the same in the request, return registry from request
@@ -641,9 +641,9 @@ let utils = {
641
641
  obj.req.soajs.log.debug("loading env registry from req.soajs.registry");
642
642
  return cb(null, obj.req.soajs.registry);
643
643
  }
644
-
644
+
645
645
  obj.req.soajs.log.debug("loading env registry from req.oauth.bearerToken.env");
646
- registryModule.loadByEnv({"envCode": obj.req.oauth.bearerToken.env}, function (error, registry) {
646
+ registryModule.loadByEnv({ "envCode": obj.req.oauth.bearerToken.env }, function (error, registry) {
647
647
  if (error || !registry) {
648
648
  if (!registry) {
649
649
  error = new Error("Registry not found for:" + obj.req.oauth.bearerToken.env);
@@ -654,12 +654,12 @@ let utils = {
654
654
  return cb(null, registry);
655
655
  });
656
656
  };
657
-
657
+
658
658
  //NOTE: we go here only if the possibility of roaming is true
659
659
  if (obj.req && obj.req.oauth && obj.req.oauth.bearerToken) {
660
660
  //if (obj.req.oauth.bearerToken.env === "dashboard" && obj.req.oauth.bearerToken.env !== obj.regEnvironment) {
661
661
  if (sensitiveEnvCodes.includes(obj.req.oauth.bearerToken.env.toLowerCase()) && obj.req.oauth.bearerToken.env !== obj.regEnvironment) {
662
- async.parallel({"tenant": getTenantInfo, "registry": getEnvRegistry}, function (error, response) {
662
+ async.parallel({ "tenant": getTenantInfo, "registry": getEnvRegistry }, function (error, response) {
663
663
  if (error) {
664
664
  return cb(170);
665
665
  }
@@ -670,7 +670,7 @@ let utils = {
670
670
  "user": obj.req.oauth.bearerToken.user,
671
671
  "code": response.tenant.code
672
672
  };
673
-
673
+
674
674
  if (response.registry && response.registry.tenantMetaDB) {
675
675
  obj.req.soajs.tenant.roaming.tenantMetaDB = response.registry.tenantMetaDB;
676
676
  }
@@ -683,7 +683,7 @@ let utils = {
683
683
  return cb(null, obj);
684
684
  }
685
685
  },
686
-
686
+
687
687
  /**
688
688
  * Checks if the acl permissions allow access to the requested api or not
689
689
  * @param {Object} obj
@@ -17,6 +17,7 @@ const SoajsRes = require("./response.js");
17
17
  */
18
18
  module.exports = (configuration) => {
19
19
  return (req, res, next) => {
20
+ let ended = false;
20
21
  if (!req.soajs) {
21
22
  req.soajs = {};
22
23
  }
@@ -35,7 +36,7 @@ module.exports = (configuration) => {
35
36
  } else {
36
37
  response = new SoajsRes(true, data);
37
38
  }
38
-
39
+
39
40
  return response;
40
41
  };
41
42
  if (configuration && configuration.controllerResponse) {
@@ -47,7 +48,7 @@ module.exports = (configuration) => {
47
48
  }
48
49
  jsonRes = req.soajs.buildResponse(jsonObj);
49
50
  }
50
-
51
+
51
52
  let headObj = {};
52
53
  if (jsonObj && jsonObj.headObj) {
53
54
  headObj = jsonObj.headObj;
@@ -63,7 +64,10 @@ module.exports = (configuration) => {
63
64
  res.writeHead(200, headObj);
64
65
  }
65
66
  }
66
- res.end(JSON.stringify(jsonRes));
67
+ if (!ended) {
68
+ ended = true;
69
+ res.end(JSON.stringify(jsonRes));
70
+ }
67
71
  };
68
72
  }
69
73
  return next();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "soajs.controller",
3
3
  "description": "soajs multi tenant API gateway",
4
- "version": "4.2.20",
4
+ "version": "4.2.31",
5
5
  "author": {
6
6
  "name": "soajs team",
7
7
  "email": "team@soajs.org"
@@ -28,7 +28,6 @@
28
28
  "netmask": "2.0.2",
29
29
  "oauth2-server": "2.4.1",
30
30
  "path-to-regexp": "6.2.2",
31
- "request": "2.88.2",
32
31
  "soajs.core.libs": "1.2.0",
33
32
  "soajs.core.modules": "5.2.12",
34
33
  "soajs.urac.driver": "3.2.9",
@@ -51,6 +50,7 @@
51
50
  "grunt-mocha-test": "0.13.3",
52
51
  "mocha": "10.7.3",
53
52
  "nock": "13.5.6",
53
+ "request": "2.88.2",
54
54
  "sinon": "19.0.2"
55
55
  }
56
56
  }
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ "services": {
5
+ "controller": {
6
+ "maxPoolSize": 100,
7
+ "authorization": true,
8
+ "requestTimeout": 30,
9
+ "requestTimeoutRenewal": 0
10
+ },
11
+ "config": {
12
+ "awareness": {},
13
+ "key": {
14
+ "algorithm": "aes256",
15
+ "password": "soajs key lal massa"
16
+ },
17
+ "logger": {
18
+ "src": true,
19
+ "level": "debug",
20
+ "formatter": {
21
+ "outputMode": "long"
22
+ }
23
+ },
24
+ "cors": {
25
+ "enabled": true,
26
+ "origin": "*",
27
+ "credentials": "true",
28
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
29
+ "headers": "key,soajsauth,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type",
30
+ "maxage": 1728000
31
+ },
32
+ "oauth": {
33
+ "grants": [
34
+ "password",
35
+ "refresh_token"
36
+ ],
37
+ "accessTokenLifetime": 7200,
38
+ "refreshTokenLifetime": 1209600,
39
+ "debug": false
40
+ },
41
+ "ports": {
42
+ "controller": 4000,
43
+ "maintenanceInc": 1000,
44
+ "randomInc": 100
45
+ },
46
+ "cookie": {},
47
+ "session": {}
48
+ }
49
+ }
50
+ };
package/release ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ IMAGE="gateway"
3
+ DFILE="Dockerfile"
4
+
5
+ echo "Release ${IMAGE} from ${DFILE}"
6
+
7
+ PACKAGE_VERSION=$(cat package.json | grep version | head -1 | awk -Fn '{ print $2 }' | sed 's/[n:",]//g' | tr -d '[[:space:]]')
8
+ MAJOR_VERSION=$(echo ${PACKAGE_VERSION} | awk -F. '{ print $1 }')
9
+ echo "Package version ${PACKAGE_VERSION}"
10
+ echo "Major version ${MAJOR_VERSION}"
11
+
12
+ docker build -t soajsorg/${IMAGE} -f ${DFILE} . --platform linux/amd64
13
+ docker tag soajsorg/${IMAGE}:latest soajsorg/${IMAGE}:${PACKAGE_VERSION}
14
+ docker tag soajsorg/${IMAGE}:latest soajsorg/${IMAGE}:${MAJOR_VERSION}.x
15
+
16
+ docker push soajsorg/${IMAGE}
17
+ docker push soajsorg/${IMAGE}:${PACKAGE_VERSION}
18
+ docker push soajsorg/${IMAGE}:${MAJOR_VERSION}.x
@@ -176,9 +176,6 @@ Controller.prototype.init = function (callback) {
176
176
  app.use(lastSeen_mw());
177
177
 
178
178
  app.use((req, res, next) => {
179
- setImmediate(() => {
180
- req.soajs.controller.gotoservice(req, res, next);
181
- });
182
179
 
183
180
  req.on("error", (error) => {
184
181
  req.soajs.log.error("Error @ controller:", error);
@@ -191,10 +188,12 @@ Controller.prototype.init = function (callback) {
191
188
  req.on("close", () => {
192
189
  if (req.soajs.controller.redirectedRequest) {
193
190
  req.soajs.log.info("Request closed:", req.url);
194
- // req.soajs.controller.redirectedRequest.destroy();
195
- // req.soajs.controller.redirectedRequest = null;
196
191
  }
197
192
  });
193
+
194
+ setImmediate(() => {
195
+ req.soajs.controller.gotoservice(req, res, next);
196
+ });
198
197
  });
199
198
 
200
199
  app.use(utils.logErrors);