@stratum-hq/sdk 1.1.0 → 1.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.
package/README.md CHANGED
@@ -5,7 +5,7 @@ HTTP client, LRU cache, and Express/Fastify middleware for the [Stratum](https:/
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @stratum-hq/sdk @stratum-hq/core
8
+ npm install @stratum-hq/sdk @stratum-hq/core jsonwebtoken
9
9
  ```
10
10
 
11
11
  ## Quick Start
@@ -18,11 +18,19 @@ const s = stratum({
18
18
  apiKey: "sk_live_your_key",
19
19
  });
20
20
 
21
+ // The tenant binding comes from a signed token, so the server does not start
22
+ // without the key that verifies it. Without jwtSecret, the middleware reads
23
+ // the tenant from the X-Tenant-ID header instead.
24
+ const jwtSecret = process.env.JWT_SECRET;
25
+ if (!jwtSecret) {
26
+ throw new Error("JWT_SECRET is required to verify bearer tokens.");
27
+ }
28
+
21
29
  // Express
22
- app.use(s.middleware({ jwtClaimPath: "tenant_id" }));
30
+ app.use(s.middleware({ jwtClaimPath: "tenant_id", jwtSecret }));
23
31
 
24
32
  // Fastify
25
- app.register(s.plugin({ jwtClaimPath: "tenant_id" }));
33
+ app.register(s.plugin({ jwtClaimPath: "tenant_id", jwtSecret }));
26
34
 
27
35
  // Direct client access
28
36
  const ctx = await s.client.resolveTenant("tenant-uuid");
@@ -39,10 +47,14 @@ const client = new StratumClient({
39
47
  cache: { enabled: true, ttlMs: 60000, maxSize: 100 },
40
48
  });
41
49
 
50
+ const jwtSecret = process.env.JWT_SECRET;
51
+ if (!jwtSecret) {
52
+ throw new Error("JWT_SECRET is required to verify bearer tokens.");
53
+ }
54
+
42
55
  app.use(expressMiddleware(client, {
43
56
  jwtClaimPath: "tenant_id",
44
- jwtSecret: process.env.JWT_SECRET,
45
- headerName: "X-Tenant-ID",
57
+ jwtSecret,
46
58
  }));
47
59
 
48
60
  app.get("/data", (req, res) => {
@@ -61,16 +73,65 @@ JWT resolution activates only when `jwtSecret` or `jwtVerify` is provided; other
61
73
 
62
74
  `jwtSecret` verifies HS256 tokens with [`jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken), an optional peer dependency: install it alongside the SDK (`npm install jsonwebtoken`) or pass `jwtVerify` instead. The middleware throws at construction if `jwtSecret` is set and `jsonwebtoken` cannot be loaded.
63
75
 
76
+ Set `jwtAudience` and/or `jwtIssuer` to bind tokens to your application: a verified token whose `aud` (or `iss`) claim does not match is rejected with `401 INVALID_TOKEN`. Both checks apply to `jwtSecret` and `jwtVerify`.
77
+
64
78
  `headerName` replaces the default `X-Tenant-ID` header: when it is set, only that header is read.
65
79
 
80
+ ## Archive or purge a tenant
81
+
82
+ `archiveTenant` and `purgeTenant` do different things. Choose the correct one before you call it.
83
+
84
+ - `archiveTenant(id)` is a soft delete. The tenant row and its data stay in the database, and the archive is reversible.
85
+ - `purgeTenant(id)` permanently deletes the tenant and its data (GDPR Article 17). You cannot undo a purge. The API key must have the `admin` scope, and the tenant must have no children. For a tenant with its own schema or database, the control plane also drops that schema or database. Rows in your own tables that share a database with other tenants stay: delete them yourself.
86
+
87
+ `deleteTenant(id)` is deprecated. It sends the same request as `archiveTenant`, so it does not remove data.
88
+
66
89
  ## Error Handling
67
90
 
68
91
  The SDK throws typed errors from `@stratum-hq/core`:
69
92
 
70
93
  ```typescript
71
- import { TenantNotFoundError, UnauthorizedError } from "@stratum-hq/core";
94
+ import {
95
+ ForbiddenError,
96
+ RegionInUseError,
97
+ RegionNotActiveError,
98
+ RegionNotFoundError,
99
+ TenantArchivedError,
100
+ TenantNotFoundError,
101
+ TenantSuspendedError,
102
+ UnauthorizedError,
103
+ ValidationError,
104
+ WebhookNotFoundError,
105
+ } from "@stratum-hq/core";
72
106
  ```
73
107
 
108
+ | Control plane response | Error |
109
+ |---|---|
110
+ | 400 `VALIDATION_ERROR` | `ValidationError`, with the issues in `details.issues` |
111
+ | 400, any other code | `Error`, with the control plane's message |
112
+ | 401 | `UnauthorizedError` |
113
+ | 403 `TENANT_SUSPENDED` | `TenantSuspendedError` |
114
+ | 403, any other code | `ForbiddenError` |
115
+ | 404 `TENANT_NOT_FOUND` | `TenantNotFoundError` |
116
+ | 404 `WEBHOOK_NOT_FOUND` | `WebhookNotFoundError` |
117
+ | 404 `REGION_NOT_FOUND` | `RegionNotFoundError` |
118
+ | 404, any other code | `Error`, with the control plane's message |
119
+ | 409 `REGION_IN_USE` | `RegionInUseError`, with the region ID in `details.region_id` |
120
+ | 409 `REGION_NOT_ACTIVE` | `RegionNotActiveError`, with the region ID in `details.region_id`. Only `POST /api/v1/tenants/{id}/migrate-region` sends this code, and the SDK has no method for that route yet. |
121
+ | 410 `TENANT_ARCHIVED` | `TenantArchivedError` |
122
+
123
+ An API key that is scoped to a tenant gets `ForbiddenError` (403 `FORBIDDEN`) for a descendant that is suspended or archived, not `TenantSuspendedError` or `TenantArchivedError`. An API key without the `admin` scope gets `ForbiddenError` from an admin operation, for example `purgeTenant`.
124
+
125
+ The middleware answers these tenant errors with 404, 403, or 410, for the caller's tenant and for an impersonation target, and does not call `onError` for them. A control plane timeout gets 504 `CONTROL_PLANE_TIMEOUT`. An `UnauthorizedError` for the SDK's own API key gets 500 `CONTROL_PLANE_AUTH_FAILED` and a `console.error` line. The middleware calls `onError` for these two. Other errors go to your framework's error handler. Other adapters can use the same mapping: import `tenantErrorResponse` and `controlPlaneErrorResponse`.
126
+
127
+ Each control plane request has a time limit of `timeoutMs` milliseconds (default 10000). A request that takes longer rejects with a `TimeoutError` `DOMException`. The value must be an integer from 1 to 4294967295, or `Infinity` to turn the time limit off. Any other value makes the constructor throw a `RangeError`:
128
+
129
+ ```typescript
130
+ const client = new StratumClient({ controlPlaneUrl, apiKey, timeoutMs: 5000 });
131
+ ```
132
+
133
+ A timeout does not mean that the operation failed. If `purgeTenant` times out, the purge can still complete. Call `getTenant(id)` to find out.
134
+
74
135
  ## Links
