soajs.controller 4.2.41 → 4.2.43

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.
Files changed (42) hide show
  1. package/.github/workflows/ci.yml +43 -0
  2. package/.github/workflows/release.yml +92 -0
  3. package/ARCHITECTURE.md +193 -0
  4. package/Gruntfile.js +1 -1
  5. package/docs/configuration-custom-registry.md +421 -0
  6. package/docs/configuration-services-config.md +275 -0
  7. package/docs/data-flow.md +138 -0
  8. package/docs/deployment.md +205 -0
  9. package/docs/external-integrations.md +159 -0
  10. package/docs/gateway-routes.md +259 -0
  11. package/docs/maintenance-routes.md +308 -0
  12. package/docs/middleware/awareness.md +120 -0
  13. package/docs/middleware/cors.md +88 -0
  14. package/docs/middleware/enhancer.md +75 -0
  15. package/docs/middleware/favicon.md +36 -0
  16. package/docs/middleware/gotoService.md +146 -0
  17. package/docs/middleware/ip2ban.md +70 -0
  18. package/docs/middleware/key.md +196 -0
  19. package/docs/middleware/keyACL.md +139 -0
  20. package/docs/middleware/lastSeen.md +111 -0
  21. package/docs/middleware/maintenanceMode.md +81 -0
  22. package/docs/middleware/mt.md +188 -0
  23. package/docs/middleware/oauth.md +173 -0
  24. package/docs/middleware/response.md +106 -0
  25. package/docs/middleware/soajs.md +71 -0
  26. package/docs/middleware/traffic.md +190 -0
  27. package/docs/middleware/url.md +102 -0
  28. package/docs/multi-tenant-security.md +183 -0
  29. package/docs/request-flow.md +230 -0
  30. package/docs/service-discovery.md +167 -0
  31. package/mw/gotoService/redirectToService.js +15 -4
  32. package/mw/key/index.js +16 -1
  33. package/mw/lastSeen/index.js +3 -0
  34. package/mw/mt/urac.js +21 -1
  35. package/mw/mt/utils.js +2 -0
  36. package/package.json +7 -7
  37. package/test/integration/UC1-gateway-routes/index.js +2 -2
  38. package/test/unit/mw/key/index.js +150 -0
  39. package/test/unit/mw/lastSeen/index.js +5 -4
  40. package/test/unit/mw/mt/urac.js +157 -4
  41. package/test/unit/mw/mt/utils.js +6 -6
  42. package/.travis.yml +0 -72
