@stratum-hq/nestjs 0.3.1 → 1.0.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/dist/stratum.decorator.d.ts +1 -1
- package/dist/stratum.decorator.js +1 -1
- package/package.json +10 -3
- package/dist/__tests__/stratum.test.d.ts +0 -2
- package/dist/__tests__/stratum.test.d.ts.map +0 -1
- package/dist/__tests__/stratum.test.js +0 -341
- package/dist/__tests__/stratum.test.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratum-hq/nestjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Stratum NestJS integration — StratumGuard, @Tenant() decorator, and StratumModule",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multi-tenancy",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@nestjs/common": ">=10.0.0",
|
|
45
45
|
"@nestjs/core": ">=10.0.0",
|
|
46
|
-
"@stratum-hq/core": ">=0.
|
|
47
|
-
"@stratum-hq/sdk": ">=0.
|
|
46
|
+
"@stratum-hq/core": ">=1.0.0",
|
|
47
|
+
"@stratum-hq/sdk": ">=1.0.0",
|
|
48
48
|
"reflect-metadata": ">=0.1.13"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
@@ -57,6 +57,13 @@
|
|
|
57
57
|
"typescript": "^5.4.0",
|
|
58
58
|
"vitest": "^1.6.0"
|
|
59
59
|
},
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"author": "Christian Crank",
|
|
62
|
+
"homepage": "https://github.com/stratum-hq/Stratum/tree/main/packages/nestjs#readme",
|
|
63
|
+
"bugs": "https://github.com/stratum-hq/Stratum/issues",
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=20.0.0"
|
|
66
|
+
},
|
|
60
67
|
"repository": {
|
|
61
68
|
"type": "git",
|
|
62
69
|
"url": "https://github.com/stratum-hq/Stratum.git",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stratum.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/stratum.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { resolveFromHeader, resolveFromJwt } from "@stratum-hq/sdk";
|
|
3
|
-
import { StratumGuard } from "../stratum.guard.js";
|
|
4
|
-
// ── Mock StratumClient ───────────────────────────────────────────────────────
|
|
5
|
-
function makeMockClient(resolvedContext = null, shouldThrow) {
|
|
6
|
-
return {
|
|
7
|
-
resolveTenant: vi.fn(async (_tenantId) => {
|
|
8
|
-
if (shouldThrow)
|
|
9
|
-
throw shouldThrow;
|
|
10
|
-
if (!resolvedContext)
|
|
11
|
-
throw new Error("No context configured");
|
|
12
|
-
return resolvedContext;
|
|
13
|
-
}),
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
// ── makeContext helper ───────────────────────────────────────────────────────
|
|
17
|
-
function makeExecutionContext(req) {
|
|
18
|
-
return {
|
|
19
|
-
switchToHttp: () => ({
|
|
20
|
-
getRequest: () => req,
|
|
21
|
-
getResponse: () => ({}),
|
|
22
|
-
getNext: () => ({}),
|
|
23
|
-
}),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
// ── Stubs for NestJS exceptions ──────────────────────────────────────────────
|
|
27
|
-
import { TenantNotFoundError } from "@stratum-hq/core";
|
|
28
|
-
class UnauthorizedException extends Error {
|
|
29
|
-
constructor(message) {
|
|
30
|
-
super(message);
|
|
31
|
-
this.name = "UnauthorizedException";
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
class ForbiddenException extends Error {
|
|
35
|
-
constructor(message) {
|
|
36
|
-
super(message);
|
|
37
|
-
this.name = "ForbiddenException";
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// ── Guard logic (mirrors stratum.guard.ts) ───────────────────────────────────
|
|
41
|
-
async function canActivate(client, context, options = {}) {
|
|
42
|
-
const req = context.switchToHttp().getRequest();
|
|
43
|
-
// 1. Resolve tenant ID: JWT (verified) → header → custom resolvers
|
|
44
|
-
let tenantId = null;
|
|
45
|
-
tenantId = resolveFromJwt(req, options.jwtClaimPath, {
|
|
46
|
-
secret: options.jwtSecret,
|
|
47
|
-
verify: options.jwtVerify,
|
|
48
|
-
});
|
|
49
|
-
if (!tenantId) {
|
|
50
|
-
tenantId = resolveFromHeader(req);
|
|
51
|
-
}
|
|
52
|
-
if (!tenantId && options.resolvers) {
|
|
53
|
-
for (const resolver of options.resolvers) {
|
|
54
|
-
const result = await resolver.resolve(req);
|
|
55
|
-
if (result) {
|
|
56
|
-
tenantId = result;
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (!tenantId) {
|
|
62
|
-
throw new UnauthorizedException("Tenant ID could not be resolved from request");
|
|
63
|
-
}
|
|
64
|
-
// 2. Resolve caller tenant context
|
|
65
|
-
let callerContext;
|
|
66
|
-
try {
|
|
67
|
-
callerContext = await client.resolveTenant(tenantId);
|
|
68
|
-
}
|
|
69
|
-
catch (err) {
|
|
70
|
-
if (err instanceof TenantNotFoundError) {
|
|
71
|
-
throw new UnauthorizedException(`Tenant not found: ${tenantId}`);
|
|
72
|
-
}
|
|
73
|
-
throw err;
|
|
74
|
-
}
|
|
75
|
-
req["tenant"] = callerContext;
|
|
76
|
-
req["impersonating"] = false;
|
|
77
|
-
// 3. Impersonation
|
|
78
|
-
if (options.impersonation?.enabled) {
|
|
79
|
-
const impersonateHeader = options.impersonation.headerName ?? "X-Impersonate-Tenant";
|
|
80
|
-
const headers = req.headers;
|
|
81
|
-
const rawVal = headers?.[impersonateHeader.toLowerCase()];
|
|
82
|
-
const impersonateTenantId = Array.isArray(rawVal) ? rawVal[0] : rawVal;
|
|
83
|
-
if (impersonateTenantId && impersonateTenantId !== tenantId) {
|
|
84
|
-
const authorized = await options.impersonation.authorize(req, tenantId, impersonateTenantId);
|
|
85
|
-
if (!authorized) {
|
|
86
|
-
throw new ForbiddenException("Not authorized to impersonate this tenant");
|
|
87
|
-
}
|
|
88
|
-
let impersonatedContext;
|
|
89
|
-
try {
|
|
90
|
-
impersonatedContext = await client.resolveTenant(impersonateTenantId);
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
if (err instanceof TenantNotFoundError) {
|
|
94
|
-
throw new UnauthorizedException(`Impersonated tenant not found: ${impersonateTenantId}`);
|
|
95
|
-
}
|
|
96
|
-
throw err;
|
|
97
|
-
}
|
|
98
|
-
req["tenant"] = impersonatedContext;
|
|
99
|
-
req["impersonating"] = true;
|
|
100
|
-
req["originalTenantId"] = tenantId;
|
|
101
|
-
options.impersonation.onImpersonate?.(req, tenantId, impersonateTenantId);
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
// ── @Tenant() decorator extraction logic ─────────────────────────────────────
|
|
108
|
-
function extractTenant(req) {
|
|
109
|
-
return req["tenant"];
|
|
110
|
-
}
|
|
111
|
-
// ── Tests ─────────────────────────────────────────────────────────────────────
|
|
112
|
-
const MOCK_CONTEXT = {
|
|
113
|
-
id: "tenant-123",
|
|
114
|
-
slug: "acme",
|
|
115
|
-
name: "Acme Corp",
|
|
116
|
-
};
|
|
117
|
-
const MOCK_CONTEXT_B = {
|
|
118
|
-
id: "tenant-456",
|
|
119
|
-
slug: "other",
|
|
120
|
-
name: "Other Corp",
|
|
121
|
-
};
|
|
122
|
-
describe("StratumGuard", () => {
|
|
123
|
-
let client;
|
|
124
|
-
beforeEach(() => {
|
|
125
|
-
client = makeMockClient(MOCK_CONTEXT);
|
|
126
|
-
});
|
|
127
|
-
describe("canActivate — x-tenant-id header", () => {
|
|
128
|
-
it("returns true and sets req.tenant when x-tenant-id header is present", async () => {
|
|
129
|
-
const req = {
|
|
130
|
-
headers: { "x-tenant-id": "tenant-123" },
|
|
131
|
-
};
|
|
132
|
-
const ctx = makeExecutionContext(req);
|
|
133
|
-
const result = await canActivate(client, ctx);
|
|
134
|
-
expect(result).toBe(true);
|
|
135
|
-
expect(req["tenant"]).toEqual(MOCK_CONTEXT);
|
|
136
|
-
expect(client.resolveTenant).toHaveBeenCalledWith("tenant-123");
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
describe("canActivate — JWT (unverified tokens rejected)", () => {
|
|
140
|
-
function makeJwt(payload) {
|
|
141
|
-
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
|
|
142
|
-
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
143
|
-
return `${header}.${body}.fakesig`;
|
|
144
|
-
}
|
|
145
|
-
it("does NOT trust JWT claims when no jwtSecret or jwtVerify is configured", async () => {
|
|
146
|
-
// Without a secret, the guard must not extract tenant from JWT
|
|
147
|
-
const token = makeJwt({ tenant_id: "forged-tenant" });
|
|
148
|
-
const req = {
|
|
149
|
-
headers: { authorization: `Bearer ${token}` },
|
|
150
|
-
};
|
|
151
|
-
const ctx = makeExecutionContext(req);
|
|
152
|
-
// No options — should reject because JWT is unverified
|
|
153
|
-
await expect(canActivate(client, ctx, {})).rejects.toThrow(UnauthorizedException);
|
|
154
|
-
await expect(canActivate(client, ctx, {})).rejects.toThrow("Tenant ID could not be resolved from request");
|
|
155
|
-
expect(client.resolveTenant).not.toHaveBeenCalled();
|
|
156
|
-
});
|
|
157
|
-
it("resolves tenant from JWT when jwtVerify is provided", async () => {
|
|
158
|
-
const token = makeJwt({ tenant_id: "tenant-from-jwt" });
|
|
159
|
-
const req = {
|
|
160
|
-
headers: { authorization: `Bearer ${token}` },
|
|
161
|
-
};
|
|
162
|
-
const ctx = makeExecutionContext(req);
|
|
163
|
-
// Supply a verify function that trusts this token
|
|
164
|
-
const jwtVerify = (_t) => ({ tenant_id: "tenant-from-jwt" });
|
|
165
|
-
const result = await canActivate(client, ctx, { jwtVerify });
|
|
166
|
-
expect(result).toBe(true);
|
|
167
|
-
expect(client.resolveTenant).toHaveBeenCalledWith("tenant-from-jwt");
|
|
168
|
-
});
|
|
169
|
-
it("prefers the verified JWT claim over the x-tenant-id header", async () => {
|
|
170
|
-
const token = makeJwt({ tenant_id: "jwt-tenant" });
|
|
171
|
-
const req = {
|
|
172
|
-
headers: {
|
|
173
|
-
"x-tenant-id": "header-tenant",
|
|
174
|
-
authorization: `Bearer ${token}`,
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
const ctx = makeExecutionContext(req);
|
|
178
|
-
await canActivate(client, ctx, { jwtVerify: () => ({ tenant_id: "jwt-tenant" }) });
|
|
179
|
-
expect(client.resolveTenant).toHaveBeenCalledWith("jwt-tenant");
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
describe("canActivate — missing tenant", () => {
|
|
183
|
-
it("throws UnauthorizedException when no tenant identifier in request", async () => {
|
|
184
|
-
const req = { headers: {} };
|
|
185
|
-
const ctx = makeExecutionContext(req);
|
|
186
|
-
await expect(canActivate(client, ctx)).rejects.toThrow(UnauthorizedException);
|
|
187
|
-
await expect(canActivate(client, ctx)).rejects.toThrow("Tenant ID could not be resolved from request");
|
|
188
|
-
});
|
|
189
|
-
it("throws UnauthorizedException when tenant not found in control plane", async () => {
|
|
190
|
-
const notFoundClient = makeMockClient(null, new TenantNotFoundError("tenant-missing"));
|
|
191
|
-
const req = {
|
|
192
|
-
headers: { "x-tenant-id": "tenant-missing" },
|
|
193
|
-
};
|
|
194
|
-
const ctx = makeExecutionContext(req);
|
|
195
|
-
await expect(canActivate(notFoundClient, ctx)).rejects.toThrow(UnauthorizedException);
|
|
196
|
-
await expect(canActivate(notFoundClient, ctx)).rejects.toThrow("Tenant not found: tenant-missing");
|
|
197
|
-
});
|
|
198
|
-
it("re-throws unexpected errors", async () => {
|
|
199
|
-
const boom = new Error("Network failure");
|
|
200
|
-
const errorClient = makeMockClient(null, boom);
|
|
201
|
-
const req = {
|
|
202
|
-
headers: { "x-tenant-id": "tenant-123" },
|
|
203
|
-
};
|
|
204
|
-
const ctx = makeExecutionContext(req);
|
|
205
|
-
await expect(canActivate(errorClient, ctx)).rejects.toThrow("Network failure");
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
describe("canActivate — custom resolvers", () => {
|
|
209
|
-
it("uses custom resolver when header and JWT resolve nothing", async () => {
|
|
210
|
-
const req = { headers: {} };
|
|
211
|
-
const ctx = makeExecutionContext(req);
|
|
212
|
-
const customResolver = { resolve: vi.fn(async () => "tenant-from-resolver") };
|
|
213
|
-
const result = await canActivate(client, ctx, { resolvers: [customResolver] });
|
|
214
|
-
expect(result).toBe(true);
|
|
215
|
-
expect(customResolver.resolve).toHaveBeenCalledWith(req);
|
|
216
|
-
expect(client.resolveTenant).toHaveBeenCalledWith("tenant-from-resolver");
|
|
217
|
-
});
|
|
218
|
-
it("stops at first resolver that returns a value", async () => {
|
|
219
|
-
const req = { headers: {} };
|
|
220
|
-
const ctx = makeExecutionContext(req);
|
|
221
|
-
const r1 = { resolve: vi.fn(async () => "first-resolver-tenant") };
|
|
222
|
-
const r2 = { resolve: vi.fn(async () => "second-resolver-tenant") };
|
|
223
|
-
await canActivate(client, ctx, { resolvers: [r1, r2] });
|
|
224
|
-
expect(r1.resolve).toHaveBeenCalled();
|
|
225
|
-
expect(r2.resolve).not.toHaveBeenCalled();
|
|
226
|
-
expect(client.resolveTenant).toHaveBeenCalledWith("first-resolver-tenant");
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
describe("canActivate — impersonation", () => {
|
|
230
|
-
it("impersonates target tenant when authorized", async () => {
|
|
231
|
-
// client returns MOCK_CONTEXT for "tenant-123", MOCK_CONTEXT_B for "tenant-456"
|
|
232
|
-
const impClient = {
|
|
233
|
-
resolveTenant: vi.fn(async (id) => {
|
|
234
|
-
if (id === "tenant-123")
|
|
235
|
-
return MOCK_CONTEXT;
|
|
236
|
-
if (id === "tenant-456")
|
|
237
|
-
return MOCK_CONTEXT_B;
|
|
238
|
-
throw new TenantNotFoundError(id);
|
|
239
|
-
}),
|
|
240
|
-
};
|
|
241
|
-
const req = {
|
|
242
|
-
headers: {
|
|
243
|
-
"x-tenant-id": "tenant-123",
|
|
244
|
-
"x-impersonate-tenant": "tenant-456",
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
const ctx = makeExecutionContext(req);
|
|
248
|
-
const onImpersonate = vi.fn();
|
|
249
|
-
const result = await canActivate(impClient, ctx, {
|
|
250
|
-
impersonation: {
|
|
251
|
-
enabled: true,
|
|
252
|
-
authorize: async () => true,
|
|
253
|
-
onImpersonate,
|
|
254
|
-
},
|
|
255
|
-
});
|
|
256
|
-
expect(result).toBe(true);
|
|
257
|
-
expect(req["tenant"]).toEqual(MOCK_CONTEXT_B);
|
|
258
|
-
expect(req["impersonating"]).toBe(true);
|
|
259
|
-
expect(req["originalTenantId"]).toBe("tenant-123");
|
|
260
|
-
expect(onImpersonate).toHaveBeenCalledWith(req, "tenant-123", "tenant-456");
|
|
261
|
-
});
|
|
262
|
-
it("throws ForbiddenException when impersonation is denied", async () => {
|
|
263
|
-
const req = {
|
|
264
|
-
headers: {
|
|
265
|
-
"x-tenant-id": "tenant-123",
|
|
266
|
-
"x-impersonate-tenant": "tenant-456",
|
|
267
|
-
},
|
|
268
|
-
};
|
|
269
|
-
const ctx = makeExecutionContext(req);
|
|
270
|
-
await expect(canActivate(client, ctx, {
|
|
271
|
-
impersonation: {
|
|
272
|
-
enabled: true,
|
|
273
|
-
authorize: async () => false,
|
|
274
|
-
},
|
|
275
|
-
})).rejects.toThrow(ForbiddenException);
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
});
|
|
279
|
-
// ── Real StratumGuard: verified JWT must be authoritative ─────────────────────
|
|
280
|
-
// Exercises the actual guard (not the mirror above) to lock in that an untrusted
|
|
281
|
-
// X-Tenant-ID header cannot override the tenant proven by a verified JWT.
|
|
282
|
-
describe("StratumGuard (real guard): tenant identity precedence", () => {
|
|
283
|
-
function makeJwt(payload) {
|
|
284
|
-
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
|
|
285
|
-
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
286
|
-
return `${header}.${body}.fakesig`;
|
|
287
|
-
}
|
|
288
|
-
it("uses the verified JWT tenant and ignores a conflicting X-Tenant-ID header", async () => {
|
|
289
|
-
const token = makeJwt({ tenant_id: "tenant-a" });
|
|
290
|
-
const req = {
|
|
291
|
-
headers: {
|
|
292
|
-
authorization: `Bearer ${token}`,
|
|
293
|
-
"x-tenant-id": "tenant-b",
|
|
294
|
-
},
|
|
295
|
-
};
|
|
296
|
-
const ctx = makeExecutionContext(req);
|
|
297
|
-
const resolveTenant = vi.fn(async (id) => ({ id, slug: id, name: id }));
|
|
298
|
-
const client = { resolveTenant };
|
|
299
|
-
const options = { jwtVerify: () => ({ tenant_id: "tenant-a" }) };
|
|
300
|
-
const guard = new StratumGuard(client, options);
|
|
301
|
-
const result = await guard.canActivate(ctx);
|
|
302
|
-
expect(result).toBe(true);
|
|
303
|
-
// The verified JWT tenant is authoritative; the header must not be used.
|
|
304
|
-
expect(resolveTenant).toHaveBeenCalledWith("tenant-a");
|
|
305
|
-
expect(resolveTenant).not.toHaveBeenCalledWith("tenant-b");
|
|
306
|
-
expect(req["tenant"].id).toBe("tenant-a");
|
|
307
|
-
});
|
|
308
|
-
it("falls back to the X-Tenant-ID header only when no verified JWT tenant is present", async () => {
|
|
309
|
-
const req = {
|
|
310
|
-
headers: { "x-tenant-id": "tenant-header" },
|
|
311
|
-
};
|
|
312
|
-
const ctx = makeExecutionContext(req);
|
|
313
|
-
const resolveTenant = vi.fn(async (id) => ({ id, slug: id, name: id }));
|
|
314
|
-
const client = { resolveTenant };
|
|
315
|
-
const guard = new StratumGuard(client, {});
|
|
316
|
-
const result = await guard.canActivate(ctx);
|
|
317
|
-
expect(result).toBe(true);
|
|
318
|
-
expect(resolveTenant).toHaveBeenCalledWith("tenant-header");
|
|
319
|
-
});
|
|
320
|
-
});
|
|
321
|
-
describe("@Tenant() decorator", () => {
|
|
322
|
-
it("extracts req.tenant from execution context", () => {
|
|
323
|
-
const req = { tenant: MOCK_CONTEXT };
|
|
324
|
-
const tenant = extractTenant(req);
|
|
325
|
-
expect(tenant).toEqual(MOCK_CONTEXT);
|
|
326
|
-
});
|
|
327
|
-
it("returns undefined when tenant not yet set (guard not applied)", () => {
|
|
328
|
-
const req = {};
|
|
329
|
-
const tenant = extractTenant(req);
|
|
330
|
-
expect(tenant).toBeUndefined();
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
describe("STRATUM_CLIENT / STRATUM_OPTIONS constants", () => {
|
|
334
|
-
it("exports distinct Symbol injection tokens", async () => {
|
|
335
|
-
const { STRATUM_CLIENT, STRATUM_OPTIONS } = await import("../constants.js");
|
|
336
|
-
expect(typeof STRATUM_CLIENT).toBe("symbol");
|
|
337
|
-
expect(typeof STRATUM_OPTIONS).toBe("symbol");
|
|
338
|
-
expect(STRATUM_CLIENT).not.toBe(STRATUM_OPTIONS);
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
//# sourceMappingURL=stratum.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stratum.test.js","sourceRoot":"","sources":["../../src/__tests__/stratum.test.ts"],"names":[],"mappings":"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"}
|