@stratum-hq/sdk 1.3.0 → 1.4.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.
- package/README.md +6 -4
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/resolvers/jwt.js +1 -1
- package/dist/resolvers/jwt.js.map +1 -1
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
HTTP client, LRU cache, and Express/Fastify middleware for the [Stratum](https://github.com/stratum-hq/Stratum) control plane. Resolves tenant context from incoming requests and attaches it to the request object.
|
|
4
4
|
|
|
5
|
+
Read the documentation at [docs.stratum-hq.org/packages/sdk](https://docs.stratum-hq.org/packages/sdk/).
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -64,10 +66,10 @@ app.get("/data", (req, res) => {
|
|
|
64
66
|
|
|
65
67
|
## Features
|
|
66
68
|
|
|
67
|
-
- **`StratumClient
|
|
68
|
-
- **`expressMiddleware` / `fastifyPlugin
|
|
69
|
-
- **AsyncLocalStorage context
|
|
70
|
-
- **Custom resolvers
|
|
69
|
+
- **`StratumClient`**: HTTP client for the control plane API (`resolveTenant`, `getTenantTree`, `createTenant`, `createWebhook`, `listRegions`, …) with a built-in LRU cache. Mutations made through the client invalidate affected entries (a move clears the whole cache); changes made elsewhere, such as a suspension or a config or permission change, are picked up when the entry expires, so the cache TTL (`cache.ttlMs`, default 60s) bounds how stale a context can be.
|
|
70
|
+
- **`expressMiddleware` / `fastifyPlugin`**: resolve the tenant from a JWT claim, `X-Tenant-ID` header, or custom resolvers (tried in that order), then populate `req.tenant`. Resolving a tenant needs only the `read` scope: give the app server a `read` key scoped to its tenant, which also resolves that tenant's descendants. In `resolved_config`, a sensitive value inherited from an ancestor arrives masked (`value: null`, `masked: true`) unless the key belongs to the tenant that set it.
|
|
71
|
+
- **AsyncLocalStorage context**: `getTenantContext()` and `runWithTenantContext()` make the resolved context available to services that never see the request object.
|
|
72
|
+
- **Custom resolvers**: supply async functions (e.g. subdomain- or query-based) via the `resolvers` option.
|
|
71
73
|
|
|
72
74
|
JWT resolution activates only when `jwtSecret` or `jwtVerify` is provided; otherwise Bearer tokens are ignored. When it is active, the verified JWT is the tenant binding: a Bearer token that fails verification is rejected with `401 INVALID_TOKEN`, and the tenant header is not read unless you set `trustTenantHeader: true`. If no tenant is found, the middleware returns `400 MISSING_TENANT`.
|
|
73
75
|
|
package/dist/context.js
CHANGED
|
@@ -18,7 +18,7 @@ function runWithTenantContext(context, fn) {
|
|
|
18
18
|
return exports.tenantStorage.run(context, fn);
|
|
19
19
|
}
|
|
20
20
|
function setTenantContext(context) {
|
|
21
|
-
// Bind the current store value
|
|
21
|
+
// Bind the current store value, for middleware entry points
|
|
22
22
|
exports.tenantStorage.enterWith(context);
|
|
23
23
|
}
|
|
24
24
|
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;AAMA,4CAMC;AAED,oDAEC;AAED,4CAGC;AArBD,uDAAqD;AACrD,2CAA8D;AAGjD,QAAA,aAAa,GAAG,IAAI,oCAAiB,EAAyB,CAAC;AAE5E,SAAgB,gBAAgB;IAC9B,MAAM,GAAG,GAAG,qBAAa,CAAC,QAAQ,EAAE,CAAC;IACrC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,iCAA0B,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,oBAAoB,CAAI,OAA8B,EAAE,EAAW;IACjF,OAAO,qBAAa,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAA8B;IAC7D,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;AAMA,4CAMC;AAED,oDAEC;AAED,4CAGC;AArBD,uDAAqD;AACrD,2CAA8D;AAGjD,QAAA,aAAa,GAAG,IAAI,oCAAiB,EAAyB,CAAC;AAE5E,SAAgB,gBAAgB;IAC9B,MAAM,GAAG,GAAG,qBAAa,CAAC,QAAQ,EAAE,CAAC;IACrC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,iCAA0B,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,oBAAoB,CAAI,OAA8B,EAAE,EAAW;IACjF,OAAO,qBAAa,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAA8B;IAC7D,4DAA4D;IAC5D,qBAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/resolvers/jwt.js
CHANGED
|
@@ -79,7 +79,7 @@ function resolveJwtTenant(req, claimPath = "tenant_id", options) {
|
|
|
79
79
|
claims = verifyWithJsonwebtoken(token, options.secret);
|
|
80
80
|
}
|
|
81
81
|
else {
|
|
82
|
-
// No secret or verify function provided
|
|
82
|
+
// No secret or verify function provided: refuse to trust unsigned tokens
|
|
83
83
|
console.warn("[stratum] JWT ignored: no jwtSecret or jwtVerify provided. " +
|
|
84
84
|
"Configure middleware options to enable JWT tenant resolution.");
|
|
85
85
|
return { status: "absent" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/resolvers/jwt.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/resolvers/jwt.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratum-hq/sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Multi-tenant context for Express and Fastify: tenant resolution middleware and HTTP client for the Stratum control plane",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multi-tenancy",
|
|
7
|
+
"multitenancy",
|
|
7
8
|
"multi-tenant",
|
|
8
9
|
"saas",
|
|
9
10
|
"tenant",
|
|
11
|
+
"tenant-isolation",
|
|
12
|
+
"express",
|
|
13
|
+
"express-middleware",
|
|
14
|
+
"fastify",
|
|
10
15
|
"context-propagation",
|
|
11
16
|
"middleware",
|
|
12
17
|
"node",
|
|
13
18
|
"typescript",
|
|
14
|
-
"express",
|
|
15
|
-
"fastify",
|
|
16
19
|
"stratum"
|
|
17
20
|
],
|
|
18
21
|
"main": "./dist/index.js",
|
|
@@ -40,7 +43,7 @@
|
|
|
40
43
|
"registry": "https://registry.npmjs.org/"
|
|
41
44
|
},
|
|
42
45
|
"dependencies": {
|
|
43
|
-
"@stratum-hq/core": "^1.
|
|
46
|
+
"@stratum-hq/core": "^1.6.0"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|
|
46
49
|
"@types/express": "^4.17.0",
|
|
@@ -53,7 +56,7 @@
|
|
|
53
56
|
},
|
|
54
57
|
"license": "MIT",
|
|
55
58
|
"author": "Christian Crank",
|
|
56
|
-
"homepage": "https://
|
|
59
|
+
"homepage": "https://docs.stratum-hq.org/packages/sdk/",
|
|
57
60
|
"bugs": "https://github.com/stratum-hq/Stratum/issues",
|
|
58
61
|
"engines": {
|
|
59
62
|
"node": ">=20.0.0"
|