soajs.controller 4.2.42 → 4.3.0

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 (37) hide show
  1. package/.github/workflows/ci.yml +43 -0
  2. package/.github/workflows/release.yml +94 -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 +568 -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/key/index.js +16 -1
  32. package/mw/mt/urac.js +21 -1
  33. package/mw/mt/utils.js +2 -0
  34. package/package.json +13 -13
  35. package/test/unit/mw/key/index.js +150 -0
  36. package/test/unit/mw/mt/urac.js +157 -4
  37. package/.travis.yml +0 -72
@@ -0,0 +1,183 @@
1
+ # Multi-Tenant Security Pipeline
2
+
3
+ The SOAJS Controller Gateway implements a comprehensive security pipeline for multi-tenant environments.
4
+
5
+ ## Security Check Flow
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────────────────────────────┐
9
+ │ MULTI-TENANT SECURITY CHECKS │
10
+ └─────────────────────────────────────────────────────────────────────────────────┘
11
+
12
+ Incoming Request with Key
13
+ │
14
+ ▼
15
+ ┌───────────────────┐
16
+ │ 1. IP Whitelist │ Check application-level IP restrictions
17
+ │ Validation │ FAIL → 403 Forbidden
18
+ └─────────┬─────────┘
19
+ │ PASS
20
+ ▼
21
+ ┌───────────────────┐
22
+ │ 2. Geo-Location │ Validate request origin geography
23
+ │ Check │ FAIL → 403 Forbidden
24
+ └─────────┬─────────┘
25
+ │ PASS
26
+ ▼
27
+ ┌───────────────────┐
28
+ │ 3. Device │ Verify device fingerprint
29
+ │ Fingerprint │ FAIL → 403 Forbidden
30
+ └─────────┬─────────┘
31
+ │ PASS
32
+ ▼
33
+ ┌───────────────────┐
34
+ │ 4. ACL Check │ Validate service/API access permission
35
+ │ │ FAIL → 403 Forbidden
36
+ └─────────┬─────────┘
37
+ │ PASS
38
+ ▼
39
+ ┌───────────────────┐
40
+ │ 5. OAuth Check │ Validate token (OAuth2 or JWT)
41
+ │ │ FAIL → 401 Unauthorized
42
+ └─────────┬─────────┘
43
+ │ PASS
44
+ ▼
45
+ ┌───────────────────┐
46
+ │ 6. URAC Profile │ Load user profile and groups
47
+ │ Resolution │ Resolve user-specific ACL
48
+ └─────────┬─────────┘
49
+ │
50
+ ▼
51
+ Continue to Service
52
+ ```
53
+
54
+ ## Security Checks Detail
55
+
56
+ ### 1. IP Whitelist Validation
57
+
58
+ **Middleware:** `mw/mt/utils.js`
59
+
60
+ Validates that the request IP is allowed to access the application.
61
+
62
+ - Configured per external key in the key's `geo` field
63
+ - Supports CIDR notation for IP ranges
64
+ - Also supports gateway-level whitelist via custom registry
65
+
66
+ ### 2. Geo-Location Check
67
+
68
+ **Middleware:** `mw/mt/utils.js`
69
+
70
+ Validates request origin based on geographic location.
71
+
72
+ - Configured in external key's `geo` field
73
+ - Supports country-level restrictions
74
+
75
+ ### 3. Device Fingerprint
76
+
77
+ **Middleware:** `mw/mt/utils.js`
78
+
79
+ Validates device fingerprint for mobile/app authentication.
80
+
81
+ - Configured in external key's `device` field
82
+ - Useful for mobile app authentication
83
+
84
+ ### 4. ACL Check
85
+
86
+ **Middleware:** `mw/mt/utils.js`
87
+
88
+ Validates that the tenant has access to the requested service/API.
89
+
90
+ ACL Resolution Priority:
91
+ 1. User-specific ACL (from URAC profile)
92
+ 2. Application ACL (from tenant application)
93
+ 3. Package ACL (from product package)
94
+
95
+ ### 5. OAuth Check
96
+
97
+ **Middleware:** `mw/oauth/index.js`
98
+
99
+ Validates OAuth2 tokens or JWT.
100
+
101
+ - Supports OAuth2 password grant
102
+ - Supports JWT validation
103
+ - Configurable per service
104
+
105
+ ### 6. URAC Profile Resolution
106
+
107
+ **Middleware:** `mw/mt/urac.js`
108
+
109
+ Loads user profile from URAC for authenticated requests.
110
+
111
+ - Resolves user groups
112
+ - Applies user-specific ACL overrides
113
+ - Handles network package override for user packages
114
+
115
+ ## IP Whitelist Configuration
116
+
117
+ ### Gateway-Level Whitelist
118
+
119
+ ```javascript
120
+ // In custom registry: gateway.value.mt.whitelist
121
+ {
122
+ "mt": {
123
+ "whitelist": {
124
+ "ips": ["10.0.0.0/8", "192.168.1.0/24"],
125
+ "acl": true, // Skip ACL checks for whitelisted IPs
126
+ "oauth": true // Skip OAuth checks for whitelisted IPs
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Key-Level Restrictions
133
+
134
+ ```javascript
135
+ // In external key definition
136
+ {
137
+ "extKey": "...",
138
+ "env": "DEV",
139
+ "geo": {
140
+ "ips": ["192.168.1.0/24"],
141
+ "countries": ["US", "CA"]
142
+ },
143
+ "device": {
144
+ "allow": ["iOS", "Android"]
145
+ }
146
+ }
147
+ ```
148
+
149
+ ## ACL Structure
150
+
151
+ ```javascript
152
+ {
153
+ "serviceName": {
154
+ "version": {
155
+ "access": true, // or false, or ["group1", "group2"]
156
+ "apisPermission": "restricted", // "restricted" = whitelist mode
157
+ "get": {
158
+ "apis": {
159
+ "/api/path": {
160
+ "access": ["owner", "admin"] // Groups allowed
161
+ }
162
+ }
163
+ },
164
+ "post": { ... },
165
+ "put": { ... },
166
+ "delete": { ... }
167
+ }
168
+ }
169
+ }
170
+ ```
171
+
172
+ ## Error Codes
173
+
174
+ | Code | Description |
175
+ |------|-------------|
176
+ | 150 | ACL validation failed - no access to service |
177
+ | 151 | ACL validation failed - no access to API |
178
+ | 152 | ACL validation failed - version mismatch |
179
+ | 153 | Geo-location validation failed |
180
+ | 154 | Device validation failed |
181
+ | 155 | IP whitelist validation failed |
182
+ | 401 | OAuth token invalid or expired |
183
+ | 403 | Access forbidden |
@@ -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 |
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 + "]");
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) {