@@ -0,0 +1,230 @@
1
+ # Request Flow
2
+
3
+ The complete request lifecycle through the SOAJS Controller Gateway.
4
+
5
+ ```
6
+ ┌──────────────────────────────────────────────────────────────────────────────────┐
7
+ │ REQUEST LIFECYCLE │
8
+ └──────────────────────────────────────────────────────────────────────────────────┘
9
+
10
+ HTTP Request HTTP Response
11
+ │ ▲
12
+ ▼ │
13
+ ┌──────────────┐ ┌──────────────┐
14
+ │ 1. SOAJS MW │ Initialize req.soajs context │ Error Handler│
15
+ │ │ Attach registry reference │ │
16
+ └──────┬───────┘ └──────▲───────┘
17
+ │ │
18
+ ▼ │
19
+ ┌──────────────┐ │
20
+ │ 2. Security │ CORS, IP Ban, Maintenance Mode │
21
+ │ Checks │ │
22
+ └──────┬───────┘ │
23
+ │ │
24
+ ▼ │
25
+ ┌──────────────┐ │
26
+ │ 3. URL Parse │ Extract: serviceName, version, path │
27
+ │ │ Extract: key/token from header/query │
28
+ └──────┬───────┘ │
29
+ │ │
30
+ ▼ │
31
+ ┌──────────────┐ │
32
+ │ 4. Service │ Resolve service host via awareness │
33
+ │ Discovery │ Support HA (K8s/Swarm) or custom │
34
+ └──────┬───────┘ │
35
+ │ │
36
+ ▼ │
37
+ ┌──────────────┐ │
38
+ │ 5. Tenant │ Load key data, validate tenant │
39
+ │ Resolution │ Extract ACL from package │
40
+ └──────┬───────┘ │
41
+ │ │
42
+ ▼ │
43
+ ┌──────────────┐ │
44
+ │ 6. Security │ IP Whitelist → Geo Check → Device Check │
45
+ │ Pipeline │ → ACL Check → OAuth Check │
46
+ └──────┬───────┘ │
47
+ │ │
48
+ ▼ │
49
+ ┌──────────────┐ │
50
+ │ 7. Traffic │ Rate limiting with configurable │
51
+ │ Control │ strategies and storage backends │
52
+ └──────┬───────┘ │
53
+ │ │
54
+ ▼ │
55
+ ┌──────────────────────────────────────────────────────────────────┬──────┘
56
+ │ 8. PROXY TO SERVICE │
57
+ │ │
58
+ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │
59
+ │ │ Resolve Host │───▶│ Build Request │───▶│ HTTP Proxy │ │
60
+ │ │ (awareness) │ │ (headers/body) │ │ (forward) │ │
61
+ │ └─────────────────┘ └─────────────────┘ └──────────────┘ │
62
+ │ │ │
63
+ │ ▼ │
64
+ │ ┌──────────────────┐ │
65
+ │ │ Target Service │ │
66
+ │ │ (Microservice) │ │
67
+ │ └──────────────────┘ │
68
+ └──────────────────────────────────────────────────────────────────┘
69
+ ```
70
+
71
+ ## Stage Details
72
+
73
+ ### 1. SOAJS Initialization
74
+
75
+ **Middleware:** `mw/soajs/index.js`
76
+
77
+ - Creates `req.soajs` object
78
+ - Attaches registry reference
79
+ - Sets up logging context
80
+ - Initializes controller params
81
+
82
+ ### 2. Security Checks
83
+
84
+ **Middlewares:** `mw/cors`, `mw/ip2ban`, `mw/maintenanceMode`
85
+
86
+ - CORS preflight handling
87
+ - IP blacklist enforcement
88
+ - Maintenance mode check
89
+
90
+ ### 3. URL Parsing
91
+
92
+ **Middleware:** `mw/url/index.js`
93
+
94
+ - Extracts service name from URL path
95
+ - Parses version number (if provided)
96
+ - Extracts API path
97
+
98
+ ### 4. Service Discovery
99
+
100
+ **Middleware:** `mw/awareness/index.js`
101
+
102
+ - Attaches `getHost()` and `getLatestVersion()` functions
103
+ - Supports both custom and HA modes
104
+
105
+ ### 5. Tenant Resolution
106
+
107
+ **Middlewares:** `mw/key`, `mw/keyACL`
108
+
109
+ - Loads external key data
110
+ - Validates key for environment
111
+ - Extracts ACL from package or application
112
+
113
+ ### 6. Security Pipeline
114
+
115
+ **Middleware:** `mw/mt/index.js`
116
+
117
+ - IP whitelist validation
118
+ - Geo-location checks
119
+ - Device fingerprint verification
120
+ - ACL enforcement
121
+ - OAuth token validation
122
+
123
+ ### 7. Traffic Control
124
+
125
+ **Middleware:** `mw/traffic/index.js`
126
+
127
+ - Rate limiting per strategy
128
+ - Response headers (X-RateLimit-*)
129
+
130
+ ### 8. Proxy to Service
131
+
132
+ **Middleware:** `mw/gotoService/*`
133
+
134
+ - Resolves target host
135
+ - Builds proxy request
136
+ - Forwards to microservice
137
+ - Returns response to client
138
+
139
+ ## Configuration Model
140
+
141
+ ```
142
+ ┌─────────────────────────────────────────────────────────────────────────────────┐
143
+ │ CONFIGURATION HIERARCHY │
144
+ └─────────────────────────────────────────────────────────────────────────────────┘
145
+
146
+ ┌─────────────────────────────────────────────────────────────────────────┐
147
+ │ ENVIRONMENT VARIABLES (Highest Priority) │
148
+ ├─────────────────────────────────────────────────────────────────────────┤
149
+ │ SOAJS_ENV │ Environment code (default: "dev") │
150
+ │ SOAJS_SOLO │ Solo mode flag (local registry) │
151
+ │ SOAJS_DEPLOY_HA │ HA mode: "kubernetes" | "swarm" │
152
+ │ SOAJS_MAX_BODY_SIZE │ Max request body (default: 10MB) │
153
+ │ SOAJS_SENSITIVE_ENVS │ Sensitive env codes (default: ["dashboard"]) │
154
+ └─────────────────────────────────────────────────────────────────────────┘
155
+ │
156
+ ▼
157
+ ┌─────────────────────────────────────────────────────────────────────────┐
158
+ │ SERVICE CONFIGURATION │
159
+ ├─────────────────────────────────────────────────────────────────────────┤
160
+ │ config.js │ Service metadata (name, version, port) │
161
+ │ profiles/single.js │ MongoDB connection profile │
162
+ │ profiles/solo.js │ Local file-based profile │
163
+ └─────────────────────────────────────────────────────────────────────────┘
164
+ │
165
+ ▼
166
+ ┌─────────────────────────────────────────────────────────────────────────┐
167
+ │ REGISTRY (from Core DB) │
168
+ ├─────────────────────────────────────────────────────────────────────────┤
169
+ │ services │ Service definitions (ports, hosts, versions) │
170
+ │ serviceConfig │ Global configs (throttling, CORS, OAuth) │
171
+ │ custom.gateway │ Gateway-specific settings │
172
+ │ dbs │ Database connection configs │
173
+ └─────────────────────────────────────────────────────────────────────────┘
174
+ │
175
+ ▼
176
+ ┌─────────────────────────────────────────────────────────────────────────┐
177
+ │ TENANT/APPLICATION (Lowest Priority) │
178
+ ├─────────────────────────────────────────────────────────────────────────┤
179
+ │ Tenant.application │ App-specific OAuth, ACL overrides │
180
+ │ Package.acl │ Package-level access control │
181
+ └─────────────────────────────────────────────────────────────────────────┘
182
+ ```
183
+
184
+ ## Rate Limiting Architecture
185
+
186
+ ```
187
+ ┌─────────────────────────────────────────────────────────────────────────────────┐
188
+ │ RATE LIMITING (THROTTLING) │
189
+ └─────────────────────────────────────────────────────────────────────────────────┘
190
+
191
+ ┌────────────────────────────────────────────────────────────────────────────┐
192
+ │ STRATEGY SELECTION │
193
+ │ │
194
+ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │
195
+ │ │ publicAPIStrategy │ │ privateAPIStrategy │ │
196
+ │ │ (Unauthenticated) │ │ (Authenticated) │ │
197
+ │ └───────────┬─────────────┘ └───────────┬─────────────┘ │
198
+ │ │ │ │
199
+ │ └──────────────┬───────────────────┘ │
200
+ │ ▼ │
201
+ └──────────────────────────────┬─────────────────────────────────────────────┘
202
+ │
203
+ ▼
204
+ ┌────────────────────────────────────────────────────────────────────────────┐
205
+ │ CONFIGURATION CASCADE │
206
+ │ │
207
+ │ 1. Service-specific: gateway.throttling │
208
+ │ 2. Custom registry: gateway.value.traffic.throttling │
209
+ │ 3. Global default: serviceConfig.throttling │
210
+ └──────────────────────────────┬─────────────────────────────────────────────┘
211
+ │
212
+ ▼
213
+ ┌────────────────────────────────────────────────────────────────────────────┐
214
+ │ STORAGE BACKENDS │
215
+ │ │
216
+ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │
217
+ │ │ Memory │ │ MongoDB │ │
218
+ │ │ (Fast, volatile) │ │ (Persistent, shared) │ │
219
+ │ └─────────────────────────┘ └─────────────────────────┘ │
220
+ └──────────────────────────────┬─────────────────────────────────────────────┘
221
+ │
222
+ ▼
223
+ ┌────────────────────────────────────────────────────────────────────────────┐
224
+ │ RESPONSE HEADERS │
225
+ │ │
226
+ │ X-RateLimit-Limit │ Maximum requests allowed │
227
+ │ X-RateLimit-Remaining │ Requests remaining in window │
228
+ │ Retry-After │ Seconds until window resets │
229
+ └────────────────────────────────────────────────────────────────────────────┘
230
+ ```
@@ -0,0 +1,167 @@
1
+ # Service Discovery Modes
2
+
3
+ The SOAJS Controller Gateway supports two service discovery modes: Custom (non-Kubernetes) and HA (Kubernetes/Docker Swarm).
4
+
5
+ ## Discovery Modes Overview
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────────────────────────────┐
9
+ │ SERVICE DISCOVERY MODES │
10
+ └─────────────────────────────────────────────────────────────────────────────────┘
11
+
12
+ ┌─────────────────────────────────┐ ┌──────────────────────────────────────────┐
13
+ │ CUSTOM MODE │ │ HA MODE │
14
+ │ (Non-Kubernetes) │ │ (Kubernetes / Docker Swarm) │
15
+ ├─────────────────────────────────┤ ├──────────────────────────────────────────┤
16
+ │ │ │ │
17
+ │ ┌─────────────────────────┐ │ │ ┌──────────────────────────────────┐ │
18
+ │ │ Registry DB │ │ │ │ Cluster API │ │
19
+ │ │ (MongoDB/Local) │ │ │ │ (K8s API / Docker API) │ │
20
+ │ └───────────┬─────────────┘ │ │ └────────────────┬─────────────────┘ │
21
+ │ │ │ │ │ │
22
+ │ ▼ │ │ ▼ │
23
+ │ ┌─────────────────────────┐ │ │ ┌──────────────────────────────────┐ │
24
+ │ │ Static Host List │ │ │ │ Dynamic Service Discovery │ │
25
+ │ │ per Service/Version │ │ │ │ via Labels/Selectors │ │
26
+ │ └───────────┬─────────────┘ │ │ └────────────────┬─────────────────┘ │
27
+ │ │ │ │ │ │
28
+ │ ▼ │ │ ▼ │
29
+ │ ┌─────────────────────────┐ │ │ ┌──────────────────────────────────┐ │
30
+ │ │ In-Memory Health │ │ │ │ Automatic Health Monitoring │ │
31
+ │ │ State Tracking │ │ │ │ via Pod/Container Status │ │
32
+ │ └───────────┬─────────────┘ │ │ └────────────────┬─────────────────┘ │
33
+ │ │ │ │ │ │
34
+ │ ▼ │ │ ▼ │
35
+ │ ┌─────────────────────────┐ │ │ ┌──────────────────────────────────┐ │
36
+ │ │ Round-Robin │ │ │ │ Cluster Load Balancing │ │
37
+ │ │ Selection │ │ │ │ (via Service/Ingress) │ │
38
+ │ └─────────────────────────┘ │ │ └──────────────────────────────────┘ │
39
+ │ │ │ │
40
+ └─────────────────────────────────┘ └──────────────────────────────────────────┘
41
+ ```
42
+
43
+ ## Custom Mode
44
+
45
+ Used when running outside of container orchestration platforms.
46
+
47
+ ### Configuration
48
+
49
+ Set via environment variable:
50
+ ```bash
51
+ # Do not set SOAJS_DEPLOY_HA, or set it to empty
52
+ unset SOAJS_DEPLOY_HA
53
+ ```
54
+
55
+ ### How it Works
56
+
57
+ 1. **Registry Loading**: Service hosts are loaded from MongoDB registry
58
+ 2. **Host List**: Static list of hosts per service/version
59
+ 3. **Health Tracking**: In-memory state tracking with heartbeat
60
+ 4. **Load Balancing**: Round-robin selection among healthy hosts
61
+
62
+ ### Registry Structure
63
+
64
+ ```javascript
65
+ // In environment registry
66
+ {
67
+ "services": {
68
+ "oauth": {
69
+ "port": 4002,
70
+ "hosts": {
71
+ "1": ["host1.local", "host2.local"],
72
+ "2": ["host3.local"]
73
+ }
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ## HA Mode (Kubernetes)
80
+
81
+ Used when running in Kubernetes.
82
+
83
+ ### Configuration
84
+
85
+ ```bash
86
+ export SOAJS_DEPLOY_HA=kubernetes
87
+ ```
88
+
89
+ ### How it Works
90
+
91
+ 1. **API Discovery**: Uses Kubernetes API to discover services
92
+ 2. **Label Selectors**: Finds pods via SOAJS labels
93
+ 3. **Health Monitoring**: Leverages pod readiness/liveness probes
94
+ 4. **Load Balancing**: Can use Kubernetes Service or direct pod access
95
+
96
+ ### Kubernetes Labels
97
+
98
+ SOAJS uses these labels to discover services:
99
+
100
+ ```yaml
101
+ metadata:
102
+ labels:
103
+ soajs.env.code: dev
104
+ soajs.service.name: oauth
105
+ soajs.service.version: "1"
106
+ ```
107
+
108
+ ## HA Mode (Docker Swarm)
109
+
110
+ Used when running in Docker Swarm.
111
+
112
+ ### Configuration
113
+
114
+ ```bash
115
+ export SOAJS_DEPLOY_HA=swarm
116
+ ```
117
+
118
+ ### How it Works
119
+
120
+ 1. **API Discovery**: Uses Docker Swarm API to discover services
121
+ 2. **Label Selectors**: Finds tasks via SOAJS labels
122
+ 3. **Health Monitoring**: Leverages task health checks
123
+ 4. **Load Balancing**: Can use Swarm service mesh or direct task access
124
+
125
+ ## Awareness Middleware
126
+
127
+ **File:** `mw/awareness/index.js`
128
+
129
+ The awareness middleware attaches helper functions to the request:
130
+
131
+ ```javascript
132
+ req.soajs.awareness = {
133
+ getHost: function(serviceName, version, callback) {
134
+ // Returns host:port for the service
135
+ },
136
+ getLatestVersion: function(serviceName, callback) {
137
+ // Returns latest available version
138
+ }
139
+ };
140
+ ```
141
+
142
+ ## Cross-Environment Awareness
143
+
144
+ **File:** `mw/awarenessEnv/index.js`
145
+
146
+ For roaming requests that need to access services in other environments:
147
+
148
+ ```javascript
149
+ req.soajs.awarenessEnv = {
150
+ getHost: function(envCode, serviceName, version, callback) {
151
+ // Returns host:port for service in specified environment
152
+ }
153
+ };
154
+ ```
155
+
156
+ ## Driver Module
157
+
158
+ **File:** `modules/driver/index.js`
159
+
160
+ The driver module abstracts infrastructure-specific operations:
161
+
162
+ | Method | Description |
163
+ |--------|-------------|
164
+ | `getServiceHosts()` | Get all hosts for a service |
165
+ | `getServiceHost()` | Get a single host (load balanced) |
166
+ | `getLatestVersion()` | Get latest version number |
167
+ | `getInfo()` | Get node/container info |
@@ -194,6 +194,9 @@ module.exports = (configuration) => {
194
194
  const extraOptions = {};
195
195
 
196
196
  if (monitor && !monitor_service_blacklist && monitor.req_response) {
197
+ const MAX_RESPONSE_SIZE = process.env.SOAJS_MAX_RESPONSE_SIZE || 10 * 1024 * 1024; // 10MB default
198
+ let responseSize = 0;
199
+ let responseExceeded = false;
197
200
  extraOptions.events = {
198
201
  "response": (_resContentType) => {
199
202
  resContentType = _resContentType;
@@ -209,10 +212,18 @@ module.exports = (configuration) => {
209
212
  },
210
213
  "data": (chunk) => {
211
214
  if (!isStream && allowedContentType) {
212
- if (!monitoObj.response) {
213
- monitoObj.response = chunk;
214
- } else {
215
- monitoObj.response += chunk;
215
+ responseSize += chunk.length;
216
+ if (responseSize > MAX_RESPONSE_SIZE) {
217
+ if (!responseExceeded) {
218
+ responseExceeded = true;
219
+ monitoObj.response = "{\"error\": \"Response body exceeds maximum size limit\"}";
220
+ }
221
+ } else if (!responseExceeded) {
222
+ if (!monitoObj.response) {
223
+ monitoObj.response = chunk;
224
+ } else {
225
+ monitoObj.response += chunk;
226
+ }
216
227
  }
217
228
  } else {
218
229
  monitoObj.response = "{\"contentType\": \"is stream or not allowed\", \"value': \"" + resContentType + "\"}";
package/mw/key/index.js CHANGED
@@ -8,13 +8,15 @@
8
8
  * found in the LICENSE file at the root of this repository
9
9
  */
10
10
 
11
+ const get = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);
12
+
11
13
  /**
12
14
  *
13
15
  * @param {object} configuration {provision,regEnvironment}
14
16
  * @returns {Function}
15
17
  */
16
18
  module.exports = (configuration) => {
17
-
19
+
18
20
  return (req, res, next) => {
19
21
  let key = req.get("key");
20
22
  if (key) {
@@ -34,6 +36,19 @@ module.exports = (configuration) => {
34
36
  return next(144);
35
37
  }
36
38
  }
39
+
40
+ // Check for network-based package override
41
+ let network = get(["soajs", "registry", "custom", "gateway", "value", "lastSeen", "network"], req);
42
+ if (network) {
43
+ let product = keyObj.application.product;
44
+ let networkPackageConfig = get(["config", "gateway", "networkPackages", network, product], keyObj);
45
+ if (networkPackageConfig && networkPackageConfig.default) {
46
+ let originalPackage = keyObj.application.package;
47
+ keyObj.application.package = networkPackageConfig.default;
48
+ req.soajs.log.debug("Network package override: replaced package [" + originalPackage + "] with [" + networkPackageConfig.default + "] for network [" + network + "] and product [" + product + "]");
49
+ }
50
+ }
51
+
37
52
  configuration.provision.getPackageData(keyObj.application.package, function (err, packObj) {
38
53
  if (err) {
39
54
  req.soajs.log.error("Unable to fetch data about package [" + keyObj.application.package + "]");
@@ -47,6 +47,9 @@ module.exports = () => {
47
47
  "json": true,
48
48
  "method": "POST"
49
49
  };
50
+ if (lastSeen.network) {
51
+ options.body = { "network": lastSeen.network };
52
+ }
50
53
  if (req.headers && req.headers.soajsinjectobj) {
51
54
  options.headers = { "soajsinjectobj": req.headers.soajsinjectobj };
52
55
  }
package/mw/mt/urac.js CHANGED
@@ -14,6 +14,8 @@ let provision = coreModules.provision;
14
14
 
15
15
  const lib = require("./lib.js");
16
16
 
17
+ const get = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);
18
+
17
19
  function Urac(param) {
18
20
  let _self = this;
19
21
 
@@ -101,7 +103,25 @@ Urac.prototype.resolveACL = function (cb) {
101
103
  let productCode = _self.soajs.tenant.application.product;
102
104
  if (_self.userRecord.groupsConfig && _self.userRecord.groupsConfig.allowedPackages) {
103
105
  if (_self.userRecord.groupsConfig.allowedPackages[productCode]) {
104
- provision.getPackagesData(_self.userRecord.groupsConfig.allowedPackages[productCode], (error, arrayACLs) => {
106
+ let allowedPackages = _self.userRecord.groupsConfig.allowedPackages[productCode].slice();
107
+
108
+ // Check for user-specific network package override
109
+ let network = get(["registry", "custom", "gateway", "value", "lastSeen", "network"], _self.soajs);
110
+ if (network) {
111
+ let keyObj = get(["controller", "serviceParams", "keyObj"], _self.soajs);
112
+ let networkPackageConfig = get(["config", "gateway", "networkPackages", network, productCode], keyObj);
113
+ if (networkPackageConfig && networkPackageConfig.users) {
114
+ for (let i = 0; i < allowedPackages.length; i++) {
115
+ if (networkPackageConfig.users[allowedPackages[i]]) {
116
+ let originalPackage = allowedPackages[i];
117
+ allowedPackages[i] = networkPackageConfig.users[allowedPackages[i]];
118
+ _self.soajs.log.debug("User network package override: replaced package [" + originalPackage + "] with [" + allowedPackages[i] + "] for network [" + network + "] and product [" + productCode + "]");
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ provision.getPackagesData(allowedPackages, (error, arrayACLs) => {
105
125
  if (error) {
106
126
  return cb();
107
127
  } else {
package/mw/mt/utils.js CHANGED
@@ -632,6 +632,8 @@ let utils = {
632
632
  obj.req.soajs.log.error(error.message, error.code);
633
633
  return cb(146);
634
634
  }
635
+ //NOTE: if the user changes the account's email or phone and validateTokenAccount is set to true,
636
+ // kick the user out to force re login. i.e. the username behaviour is similar by default
635
637
  if (obj.keyObj.config && obj.keyObj.config.gateway && obj.keyObj.config.gateway.validateTokenAccount) {
636
638
  if (obj.req.soajs.uracDriver.bearerTokenUser && record) {
637
639
  if (obj.keyObj.config.gateway.validateTokenAccount.email && record.email) {
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.41",
4
+ "version": "4.2.43",
5
5
  "author": {
6
6
  "name": "soajs team",
7
7
  "email": "team@soajs.org"
@@ -21,7 +21,7 @@
21
21
  "async": "3.2.6",
22
22
  "connect": "3.7.0",
23
23
  "http-proxy": "1.18.1",
24
- "jsonwebtoken": "9.0.2",
24
+ "jsonwebtoken": "9.0.3",
25
25
  "kubernetes-client": "9.0.0",
26
26
  "lodash": "4.17.21",
27
27
  "merge": "2.1.1",
@@ -34,11 +34,11 @@
34
34
  "useragent": "2.3.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@babel/core": "7.28.5",
37
+ "@babel/core": "7.28.6",
38
38
  "@babel/plugin-transform-runtime": "7.28.5",
39
- "@babel/preset-env": "7.28.5",
40
- "@babel/runtime": "7.28.4",
41
- "express": "4.21.1",
39
+ "@babel/preset-env": "7.28.6",
40
+ "@babel/runtime": "7.28.6",
41
+ "express": "5.2.1",
42
42
  "grunt": "1.6.1",
43
43
  "grunt-babel": "8.0.0",
44
44
  "grunt-contrib-clean": "2.0.1",
@@ -52,6 +52,6 @@
52
52
  "mocha": "11.7.5",
53
53
  "nock": "14.0.10",
54
54
  "request": "2.88.2",
55
- "sinon": "21.0.0"
55
+ "sinon": "21.0.1"
56
56
  }
57
57
  }
@@ -166,7 +166,7 @@ describe("Integration for Usecase 1", function () {
166
166
  };
167
167
  requester('get', options, (error, body) => {
168
168
  assert.ok(body);
169
- assert.equal(body.data.type, "endpoint");
169
+ assert.strictEqual(body.data.type, "endpoint");
170
170
  done();
171
171
  });
172
172
  });
@@ -252,7 +252,7 @@ describe("Integration for Usecase 1", function () {
252
252
  }
253
253
  };
254
254
  requester('get', options, (error, body) => {
255
- assert.equal(body.data.id, '/muser/:12?access_token=cfb209a91b23896820f510aadbf1f4284b512123');
255
+ assert.strictEqual(body.data.id, '/muser/:12?access_token=cfb209a91b23896820f510aadbf1f4284b512123');
256
256
  done();
257
257
  });
258
258
  });