soajs.controller 4.2.42 → 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 (37) 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/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 +7 -7
  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,106 @@
1
+ # Response Middleware
2
+
3
+ **File:** `mw/response/index.js`
4
+
5
+ **Order:** 4
6
+
7
+ The Response middleware adds standardized response builder methods to the request object.
8
+
9
+ ## Purpose
10
+
11
+ - Adds `req.soajs.buildResponse()` for creating SOAJS-formatted responses
12
+ - Adds `req.soajs.controllerResponse()` for sending gateway responses
13
+ - Provides consistent error/success response structure
14
+
15
+ ## Flow
16
+
17
+ ```
18
+ Incoming Request
19
+ │
20
+ ▼
21
+ ┌─────────────────────────┐
22
+ │ Attach buildResponse() │ Creates SOAJS response objects
23
+ └────────────┬────────────┘
24
+ │
25
+ ▼
26
+ ┌─────────────────────────────┐
27
+ │ Attach controllerResponse()│ Sends JSON responses
28
+ └────────────┬────────────────┘
29
+ │
30
+ ▼
31
+ next()
32
+ ```
33
+
34
+ ## Methods Added
35
+
36
+ ### `req.soajs.buildResponse(error, data)`
37
+
38
+ Creates a SOAJS-formatted response object.
39
+
40
+ **Parameters:**
41
+ - `error` - Error object or array of errors (optional)
42
+ - `data` - Response data (optional)
43
+
44
+ **Returns:**
45
+ ```javascript
46
+ // Success
47
+ {
48
+ "result": true,
49
+ "data": { ... }
50
+ }
51
+
52
+ // Error
53
+ {
54
+ "result": false,
55
+ "errors": {
56
+ "codes": [100, 101],
57
+ "details": [
58
+ { "code": 100, "message": "Error message" },
59
+ { "code": 101, "message": "Another error" }
60
+ ]
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### `req.soajs.controllerResponse(jsonObj)`
66
+
67
+ Sends a JSON response and ends the request.
68
+
69
+ **Parameters:**
70
+ - `jsonObj` - Response object with optional `status`, `headObj`, `code`, `msg`
71
+
72
+ **Examples:**
73
+ ```javascript
74
+ // Success response
75
+ req.soajs.controllerResponse({ data: { user: "john" } });
76
+
77
+ // Error response
78
+ req.soajs.controllerResponse({
79
+ status: 403,
80
+ code: 150,
81
+ msg: "Access denied"
82
+ });
83
+
84
+ // With custom headers
85
+ req.soajs.controllerResponse({
86
+ status: 429,
87
+ msg: "Too many requests",
88
+ headObj: {
89
+ "Retry-After": 60,
90
+ "X-RateLimit-Limit": 100
91
+ }
92
+ });
93
+ ```
94
+
95
+ ## Response Format
96
+
97
+ All responses include:
98
+ - `Content-Type: application/json` header
99
+ - HTTP status code (default: 200)
100
+ - JSON body
101
+
102
+ ## Usage Notes
103
+
104
+ - `controllerResponse()` only available when `controllerResponse: true` in config
105
+ - Prevents double-ending responses (tracks `ended` state)
106
+ - Automatically formats errors using `buildResponse()` when `code` and `msg` provided
@@ -0,0 +1,71 @@
1
+ # SOAJS Middleware
2
+
3
+ **File:** `mw/soajs/index.js`
4
+
5
+ **Order:** 1
6
+
7
+ The SOAJS middleware is the first middleware in the pipeline. It initializes the `req.soajs` context object that all subsequent middleware depend on.
8
+
9
+ ## Purpose
10
+
11
+ - Creates the `req.soajs` namespace
12
+ - Attaches the logger instance
13
+ - Attaches the current registry reference
14
+ - Attaches core utility modules (meta, validator)
15
+
16
+ ## Flow
17
+
18
+ ```
19
+ Incoming Request
20
+ │
21
+ ▼
22
+ ┌─────────────────┐
23
+ │ Create │ if (!req.soajs) req.soajs = {}
24
+ │ req.soajs │
25
+ └────────┬────────┘
26
+ │
27
+ ▼
28
+ ┌─────────────────┐
29
+ │ Attach Logger │ req.soajs.log = log
30
+ └────────┬────────┘
31
+ │
32
+ ▼
33
+ ┌─────────────────┐
34
+ │ Attach │ req.soajs.registry = registryModule.get()
35
+ │ Registry │
36
+ └────────┬────────┘
37
+ │
38
+ ▼
39
+ ┌─────────────────┐
40
+ │ Attach Core │ req.soajs.meta = core.meta
41
+ │ Modules │ req.soajs.validator = core.validator
42
+ └────────┬────────┘
43
+ │
44
+ ▼
45
+ next()
46
+ ```
47
+
48
+ ## Configuration
49
+
50
+ ```javascript
51
+ {
52
+ "log": logger, // Logger instance
53
+ "core": coreModule // soajs.core.libs module
54
+ }
55
+ ```
56
+
57
+ ## Properties Set
58
+
59
+ | Property | Type | Description |
60
+ |----------|------|-------------|
61
+ | `req.soajs.log` | object | Logger instance for request-scoped logging |
62
+ | `req.soajs.registry` | object | Current environment registry |
63
+ | `req.soajs.meta` | object | Metadata utilities from core |
64
+ | `req.soajs.validator` | object | JSON schema validator |
65
+
66
+ ## Usage Notes
67
+
68
+ - This middleware MUST be first in the pipeline
69
+ - All other middleware assume `req.soajs` exists
70
+ - The registry is fetched fresh on each request (reference, not copy)
71
+ - Logger supports: `debug()`, `info()`, `warn()`, `error()`, `fatal()`
@@ -0,0 +1,190 @@
1
+ # Traffic Middleware
2
+
3
+ **File:** `mw/traffic/index.js`
4
+
5
+ **Order:** 16
6
+
7
+ The Traffic middleware implements rate limiting (throttling) with configurable strategies and storage backends.
8
+
9
+ ## Purpose
10
+
11
+ - Enforces rate limiting per tenant/IP
12
+ - Supports configurable throttling strategies
13
+ - Provides memory and MongoDB storage backends
14
+ - Returns rate limit headers in responses
15
+
16
+ ## Flow
17
+
18
+ ```
19
+ Incoming Request
20
+ │
21
+ ▼
22
+ ┌─────────────────────────┐
23
+ │ Check Prerequisites │ registry, tenant, controller exist?
24
+ └────────┬────────────────┘
25
+ │
26
+ ├─── Missing ──▶ next()
27
+ │
28
+ ▼
29
+ ┌─────────────────────────┐
30
+ │ Determine Strategy │ publicAPIStrategy or privateAPIStrategy
31
+ └────────┬────────────────┘
32
+ │
33
+ ├─── No strategy ──▶ next()
34
+ │
35
+ ▼
36
+ ┌─────────────────────────┐
37
+ │ Get Throttling Config │ Priority:
38
+ │ │ 1. servicesConfig.gateway.throttling
39
+ │ │ 2. custom.gateway.value.traffic.throttling
40
+ │ │ 3. serviceConfig.throttling
41
+ └────────┬────────────────┘
42
+ │
43
+ ▼
44
+ ┌─────────────────────────┐
45
+ │ Check Throttling │ Get/increment counter
46
+ │ Counter │ Compare to limit
47
+ └────────┬────────────────┘
48
+ │
49
+ ├─── Under limit ──▶ next()
50
+ │
51
+ ├─── Over limit, retries left ──▶ Delay and retry
52
+ │
53
+ └─── Over limit, no retries ──▶ 429 Too Many Requests
54
+ ```
55
+
56
+ ## Configuration
57
+
58
+ ### Strategy Definition
59
+
60
+ Located in `registry.serviceConfig.throttling`:
61
+
62
+ ```javascript
63
+ {
64
+ "throttling": {
65
+ "publicAPIStrategy": "default", // For unauthenticated requests
66
+ "privateAPIStrategy": "heavy", // For authenticated requests
67
+ "default": {
68
+ "status": 1, // 0=Off, 1=On
69
+ "type": 1, // 0=tenant, 1=tenant+IP
70
+ "window": 60000, // Time window in ms
71
+ "limit": 50, // Max requests per window
72
+ "retries": 2, // Retries when over limit
73
+ "delay": 1000 // Delay between retries (ms)
74
+ },
75
+ "heavy": {
76
+ "status": 1,
77
+ "type": 1,
78
+ "window": 60000,
79
+ "limit": 500,
80
+ "retries": 2,
81
+ "delay": 1000
82
+ },
83
+ "strict": {
84
+ "status": 1,
85
+ "type": 1,
86
+ "window": 60000,
87
+ "limit": 10,
88
+ "retries": 0,
89
+ "delay": 0
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### Service-Specific Override
96
+
97
+ Via custom registry or tenant config:
98
+
99
+ ```javascript
100
+ {
101
+ "throttling": {
102
+ "oauth": {
103
+ "publicAPIStrategy": "strict",
104
+ "apis": ["/token"] // Only these APIs
105
+ },
106
+ "payment": {
107
+ "publicAPIStrategy": "strict",
108
+ "privateAPIStrategy": "heavy",
109
+ "apis": ["/charge", "/refund"]
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## Strategy Selection
116
+
117
+ | Request Type | Strategy Used |
118
+ |--------------|---------------|
119
+ | Public API (no auth) | `publicAPIStrategy` |
120
+ | Private API (authenticated) | `privateAPIStrategy` |
121
+
122
+ Determined by: `req.soajs.controller.serviceParams.isAPIPublic`
123
+
124
+ ## Storage Backends
125
+
126
+ ### Memory (Default)
127
+
128
+ - Fast, in-process storage
129
+ - Lost on restart
130
+ - Good for single-instance deployments
131
+
132
+ ### MongoDB
133
+
134
+ - Persistent storage
135
+ - Shared across instances
136
+ - Required for multi-instance deployments
137
+
138
+ Configure via `registry.custom.gateway.value.traffic.model`:
139
+
140
+ ```javascript
141
+ {
142
+ "traffic": {
143
+ "model": "mongo" // or "memory"
144
+ }
145
+ }
146
+ ```
147
+
148
+ ## Rate Limit Response
149
+
150
+ When rate limit exceeded:
151
+
152
+ ```
153
+ HTTP/1.1 429 Too Many Requests
154
+ Content-Type: application/json
155
+ Retry-After: 45
156
+ X-RateLimit-Limit: 50
157
+ X-RateLimit-Remaining: 0
158
+
159
+ {
160
+ "result": false,
161
+ "errors": { ... }
162
+ }
163
+ ```
164
+
165
+ ## Response Headers
166
+
167
+ | Header | Description |
168
+ |--------|-------------|
169
+ | `X-RateLimit-Limit` | Maximum requests allowed |
170
+ | `X-RateLimit-Remaining` | Requests remaining in window |
171
+ | `Retry-After` | Seconds until window resets |
172
+
173
+ ## Throttle Key Structure
174
+
175
+ ```javascript
176
+ {
177
+ "l1": "tenant_id",
178
+ "l2": "client_ip"
179
+ }
180
+ ```
181
+
182
+ Creates unique tracking per tenant per IP.
183
+
184
+ ## Usage Notes
185
+
186
+ - Throttling disabled if no strategy configured
187
+ - Service-specific config overrides global config
188
+ - APIs array allows targeting specific endpoints
189
+ - Retries add delay before rejection
190
+ - MongoDB model required for horizontal scaling
@@ -0,0 +1,102 @@
1
+ # URL Middleware
2
+
3
+ **File:** `mw/url/index.js`
4
+
5
+ **Order:** 8
6
+
7
+ The URL middleware parses the request URL and extracts service routing information.
8
+
9
+ ## Purpose
10
+
11
+ - Parses URL into components (service name, version, path)
12
+ - Validates service exists in registry
13
+ - Normalizes header and query parameters (key, access_token)
14
+ - Creates `req.soajs.controller.serviceParams` structure
15
+
16
+ ## Flow
17
+
18
+ ```
19
+ Incoming Request
20
+ │
21
+ ▼
22
+ ┌─────────────────┐
23
+ │ Ensure │ if (!req.soajs.controller)
24
+ │ Controller │ req.soajs.controller = {}
25
+ └────────┬────────┘
26
+ │
27
+ ▼
28
+ ┌─────────────────┐
29
+ │ Parse URL │ url.parse(req.url, true)
30
+ └────────┬────────┘
31
+ │
32
+ ▼
33
+ ┌─────────────────┐
34
+ │ Extract │ service_n, service_v, service_nv
35
+ │ Service Info │ serviceInfo, path
36
+ └────────┬────────┘
37
+ │
38
+ ├─── No service name? ──▶ Error 136
39
+ │
40
+ ├─── Service not in registry? ──▶ Error 130
41
+ │
42
+ ▼
43
+ ┌─────────────────┐
44
+ │ Normalize │ key, access_token from headers/query
45
+ │ Auth Params │
46
+ └────────┬────────┘
47
+ │
48
+ ▼
49
+ next()
50
+ ```
51
+
52
+ ## URL Parsing
53
+
54
+ **URL Format:** `/{service}/{version}/{path}`
55
+
56
+ | Component | Example | Description |
57
+ |-----------|---------|-------------|
58
+ | `service_n` | `oauth` | Service name |
59
+ | `service_v` | `1` | Service version (optional) |
60
+ | `service_nv` | `oauth/1` | Service with version |
61
+ | `path` | `/token` | API path |
62
+
63
+ **Examples:**
64
+ ```
65
+ /oauth/token → service: oauth, version: null, path: /token
66
+ /oauth/1/token → service: oauth, version: 1, path: /token
67
+ /urac/3/user/login → service: urac, version: 3, path: /user/login
68
+ ```
69
+
70
+ ## Properties Set
71
+
72
+ | Property | Description |
73
+ |----------|-------------|
74
+ | `req.soajs.controller.serviceParams.service_n` | Service name |
75
+ | `req.soajs.controller.serviceParams.service_v` | Service version |
76
+ | `req.soajs.controller.serviceParams.service_nv` | Service with version |
77
+ | `req.soajs.controller.serviceParams.serviceInfo` | URL path segments array |
78
+ | `req.soajs.controller.serviceParams.parsedUrl` | Full parsed URL object |
79
+ | `req.query` | Query parameters |
80
+
81
+ ## Auth Parameter Normalization
82
+
83
+ The middleware normalizes authentication parameters:
84
+
85
+ 1. **Key:** `req.headers.key` ← `req.headers.key || req.query.key`
86
+ 2. **Access Token:** `req.query.access_token` ←
87
+ - `req.query.access_token`
88
+ - `req.headers.access_token`
89
+ - Bearer token from `Authorization` header
90
+
91
+ ## Error Codes
92
+
93
+ | Code | Description |
94
+ |------|-------------|
95
+ | 130 | Service not found in registry |
96
+ | 136 | Empty or missing service name |
97
+
98
+ ## Usage Notes
99
+
100
+ - Throws TypeError if SOAJS middleware hasn't run first
101
+ - Special handling for `soajs` service name (gateway routes)
102
+ - Authorization header is deleted after extracting Bearer token
@@ -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 |