75
136
 
76
137
  - Documentation: https://docs.stratum-hq.org/packages/sdk/
package/dist/client.d.ts CHANGED
@@ -8,6 +8,16 @@ export interface StratumClientOptions {
8
8
  ttlMs?: number;
9
9
  maxSize?: number;
10
10
  };
11
+ /**
12
+ * Time limit in milliseconds for each control plane request, including the
13
+ * response body. A request that exceeds it rejects with a `TimeoutError`
14
+ * DOMException. Default: 10000.
15
+ *
16
+ * The value must be an integer from 1 to 4294967295, or `Infinity`.
17
+ * `Infinity` turns the time limit off. Any other value makes the
18
+ * constructor throw a `RangeError`.
19
+ */
20
+ timeoutMs?: number;
11
21
  }
12
22
  export declare class StratumClient {
13
23
  private readonly baseUrl;
@@ -15,6 +25,7 @@ export declare class StratumClient {
15
25
  private readonly regionUrl;
16
26
  private readonly cache;
17
27
  private readonly cacheEnabled;
28
+ private readonly timeoutMs;
18
29
  constructor(options: StratumClientOptions);
19
30
  private fetch;
20
31
  resolveTenant(tenantId: string): Promise<ResolvedTenantContext>;
@@ -24,7 +35,34 @@ export declare class StratumClient {
24
35
  updateTenant(tenantId: string, input: UpdateTenantInput): Promise<TenantNode>;
25
36
  moveTenant(tenantId: string, input: MoveTenantInput): Promise<TenantNode>;
26
37
  archiveTenant(tenantId: string): Promise<void>;
38
+ /**
39
+ * Archive the tenant. This is a soft delete, and it is identical to `archiveTenant`.
40
+ *
41
+ * The tenant row and its data stay in the database, and the archive is reversible.
42
+ * To remove the tenant data permanently, call `purgeTenant`.
43
+ *
44
+ * @deprecated The name suggests that the data is removed. Use `archiveTenant` for
45
+ * a soft delete, or `purgeTenant` for an irreversible hard delete.
46
+ */
27
47
  deleteTenant(tenantId: string): Promise<void>;
48
+ /**
49
+ * Permanently remove the tenant and its Stratum records (GDPR Article 17). You cannot undo this.
50
+ *
51
+ * The control plane deletes the tenant row and the tenant's records in the Stratum tables:
52
+ * config, permissions, API keys, roles, webhooks, consent records and audit logs.
53
+ * For a tenant with its own schema or database, it also drops that schema or database.
54
+ * For a pending tenant, the purge removes the records and never drops storage.
55
+ * Rows in your own tables that share a database with other tenants stay; delete them yourself.
56
+ * The API key must have the `admin` scope.
57
+ *
58
+ * @param tenantId - The id of the tenant to purge. The tenant must have no children.
59
+ * @returns A promise that rejects when the control plane refuses the purge, for example
60
+ * because the tenant has children, or with `ForbiddenError` because the API key does not
61
+ * have the `admin` scope. A rejection with a `TimeoutError` does not mean that the purge
62
+ * failed: the control plane can complete it after the client stops waiting. Call
63
+ * `getTenant` to find out whether the tenant still exists.
64
+ */
65
+ purgeTenant(tenantId: string): Promise<void>;
28
66
  invalidateCache(tenantId: string): void;
29
67
  clearCache(): void;
30
68
  createWebhook(input: CreateWebhookInput): Promise<Webhook>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -3,6 +3,74 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StratumClient = void 0;
4
4
  const core_1 = require("@stratum-hq/core");
5
5
  const cache_js_1 = require("./cache.js");
6
+ const DEFAULT_TIMEOUT_MS = 10_000;
7
+ // The largest delay that AbortSignal.timeout accepts.
8
+ const MAX_TIMEOUT_MS = 4_294_967_295;
9
+ function validTimeoutMs(value) {
10
+ if (value === Number.POSITIVE_INFINITY)
11
+ return value;
12
+ if (!Number.isInteger(value) || value < 1 || value > MAX_TIMEOUT_MS) {
13
+ throw new RangeError(`timeoutMs must be an integer from 1 to ${MAX_TIMEOUT_MS}, or Infinity to turn the time limit off. Received ${value}`);
14
+ }
15
+ return value;
16
+ }
17
+ /**
18
+ * Give a typed error the control plane's own message. The core error
19
+ * constructors add a prefix, and the control plane message already has it.
20
+ */
21
+ function withMessage(err, message) {
22
+ if (message)
23
+ err.message = message;
24
+ return err;
25
+ }
26
+ /**
27
+ * Map a failed control plane response to the core error class for its status
28
+ * and error code. A response without a typed error becomes a plain Error.
29
+ */
30
+ function responseError(status, body) {
31
+ // Fastify's default 404 body has a string `error`, so it has no code.
32
+ const error = typeof body.error === "object" && body.error !== null ? body.error : undefined;
33
+ const code = error?.code;
34
+ const message = error?.message;
35
+ const rawTenantId = error?.details?.tenant_id;
36
+ const tenantId = typeof rawTenantId === "string" ? rawTenantId : "unknown";
37
+ const rawRegionId = error?.details?.region_id;
38
+ const regionId = typeof rawRegionId === "string" ? rawRegionId : "unknown";
39
+ if (status === 400 && code === core_1.ErrorCode.VALIDATION_ERROR) {
40
+ const details = isObject(error?.details) ? error.details : undefined;
41
+ const legacyIssues = error?.issues;
42
+ // An older control plane sends the issues only in the deprecated error.issues field.
43
+ if (!Array.isArray(details?.issues) && Array.isArray(legacyIssues)) {
44
+ return new core_1.ValidationError(message ?? "Validation failed", { ...details, issues: legacyIssues });
45
+ }
46
+ return new core_1.ValidationError(message ?? "Validation failed", details);
47
+ }
48
+ // Every route can answer 404, so only the error code tells what is missing.
49
+ if (status === 404 && code === core_1.ErrorCode.TENANT_NOT_FOUND) {
50
+ return withMessage(new core_1.TenantNotFoundError(tenantId), message);
51
+ }
52
+ if (status === 404 && code === core_1.ErrorCode.WEBHOOK_NOT_FOUND) {
53
+ return withMessage(new core_1.WebhookNotFoundError("unknown"), message);
54
+ }
55
+ if (status === 404 && code === core_1.ErrorCode.REGION_NOT_FOUND) {
56
+ return withMessage(new core_1.RegionNotFoundError(regionId), message);
57
+ }
58
+ if (status === 409 && code === core_1.ErrorCode.REGION_IN_USE) {
59
+ return withMessage(new core_1.RegionInUseError(regionId), message);
60
+ }
61
+ if (status === 409 && code === core_1.ErrorCode.REGION_NOT_ACTIVE) {
62
+ return withMessage(new core_1.RegionNotActiveError(regionId), message);
63
+ }
64
+ if (status === 403) {
65
+ return code === core_1.ErrorCode.TENANT_SUSPENDED
66
+ ? withMessage(new core_1.TenantSuspendedError(tenantId), message)
67
+ : new core_1.ForbiddenError(message);
68
+ }
69
+ if (status === 410 && code === core_1.ErrorCode.TENANT_ARCHIVED) {
70
+ return withMessage(new core_1.TenantArchivedError(tenantId), message);
71
+ }
72
+ return new Error(message ?? `HTTP ${status}`);
73
+ }
6
74
  /**
7
75
  * Encode an ID for use as a single URL path segment. Dot segments are refused
8
76
  * because URL parsing would resolve them against the surrounding path.
@@ -43,11 +111,13 @@ class StratumClient {
43
111
  regionUrl;
44
112
  cache;
45
113
  cacheEnabled;
114
+ timeoutMs;
46
115
  constructor(options) {
47
116
  this.baseUrl = options.controlPlaneUrl.replace(/\/$/, "");
48
117
  this.apiKey = options.apiKey;
49
118
  this.regionUrl = options.regionUrl?.replace(/\/$/, "");
50
119
  this.cacheEnabled = options.cache?.enabled !== false;
120
+ this.timeoutMs = validTimeoutMs(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
51
121
  this.cache = new cache_js_1.LRUCache({
52
122
  ttlMs: options.cache?.ttlMs,
53
123
  maxSize: options.cache?.maxSize,
@@ -57,8 +127,10 @@ class StratumClient {
57
127
  const url = `${this.baseUrl}${path}`;
58
128
  const response = await globalThis.fetch(url, {
59
129
  ...init,
130
+ signal: this.timeoutMs === Number.POSITIVE_INFINITY ? undefined : AbortSignal.timeout(this.timeoutMs),
60
131
  headers: {
61
- "Content-Type": "application/json",
132
+ // The control plane rejects the JSON content type on an empty body.
133
+ ...(init?.body !== undefined ? { "Content-Type": "application/json" } : {}),
62
134
  "X-API-Key": this.apiKey,
63
135
  ...init?.headers,
64
136
  },
@@ -67,12 +139,8 @@ class StratumClient {
67
139
  if (response.status === 401) {
68
140
  throw new core_1.UnauthorizedError("Invalid or missing API key");
69
141
  }
70
- if (response.status === 404) {
71
- const body = await response.json().catch(() => ({}));
72
- throw new core_1.TenantNotFoundError(body?.error?.message ?? "unknown");
73
- }
74
142
  const body = await response.json().catch(() => ({}));
75
- throw new Error(body?.error?.message ?? `HTTP ${response.status}`);
143
+ throw responseError(response.status, body ?? {});
76
144
  }
77
145
  if (response.status === 204)
78
146
  return undefined;
@@ -134,12 +202,49 @@ class StratumClient {
134
202
  });
135
203
  this.cache.invalidate(cacheKey(tenantId));
136
204
  }
205
+ /**
206
+ * Archive the tenant. This is a soft delete, and it is identical to `archiveTenant`.
207
+ *
208
+ * The tenant row and its data stay in the database, and the archive is reversible.
209
+ * To remove the tenant data permanently, call `purgeTenant`.
210
+ *
211
+ * @deprecated The name suggests that the data is removed. Use `archiveTenant` for
212
+ * a soft delete, or `purgeTenant` for an irreversible hard delete.
213
+ */
137
214
  async deleteTenant(tenantId) {
138
215
  await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}`, {
139
216
  method: "DELETE",
140
217
  });
141
218
  this.cache.invalidate(cacheKey(tenantId));
142
219
  }
220
+ /**
221
+ * Permanently remove the tenant and its Stratum records (GDPR Article 17). You cannot undo this.
222
+ *
223
+ * The control plane deletes the tenant row and the tenant's records in the Stratum tables:
224
+ * config, permissions, API keys, roles, webhooks, consent records and audit logs.
225
+ * For a tenant with its own schema or database, it also drops that schema or database.
226
+ * For a pending tenant, the purge removes the records and never drops storage.
227
+ * Rows in your own tables that share a database with other tenants stay; delete them yourself.
228
+ * The API key must have the `admin` scope.
229
+ *
230
+ * @param tenantId - The id of the tenant to purge. The tenant must have no children.
231
+ * @returns A promise that rejects when the control plane refuses the purge, for example
232
+ * because the tenant has children, or with `ForbiddenError` because the API key does not
233
+ * have the `admin` scope. A rejection with a `TimeoutError` does not mean that the purge
234
+ * failed: the control plane can complete it after the client stops waiting. Call
235
+ * `getTenant` to find out whether the tenant still exists.
236
+ */
237
+ async purgeTenant(tenantId) {
238
+ try {
239
+ await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}/purge`, {
240
+ method: "POST",
241
+ });
242
+ }
243
+ finally {
244
+ // A failed request can still have purged the tenant, so the cached context goes either way.
245
+ this.cache.invalidate(cacheKey(tenantId));
246
+ }
247
+ }
143
248
  invalidateCache(tenantId) {
144
249
  this.cache.invalidate(cacheKey(tenantId));
145
250
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -24,6 +24,8 @@ export type { StratumClientOptions } from "./client.js";
24
24
  export { getTenantContext, runWithTenantContext, setTenantContext } from "./context.js";
25
25
  export { expressMiddleware } from "./middleware/express.js";
26
26
  export { fastifyPlugin } from "./middleware/fastify.js";
27
+ export { tenantErrorResponse, controlPlaneErrorResponse } from "./middleware/tenant-errors.js";
28
+ export type { TenantErrorResponse } from "./middleware/tenant-errors.js";
27
29
  export { resolveFromHeader } from "./resolvers/header.js";
28
30
  export { resolveFromJwt, assertJwtSupport } from "./resolvers/jwt.js";
29
31
  export { resolveTenantId } from "./resolvers/resolve.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,OAAO,CAAC,OAAO,EAAE,oBAAoB;;wBAI7B,iBAAiB;;;;;;;;;;oBACrB,iBAAiB,eAEpB,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,SACrC,OAAO,QACR,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;;;EAShD;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACnB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,OAAO,CAAC,OAAO,EAAE,oBAAoB;;wBAI7B,iBAAiB;;;;;;;;;;oBACrB,iBAAiB,eAEpB,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,SACrC,OAAO,QACR,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;;;EAShD;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC/F,YAAY,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACnB,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveTenantId = exports.assertJwtSupport = exports.resolveFromJwt = exports.resolveFromHeader = exports.fastifyPlugin = exports.expressMiddleware = exports.setTenantContext = exports.runWithTenantContext = exports.getTenantContext = exports.StratumClient = void 0;
3
+ exports.resolveTenantId = exports.assertJwtSupport = exports.resolveFromJwt = exports.resolveFromHeader = exports.controlPlaneErrorResponse = exports.tenantErrorResponse = exports.fastifyPlugin = exports.expressMiddleware = exports.setTenantContext = exports.runWithTenantContext = exports.getTenantContext = exports.StratumClient = void 0;
4
4
  exports.stratum = stratum;
5
5
  const client_js_1 = require("./client.js");
6
6
  const express_js_1 = require("./middleware/express.js");
@@ -32,6 +32,9 @@ var express_js_2 = require("./middleware/express.js");
32
32
  Object.defineProperty(exports, "expressMiddleware", { enumerable: true, get: function () { return express_js_2.expressMiddleware; } });
33
33
  var fastify_js_2 = require("./middleware/fastify.js");
34
34
  Object.defineProperty(exports, "fastifyPlugin", { enumerable: true, get: function () { return fastify_js_2.fastifyPlugin; } });
35
+ var tenant_errors_js_1 = require("./middleware/tenant-errors.js");
36
+ Object.defineProperty(exports, "tenantErrorResponse", { enumerable: true, get: function () { return tenant_errors_js_1.tenantErrorResponse; } });
37
+ Object.defineProperty(exports, "controlPlaneErrorResponse", { enumerable: true, get: function () { return tenant_errors_js_1.controlPlaneErrorResponse; } });
35
38
  var header_js_1 = require("./resolvers/header.js");
36
39
  Object.defineProperty(exports, "resolveFromHeader", { enumerable: true, get: function () { return header_js_1.resolveFromHeader; } });
37
40
  var jwt_js_1 = require("./resolvers/jwt.js");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,0BAkBC;AAzBD,2CAA4C;AAE5C,wDAA4D;AAC5D,wDAAwD;AACxD,6CAAsE;AAGtE,SAAgB,OAAO,CAAC,OAA6B;IACnD,MAAM,MAAM,GAAG,IAAI,yBAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,CAAC,IAAwB,EAAE,EAAE,CAAC,IAAA,8BAAiB,EAAC,MAAM,EAAE,IAAI,CAAC;QACzE,MAAM,EAAE,CAAC,IAAwB,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,CACb,OAA4C,EAC5C,KAAc,EACd,IAAyC,EACzC,EAAE,CAAC,IAAA,0BAAa,EAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;YACvD,8DAA8D;YAC7D,MAA6C,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,IAAI,CAAC;YACnF,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,gBAAgB,EAAhB,6BAAgB;QAChB,oBAAoB,EAApB,iCAAoB;KACrB,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAEtB,2CAAwF;AAA/E,8GAAA,gBAAgB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACjE,sDAA4D;AAAnD,+GAAA,iBAAiB,OAAA;AAC1B,sDAAwD;AAA/C,2GAAA,aAAa,OAAA;AACtB,mDAA0D;AAAjD,8GAAA,iBAAiB,OAAA;AAC1B,6CAAsE;AAA7D,wGAAA,cAAc,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AACzC,qDAAyD;AAAhD,6GAAA,eAAe,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,0BAkBC;AAzBD,2CAA4C;AAE5C,wDAA4D;AAC5D,wDAAwD;AACxD,6CAAsE;AAGtE,SAAgB,OAAO,CAAC,OAA6B;IACnD,MAAM,MAAM,GAAG,IAAI,yBAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,CAAC,IAAwB,EAAE,EAAE,CAAC,IAAA,8BAAiB,EAAC,MAAM,EAAE,IAAI,CAAC;QACzE,MAAM,EAAE,CAAC,IAAwB,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,CACb,OAA4C,EAC5C,KAAc,EACd,IAAyC,EACzC,EAAE,CAAC,IAAA,0BAAa,EAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;YACvD,8DAA8D;YAC7D,MAA6C,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,IAAI,CAAC;YACnF,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,gBAAgB,EAAhB,6BAAgB;QAChB,oBAAoB,EAApB,iCAAoB;KACrB,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAEtB,2CAAwF;AAA/E,8GAAA,gBAAgB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACjE,sDAA4D;AAAnD,+GAAA,iBAAiB,OAAA;AAC1B,sDAAwD;AAA/C,2GAAA,aAAa,OAAA;AACtB,kEAA+F;AAAtF,uHAAA,mBAAmB,OAAA;AAAE,6HAAA,yBAAyB,OAAA;AAEvD,mDAA0D;AAAjD,8GAAA,iBAAiB,OAAA;AAC1B,6CAAsE;AAA7D,wGAAA,cAAc,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AACzC,qDAAyD;AAAhD,6GAAA,eAAe,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,KAAK,kBAAkB,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,iBAAiB,IAEpE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAyE9F"}
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQrD,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,KAAK,kBAAkB,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,iBAAiB,IAEpE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CA4F9F"}
@@ -1,13 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.expressMiddleware = expressMiddleware;
4
- const core_1 = require("@stratum-hq/core");
5
4
  const context_js_1 = require("../context.js");
6
5
  const jwt_js_1 = require("../resolvers/jwt.js");
7
6
  const resolve_js_1 = require("../resolvers/resolve.js");
7
+ const tenant_errors_js_1 = require("./tenant-errors.js");
8
8
  function expressMiddleware(client, options) {
9
9
  (0, jwt_js_1.assertJwtSupport)(options);
10
10
  return async (req, res, next) => {
11
+ /** Send the response for a known resolution error. Return false for any other error. */
12
+ const answerResolutionError = (err, tenantId) => {
13
+ const response = (0, tenant_errors_js_1.tenantErrorResponse)(err, tenantId);
14
+ if (response) {
15
+ res.status(response.status).json(response.body);
16
+ return true;
17
+ }
18
+ const failure = (0, tenant_errors_js_1.controlPlaneErrorResponse)(err);
19
+ if (!failure)
20
+ return false;
21
+ if (options?.onError && err instanceof Error) {
22
+ options.onError(err, req);
23
+ }
24
+ res.status(failure.status).json(failure.body);
25
+ return true;
26
+ };
11
27
  try {
12
28
  // Resolve tenant ID: JWT → header → custom resolvers
13
29
  const resolution = await (0, resolve_js_1.resolveTenantId)(req, options);
@@ -25,10 +41,8 @@ function expressMiddleware(client, options) {
25
41
  context = await client.resolveTenant(tenantId);
26
42
  }
27
43
  catch (err) {
28
- if (err instanceof core_1.TenantNotFoundError) {
29
- res.status(404).json({ error: { code: "TENANT_NOT_FOUND", message: `Tenant not found: ${tenantId}` } });
44
+ if (answerResolutionError(err, tenantId))
30
45
  return;
31
- }
32
46
  throw err;
33
47
  }
34
48
  req.tenant = context;
@@ -49,7 +63,15 @@ function expressMiddleware(client, options) {
49
63
  return;
50
64
  }
51
65
  // Resolve the impersonated tenant's context
52
- const impersonatedContext = await client.resolveTenant(impersonateTenantId);
66
+ let impersonatedContext;
67
+ try {
68
+ impersonatedContext = await client.resolveTenant(impersonateTenantId);
69
+ }
70
+ catch (err) {
71
+ if (answerResolutionError(err, impersonateTenantId))
72
+ return;
73
+ throw err;
74
+ }
53
75
  req.tenant = impersonatedContext;
54
76
  req.impersonating = true;
55
77
  req.originalTenantId = tenantId;
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":";;AAsBA,8CA2EC;AAjGD,2CAAuD;AAGvD,8CAAqD;AACrD,gDAAuD;AACvD,wDAA0D;AAiB1D,SAAgB,iBAAiB,CAAC,MAAqB,EAAE,OAA2B;IAClF,IAAA,yBAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,OAAO,KAAK,EAAE,GAAuB,EAAE,GAAwB,EAAE,IAAY,EAAiB,EAAE;QAC9F,IAAI,CAAC;YACH,qDAAqD;YACrD,MAAM,UAAU,GAAG,MAAM,IAAA,4BAAe,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAEvD,IAAI,UAAU,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;gBAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,oCAAoC,EAAE,EAAE,CAAC,CAAC;gBAC1G,OAAO;YACT,CAAC;YAED,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,8CAA8C,EAAE,EAAE,CAAC,CAAC;gBACrH,OAAO;YACT,CAAC;YAED,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;YAErC,IAAI,OAAO,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,0BAAmB,EAAE,CAAC;oBACvC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,qBAAqB,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;oBACxG,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC;YACrB,GAAG,CAAC,aAAa,GAAG,KAAK,CAAC;YAE1B,uDAAuD;YACvD,IAAI,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;gBACpC,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,UAAU,IAAI,sBAAsB,CAAC;gBACrF,MAAM,mBAAmB,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAuB,CAAC;gBAEjG,IAAI,mBAAmB,IAAI,mBAAmB,KAAK,QAAQ,EAAE,CAAC;oBAC5D,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;oBAC7F,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;4BACnB,KAAK,EAAE;gCACL,IAAI,EAAE,sBAAsB;gCAC5B,OAAO,EAAE,2CAA2C;6BACrD;yBACF,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,4CAA4C;oBAC5C,MAAM,mBAAmB,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;oBAC5E,GAAG,CAAC,MAAM,GAAG,mBAAmB,CAAC;oBACjC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;oBACzB,GAAG,CAAC,gBAAgB,GAAG,QAAQ,CAAC;oBAEhC,OAAO,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;oBAE1E,IAAA,iCAAoB,EAAC,mBAAmB,EAAE,GAAG,EAAE;wBAC7C,IAAI,EAAE,CAAC;oBACT,CAAC,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;YACH,CAAC;YAED,IAAA,iCAAoB,EAAC,OAAO,EAAE,GAAG,EAAE;gBACjC,IAAI,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,OAAO,EAAE,OAAO,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;gBAC7C,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../src/middleware/fastify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,UAAU,gBAAgB;IACxB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrD;AAED,UAAU,WAAW;IACnB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,OAAO,CACL,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GACpF,IAAI,CAAC;CACT;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG,iBAAiB,EACtD,IAAI,EAAE,MAAM,GACX,IAAI,CA+EN"}
1
+ {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../src/middleware/fastify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQrD,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,UAAU,gBAAgB;IACxB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrD;AAED,UAAU,WAAW;IACnB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,OAAO,CACL,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GACpF,IAAI,CAAC;CACT;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG,iBAAiB,EACtD,IAAI,EAAE,MAAM,GACX,IAAI,CAkGN"}
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fastifyPlugin = fastifyPlugin;
4
- const core_1 = require("@stratum-hq/core");
5
4
  const context_js_1 = require("../context.js");
6
5
  const jwt_js_1 = require("../resolvers/jwt.js");
7
6
  const resolve_js_1 = require("../resolvers/resolve.js");
7
+ const tenant_errors_js_1 = require("./tenant-errors.js");
8
8
  function fastifyPlugin(fastify, options, done) {
9
9
  const { client, ...middlewareOptions } = options;
10
10
  (0, jwt_js_1.assertJwtSupport)(middlewareOptions);
@@ -12,6 +12,22 @@ function fastifyPlugin(fastify, options, done) {
12
12
  fastify.decorateRequest("impersonating", false);
13
13
  fastify.decorateRequest("originalTenantId", null);
14
14
  fastify.addHook("onRequest", (request, reply, done) => {
15
+ /** Send the response for a known resolution error. Return false for any other error. */
16
+ const answerResolutionError = (err, tenantId) => {
17
+ const response = (0, tenant_errors_js_1.tenantErrorResponse)(err, tenantId);
18
+ if (response) {
19
+ reply.status(response.status).send(response.body);
20
+ return true;
21
+ }
22
+ const failure = (0, tenant_errors_js_1.controlPlaneErrorResponse)(err);
23
+ if (!failure)
24
+ return false;
25
+ if (middlewareOptions.onError && err instanceof Error) {
26
+ middlewareOptions.onError(err, request);
27
+ }
28
+ reply.status(failure.status).send(failure.body);
29
+ return true;
30
+ };
15
31
  const resolveAndRun = async () => {
16
32
  // Resolve tenant ID: JWT → header → custom resolvers
17
33
  const resolution = await (0, resolve_js_1.resolveTenantId)(request, middlewareOptions);
@@ -29,10 +45,8 @@ function fastifyPlugin(fastify, options, done) {
29
45
  context = await client.resolveTenant(tenantId);
30
46
  }
31
47
  catch (err) {
32
- if (err instanceof core_1.TenantNotFoundError) {
33
- reply.status(404).send({ error: { code: "TENANT_NOT_FOUND", message: `Tenant not found: ${tenantId}` } });
48
+ if (answerResolutionError(err, tenantId))
34
49
  return;
35
- }
36
50
  if (middlewareOptions.onError && err instanceof Error) {
37
51
  middlewareOptions.onError(err, request);
38
52
  }
@@ -55,7 +69,15 @@ function fastifyPlugin(fastify, options, done) {
55
69
  });
56
70
  return;
57
71
  }
58
- const impersonatedContext = await client.resolveTenant(impersonateTenantId);
72
+ let impersonatedContext;
73
+ try {
74
+ impersonatedContext = await client.resolveTenant(impersonateTenantId);
75
+ }
76
+ catch (err) {
77
+ if (answerResolutionError(err, impersonateTenantId))
78
+ return;
79
+ throw err;
80
+ }
59
81
  request.tenant = impersonatedContext;
60
82
  request.impersonating = true;
61
83
  request.originalTenantId = tenantId;
@@ -1 +1 @@
1
- {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/middleware/fastify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/middleware/fastify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface TenantErrorResponse {
2
+ status: number;
3
+ body: {
4
+ error: {
5
+ code: string;
6
+ message: string;
7
+ };
8
+ };
9
+ }
10
+ /**
11
+ * Return the HTTP response for a tenant resolution error, or null when the
12
+ * error is not a known tenant error. The adapters send this response instead
13
+ * of passing the error on, where it would become a 500. A tenant error is a
14
+ * normal answer for the request, so the adapters do not call `onError` for it.
15
+ */
16
+ export declare function tenantErrorResponse(err: unknown, tenantId: string): TenantErrorResponse | null;
17
+ /**
18
+ * Return the HTTP response for a control plane failure during tenant
19
+ * resolution, or null for any other error.
20
+ *
21
+ * A timeout answers 504. A rejected SDK API key answers 500, because the
22
+ * fault is in the server configuration and not in the request. For a rejected
23
+ * key, this function also writes the cause to `console.error`, because the
24
+ * response body does not show it.
25
+ */
26
+ export declare function controlPlaneErrorResponse(err: unknown): TenantErrorResponse | null;
27
+ //# sourceMappingURL=tenant-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-errors.d.ts","sourceRoot":"","sources":["../../src/middleware/tenant-errors.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACpD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAc9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAiBlF"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tenantErrorResponse = tenantErrorResponse;
4
+ exports.controlPlaneErrorResponse = controlPlaneErrorResponse;
5
+ const core_1 = require("@stratum-hq/core");
6
+ /**
7
+ * Return the HTTP response for a tenant resolution error, or null when the
8
+ * error is not a known tenant error. The adapters send this response instead
9
+ * of passing the error on, where it would become a 500. A tenant error is a
10
+ * normal answer for the request, so the adapters do not call `onError` for it.
11
+ */
12
+ function tenantErrorResponse(err, tenantId) {
13
+ if (err instanceof core_1.TenantNotFoundError) {
14
+ return { status: 404, body: { error: { code: "TENANT_NOT_FOUND", message: `Tenant not found: ${tenantId}` } } };
15
+ }
16
+ if (err instanceof core_1.TenantSuspendedError) {
17
+ return { status: 403, body: { error: { code: "TENANT_SUSPENDED", message: `Tenant ${tenantId} is suspended` } } };
18
+ }
19
+ if (err instanceof core_1.TenantArchivedError) {
20
+ return { status: 410, body: { error: { code: "TENANT_ARCHIVED", message: `Tenant ${tenantId} is archived` } } };
21
+ }
22
+ if (err instanceof core_1.ForbiddenError) {
23
+ return { status: 403, body: { error: { code: "FORBIDDEN", message: `Access to tenant ${tenantId} is denied` } } };
24
+ }
25
+ return null;
26
+ }
27
+ /**
28
+ * Return the HTTP response for a control plane failure during tenant
29
+ * resolution, or null for any other error.
30
+ *
31
+ * A timeout answers 504. A rejected SDK API key answers 500, because the
32
+ * fault is in the server configuration and not in the request. For a rejected
33
+ * key, this function also writes the cause to `console.error`, because the
34
+ * response body does not show it.
35
+ */
36
+ function controlPlaneErrorResponse(err) {
37
+ if (err instanceof Error && err.name === "TimeoutError") {
38
+ return {
39
+ status: 504,
40
+ body: { error: { code: "CONTROL_PLANE_TIMEOUT", message: "The Stratum control plane did not respond in time" } },
41
+ };
42
+ }
43
+ if (err instanceof core_1.UnauthorizedError) {
44
+ console.error("[stratum] The control plane rejected the SDK API key (401). Check the apiKey option of StratumClient.");
45
+ return {
46
+ status: 500,
47
+ body: { error: { code: "CONTROL_PLANE_AUTH_FAILED", message: "Tenant resolution failed" } },
48
+ };
49
+ }
50
+ return null;
51
+ }
52
+ //# sourceMappingURL=tenant-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-errors.js","sourceRoot":"","sources":["../../src/middleware/tenant-errors.ts"],"names":[],"mappings":";;AAmBA,kDAcC;AAWD,8DAiBC;AA7DD,2CAM0B;AAO1B;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,GAAY,EAAE,QAAgB;IAChE,IAAI,GAAG,YAAY,0BAAmB,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,qBAAqB,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC;IAClH,CAAC;IACD,IAAI,GAAG,YAAY,2BAAoB,EAAE,CAAC;QACxC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,QAAQ,eAAe,EAAE,EAAE,EAAE,CAAC;IACpH,CAAC;IACD,IAAI,GAAG,YAAY,0BAAmB,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,QAAQ,cAAc,EAAE,EAAE,EAAE,CAAC;IAClH,CAAC;IACD,IAAI,GAAG,YAAY,qBAAc,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,oBAAoB,QAAQ,YAAY,EAAE,EAAE,EAAE,CAAC;IACpH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,yBAAyB,CAAC,GAAY;IACpD,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QACxD,OAAO;YACL,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,mDAAmD,EAAE,EAAE;SACjH,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,YAAY,wBAAiB,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CACX,uGAAuG,CACxG,CAAC;QACF,OAAO;YACL,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,OAAO,EAAE,0BAA0B,EAAE,EAAE;SAC5F,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,6 +1,10 @@
1
1
  export interface JwtResolverOptions {
2
2
  secret?: string;
3
3
  verify?: (token: string) => Record<string, unknown> | null;
4
+ /** When set, the verified token's `aud` claim must equal it or include it. */
5
+ audience?: string;
6
+ /** When set, the verified token's `iss` claim must equal it. */
7
+ issuer?: string;
4
8
  }
5
9
  /**
6
10
  * Throw if `jwtSecret` is configured without a `jwtVerify` function and the
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/resolvers/jwt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5D;AAkBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAQ5F;AAgBD;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,MAAoB,EAC/B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,mBAAmB,CAuCrB;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,MAAoB,EAC/B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,MAAM,GAAG,IAAI,CAGf"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/resolvers/jwt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3D,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6BD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAQ5F;AAgBD;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,MAAoB,EAC/B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,mBAAmB,CAwCrB;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,MAAoB,EAC/B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,MAAM,GAAG,IAAI,CAGf"}
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertJwtSupport = assertJwtSupport;
4
4
  exports.resolveJwtTenant = resolveJwtTenant;
5
5
  exports.resolveFromJwt = resolveFromJwt;
6
+ /** True when the claims satisfy the configured audience and issuer, if any. */
7
+ function matchesAudienceAndIssuer(claims, options) {
8
+ if (options?.audience !== undefined) {
9
+ const aud = claims["aud"];
10
+ const audiences = Array.isArray(aud) ? aud : [aud];
11
+ if (!audiences.includes(options.audience))
12
+ return false;
13
+ }
14
+ if (options?.issuer !== undefined && claims["iss"] !== options.issuer)
15
+ return false;
16
+ return true;
17
+ }
6
18
  /**
7
19
  * Load the optional `jsonwebtoken` peer dependency. Returns null only when the
8
20
  * module is not installed; any other load failure is rethrown.
@@ -74,6 +86,8 @@ function resolveJwtTenant(req, claimPath = "tenant_id", options) {
74
86
  }
75
87
  if (!claims)
76
88
  return { status: "invalid" };
89
+ if (!matchesAudienceAndIssuer(claims, options))
90
+ return { status: "invalid" };
77
91
  // Support dotted claim paths like "stratum.tenant_id"
78
92
  const segments = claimPath.split(".");
79
93
  let current = claims;
@@ -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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/resolvers/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAEhC;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuB5G"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/resolvers/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAEhC;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyB5G"}
@@ -17,6 +17,8 @@ async function resolveTenantId(req, options) {
17
17
  const jwt = (0, jwt_js_1.resolveJwtTenant)(req, options?.jwtClaimPath, {
18
18
  secret: options?.jwtSecret,
19
19
  verify: options?.jwtVerify,
20
+ audience: options?.jwtAudience,
21
+ issuer: options?.jwtIssuer,
20
22
  });
21
23
  if (jwt.status === "resolved")
22
24
  return { status: "resolved", tenantId: jwt.tenantId };
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/resolvers/resolve.ts"],"names":[],"mappings":";;AAuBA,0CAuBC;AA7CD,qCAA4C;AAC5C,2CAAgD;AAYhD;;;;;;;;GAQG;AACI,KAAK,UAAU,eAAe,CAAC,GAAY,EAAE,OAA2B;IAC7E,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,SAAS,CAAC,CAAC;IAExE,MAAM,GAAG,GAAG,IAAA,yBAAgB,EAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE;QACvD,MAAM,EAAE,OAAO,EAAE,SAAS;QAC1B,MAAM,EAAE,OAAO,EAAE,SAAS;KAC3B,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;IACrF,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAEjE,IAAI,CAAC,aAAa,IAAI,OAAO,EAAE,iBAAiB,EAAE,CAAC;QACjD,MAAM,UAAU,GAAG,IAAA,6BAAiB,EAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC/D,IAAI,UAAU;YAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,MAAM;gBAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/resolvers/resolve.ts"],"names":[],"mappings":";;AAuBA,0CAyBC;AA/CD,qCAA4C;AAC5C,2CAAgD;AAYhD;;;;;;;;GAQG;AACI,KAAK,UAAU,eAAe,CAAC,GAAY,EAAE,OAA2B;IAC7E,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,SAAS,CAAC,CAAC;IAExE,MAAM,GAAG,GAAG,IAAA,yBAAgB,EAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE;QACvD,MAAM,EAAE,OAAO,EAAE,SAAS;QAC1B,MAAM,EAAE,OAAO,EAAE,SAAS;QAC1B,QAAQ,EAAE,OAAO,EAAE,WAAW;QAC9B,MAAM,EAAE,OAAO,EAAE,SAAS;KAC3B,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;IACrF,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAEjE,IAAI,CAAC,aAAa,IAAI,OAAO,EAAE,iBAAiB,EAAE,CAAC;QACjD,MAAM,UAAU,GAAG,IAAA,6BAAiB,EAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC/D,IAAI,UAAU;YAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,MAAM;gBAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC"}
package/dist/types.d.ts CHANGED
@@ -9,6 +9,14 @@ export interface MiddlewareOptions {
9
9
  /** HS256 secret for JWT verification. Requires the optional `jsonwebtoken` peer dependency unless `jwtVerify` is given. */
10
10
  jwtSecret?: string;
11
11
  jwtVerify?: (token: string) => Record<string, unknown> | null;
12
+ /**
13
+ * When set, a verified token is accepted only if its `aud` claim equals this
14
+ * value (or, for an array, includes it). A token that fails the check is
15
+ * rejected with 401. Applies to both `jwtSecret` and `jwtVerify`.
16
+ */
17
+ jwtAudience?: string;
18
+ /** When set, a verified token is accepted only if its `iss` claim equals this value. */
19
+ jwtIssuer?: string;
12
20
  /**
13
21
  * When `jwtSecret` or `jwtVerify` is configured, the tenant header is ignored
14
22
  * unless this is true, so the verified JWT is the only tenant binding. A
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErJ,YAAY,EAAE,qBAAqB,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,CAAC;AAE7H,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,OAAO,uBAAuB,EAAE,cAAc,EAAE,CAAC;IAC7D,oGAAoG;IACpG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2HAA2H;IAC3H,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE;QACd,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACxG,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;KACxF,CAAC;CACH"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErJ,YAAY,EAAE,qBAAqB,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,CAAC;AAE7H,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,OAAO,uBAAuB,EAAE,cAAc,EAAE,CAAC;IAC7D,oGAAoG;IACpG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2HAA2H;IAC3H,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE;QACd,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACxG,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;KACxF,CAAC;CACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stratum-hq/sdk",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Stratum Node.js SDK for multi-tenant context propagation",
5
5
  "keywords": [
6
6
  "multi-tenancy",
@@ -40,8 +40,7 @@
40
40
  "registry": "https://registry.npmjs.org/"
41
41
  },
42
42
  "dependencies": {
43
- "@stratum-hq/core": "*",
44
- "lru-cache": "^10.2.0"
43
+ "@stratum-hq/core": "^1.5.0"
45
44
  },
46
45
  "devDependencies": {
47
46
  "@types/express": "^4.17.0",