@stratum-hq/control-plane 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +41 -6
  2. package/dist/app.d.ts.map +1 -1
  3. package/dist/app.js +27 -0
  4. package/dist/app.js.map +1 -1
  5. package/dist/config.d.ts +3 -0
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +20 -0
  8. package/dist/config.js.map +1 -1
  9. package/dist/db/connection.d.ts +10 -0
  10. package/dist/db/connection.d.ts.map +1 -1
  11. package/dist/db/connection.js +41 -12
  12. package/dist/db/connection.js.map +1 -1
  13. package/dist/db/migrate.d.ts.map +1 -1
  14. package/dist/db/migrate.js +29 -6
  15. package/dist/db/migrate.js.map +1 -1
  16. package/dist/index.js +1 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/middleware/authorize.d.ts.map +1 -1
  19. package/dist/middleware/authorize.js +3 -2
  20. package/dist/middleware/authorize.js.map +1 -1
  21. package/dist/middleware/error-handler.d.ts +6 -0
  22. package/dist/middleware/error-handler.d.ts.map +1 -1
  23. package/dist/middleware/error-handler.js +27 -4
  24. package/dist/middleware/error-handler.js.map +1 -1
  25. package/dist/middleware/path-params.d.ts +31 -0
  26. package/dist/middleware/path-params.d.ts.map +1 -0
  27. package/dist/middleware/path-params.js +78 -0
  28. package/dist/middleware/path-params.js.map +1 -0
  29. package/dist/routes/config-diff.d.ts.map +1 -1
  30. package/dist/routes/config-diff.js +2 -1
  31. package/dist/routes/config-diff.js.map +1 -1
  32. package/dist/routes/config.d.ts +11 -1
  33. package/dist/routes/config.d.ts.map +1 -1
  34. package/dist/routes/config.js +102 -2
  35. package/dist/routes/config.js.map +1 -1
  36. package/dist/routes/health.d.ts.map +1 -1
  37. package/dist/routes/health.js +14 -9
  38. package/dist/routes/health.js.map +1 -1
  39. package/dist/routes/tenants.d.ts.map +1 -1
  40. package/dist/routes/tenants.js +6 -3
  41. package/dist/routes/tenants.js.map +1 -1
  42. package/dist/services/isolation-service.d.ts.map +1 -1
  43. package/dist/services/isolation-service.js +9 -4
  44. package/dist/services/isolation-service.js.map +1 -1
  45. package/package.json +3 -3
package/README.md CHANGED
@@ -14,20 +14,55 @@ Most deployments run it as a standalone service rather than importing it. A cont
14
14
 
15
15
  ## Running
16
16
 
17
+ The package has no `bin` entry. Start its entry point with Node:
18
+
17
19
  ```bash
18
- DATABASE_URL=postgres://stratum:stratum_dev@localhost:5432/stratum \
20
+ DATABASE_URL=postgres://stratum_app:stratum_dev@localhost:5432/stratum \
21
+ DATABASE_ADMIN_URL=postgres://stratum_admin:stratum_dev@localhost:5432/stratum \
19
22
  JWT_SECRET=your-secret \
20
- node dist/index.js
23
+ node node_modules/@stratum-hq/control-plane/dist/index.js
24
+ ```
25
+
26
+ In a clone of the repository, run `npm run build`, then `node packages/control-plane/dist/index.js`.
27
+
28
+ On startup the server runs database migrations (on `DATABASE_ADMIN_URL` when set), then listens on `PORT` (default `3001`). It handles `SIGTERM`/`SIGINT` for graceful shutdown.
29
+
30
+ The OpenAPI documentation needs no API key: the Swagger UI is at `/api/docs`, and the specification at `/api/docs/json` and `/api/docs/yaml`.
31
+
32
+ ## The first admin key
33
+
34
+ Every route except the health check and the OpenAPI documentation needs an API key or a JWT, and creating keys needs the `admin` scope. A JWT always belongs to a tenant, and a new API key has the scopes `read` and `write`, so create the first admin key with the library, on the same database and with the same `STRATUM_API_KEY_HMAC_SECRET` as the server:
35
+
36
+ ```typescript
37
+ import { Pool } from "pg";
38
+ import { Stratum } from "@stratum-hq/lib";
39
+
40
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL });
41
+ const adminPool = new Pool({ connectionString: process.env.DATABASE_ADMIN_URL });
42
+ const stratum = new Stratum({ adminPool, pool });
43
+ await stratum.initialize();
44
+
45
+ // A global key (tenant null) with a role that grants the admin scope.
46
+ const role = await stratum.createRole({ name: "operator", scopes: ["admin"] });
47
+ const key = await stratum.createApiKey(null, { name: "bootstrap-admin" });
48
+ await stratum.assignRoleToKey(key.id, role.id);
49
+ console.log(key.plaintext_key); // shown once: store it now
50
+
51
+ await Promise.all([pool.end(), adminPool.end()]);
21
52
  ```
22
53
 
23
- On startup the server runs database migrations, then listens on `PORT` (default `3001`). It handles `SIGTERM`/`SIGINT` for graceful shutdown. OpenAPI docs are served via `@fastify/swagger-ui`.
54
+ Run it after the server has started once, so the tables exist. Without `DATABASE_ADMIN_URL`, leave out `adminPool`. Then send the key in the `X-API-Key` header, and create further keys and roles through `/api/v1/api-keys` and `/api/v1/roles`. `stratum generate api-key` from `@stratum-hq/cli` also creates a global key, but with the default `read` and `write` scopes, so it cannot manage keys.
24
55
 
25
56
  ## Configuration
26
57
 
27
58
  | Variable | Default | Description |
28
59
  |----------|---------|-------------|
29
60
  | `PORT` | `3001` | Listen port |
30
- | `DATABASE_URL` | `postgres://stratum:stratum_dev@localhost:5432/stratum` | PostgreSQL connection string |
61
+ | `DATABASE_URL` | `postgres://stratum:stratum_dev@localhost:5432/stratum` | PostgreSQL connection string of the application login |
62
+ | `DATABASE_ADMIN_URL` | none | Optional admin login, a member of the control role of `@stratum-hq/lib` migration 032. When set, the migrations, the library (`adminPool`) and tenant schema and database provisioning run on it, both logins are checked at startup, and the health check reports `admin_db`. When unset, everything runs on `DATABASE_URL` as before. See the [hardening guide](https://docs.stratum-hq.org/guides/hardening-roles/) |
63
+ | `STRATUM_CONTROL_ROLE` | none | Name of the control role, when it is not the database's or `stratum_control` |
64
+ | `STRATUM_ALLOW_LEGACY_KEY_HASHES` | library default (`true` in 1.x) | `false` accepts only HMAC API key hashes while `STRATUM_API_KEY_HMAC_SECRET` is set; `true` also accepts legacy SHA-256 hashes and re-hashes them on use |
65
+ | `STRATUM_API_KEY_HMAC_SECRET` | none | Optional HMAC secret for API key hashes (at least 32 bytes whenever `NODE_ENV` is not `development` or `test`) |
31
66
  | `JWT_SECRET` | dev fallback | JWT signing secret, **required** whenever `NODE_ENV` is not `development` or `test` (server refuses to start without it). There it must also be at least 32 bytes and not a placeholder such as `change-me-in-production` |
32
67
  | `JWT_AUDIENCE` | none | Optional; when set, Bearer tokens must carry this `aud` claim (for example `stratum-control-plane`). Recommended whenever `JWT_SECRET` is shared with another application; the server warns at startup when it is unset and `NODE_ENV` is not `development` or `test` |
33
68
  | `JWT_ISSUER` | none | Optional; when set, Bearer tokens must carry this `iss` claim |
@@ -35,7 +70,7 @@ On startup the server runs database migrations, then listens on `PORT` (default
35
70
  | `RATE_LIMIT_MAX` | `100` | Requests per window |
36
71
  | `RATE_LIMIT_WINDOW` | `1 minute` | Rate-limit window |
37
72
  | `REDIS_URL` | none | Optional; enables distributed per-key rate limiting. While Redis is unreachable the client keeps reconnecting and per-key limits are counted in memory per process |
38
- | `STRATUM_ENCRYPTION_KEY` | dev fallback | Field-level encryption key, **required** whenever `NODE_ENV` is not `development` or `test` |
73
+ | `STRATUM_ENCRYPTION_KEY` | dev fallback | Field-level encryption key, **required** (at least 32 bytes) whenever `NODE_ENV` is not `development` or `test` |
39
74
  | `STRATUM_HKDF_SALT` | dev fallback | Hex-encoded HKDF salt, **required** whenever `NODE_ENV` is not `development` or `test` |
40
75
  | `NODE_ENV` | `development` | Environment. Any value other than `development` or `test` (staging and preview included) enforces the `JWT_SECRET` checks, requires real encryption key material, and runs migrations with RLS enforcement (refusing a `BYPASSRLS` role). Unset counts as `development` |
41
76
 
@@ -60,7 +95,7 @@ All routes are versioned under `/api/v1`:
60
95
  | `/api/v1/config` | Config diff |
61
96
  | `/api/v1/maintenance` | Retention / purge tasks |
62
97
 
63
- A `/health` endpoint reports server and Redis status.
98
+ `GET /api/v1/health` needs no API key and reports server, database (and, with `DATABASE_ADMIN_URL`, admin database) and Redis status.
64
99
 
65
100
  ## Links
66
101
 
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA4CnD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CA4EzD"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA6CnD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAqGzD"}
package/dist/app.js CHANGED
@@ -12,6 +12,7 @@ const helmet_1 = __importDefault(require("@fastify/helmet"));
12
12
  const lib_1 = require("@stratum-hq/lib");
13
13
  const openapi_js_1 = require("./openapi.js");
14
14
  const error_handler_js_1 = require("./middleware/error-handler.js");
15
+ const path_params_js_1 = require("./middleware/path-params.js");
15
16
  const auth_js_1 = require("./middleware/auth.js");
16
17
  const authorize_js_1 = require("./middleware/authorize.js");
17
18
  const tenant_scope_js_1 = require("./middleware/tenant-scope.js");
@@ -56,10 +57,30 @@ async function buildApp() {
56
57
  },
57
58
  genReqId: () => node_crypto_1.default.randomUUID(),
58
59
  });
60
+ // With DATABASE_ADMIN_URL the library runs on the admin login, as the
61
+ // control role of migration 032, and sets no app.bypass_rls. Without it,
62
+ // everything runs on DATABASE_URL as in earlier releases.
63
+ const adminPool = (0, connection_js_1.getAdminPool)();
59
64
  const stratum = new lib_1.Stratum({
60
65
  pool: (0, connection_js_1.getPool)(),
66
+ adminPool,
67
+ controlRole: config_js_2.config.controlRole,
68
+ allowLegacyKeyHashes: config_js_2.config.allowLegacyKeyHashes,
61
69
  keyPrefix: config_js_2.config.nodeEnv === "production" ? "sk_live_" : "sk_test_",
62
70
  });
71
+ // Checks the logins against the role model and logs each problem: both
72
+ // logins with DATABASE_ADMIN_URL, else whether the DATABASE_URL login is a
73
+ // member of the control role. Migrations run separately (db/migrate.ts).
74
+ if (adminPool) {
75
+ await stratum.initialize();
76
+ }
77
+ else {
78
+ // As before 1.8, the server starts without the admin login even when
79
+ // the check cannot read the database yet.
80
+ await stratum.initialize().catch((err) => {
81
+ app.log.warn(`Could not check the database role model: ${err instanceof Error ? err.message : String(err)}`);
82
+ });
83
+ }
63
84
  await app.register(helmet_1.default, {
64
85
  contentSecurityPolicy: {
65
86
  directives: {
@@ -83,6 +104,11 @@ async function buildApp() {
83
104
  await (0, openapi_js_1.registerOpenApi)(app);
84
105
  app.addHook("preHandler", (0, auth_js_1.createAuthMiddleware)(stratum));
85
106
  app.addHook("preHandler", (0, authorize_js_1.createAuthorizeMiddleware)());
107
+ // A path id or a query-string tenant id that is not a UUID gets 400, after
108
+ // authentication and before any lookup by that id.
109
+ (0, path_params_js_1.registerUuidPathParams)(app);
110
+ app.addHook("preHandler", path_params_js_1.rejectInvalidPathParams);
111
+ app.addHook("preHandler", path_params_js_1.rejectInvalidQueryTenantIds);
86
112
  // Default-deny: a route that declares no tenant scope is refused.
87
113
  app.addHook("preHandler", (0, tenant_scope_js_1.createTenantScopeEnforcer)(stratum));
88
114
  // Use Redis-backed rate limiting when REDIS_URL is configured, otherwise in-memory
@@ -100,6 +126,7 @@ async function buildApp() {
100
126
  app.log.info("Per-key rate limiting: in-memory (no REDIS_URL)");
101
127
  }
102
128
  app.setErrorHandler(error_handler_js_1.errorHandler);
129
+ app.setNotFoundHandler(error_handler_js_1.notFoundHandler);
103
130
  await app.register((0, health_js_1.healthRoutes)(redis_js_1.checkRedisHealth));
104
131
  await app.register((0, tenants_js_1.createTenantRoutes)(stratum), { prefix: "/api/v1/tenants" });
105
132
  await app.register((0, config_js_1.createConfigRoutes)(stratum), { prefix: "/api/v1/tenants/:id/config" });
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export declare const config: {
2
2
  port: number;
3
3
  databaseUrl: string;
4
+ databaseAdminUrl: string | undefined;
5
+ controlRole: string | undefined;
6
+ allowLegacyKeyHashes: boolean | undefined;
4
7
  nodeEnv: string;
5
8
  jwtSecret: string;
6
9
  jwtAudience: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA4CA,eAAO,MAAM,MAAM;;;;;;;;;;;CAalB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAwDA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;CAmBlB,CAAC"}
package/dist/config.js CHANGED
@@ -42,9 +42,29 @@ const jwtIssuerEnv = process.env.JWT_ISSUER || undefined;
42
42
  if (!jwtAudienceEnv && enforceSecretHygiene) {
43
43
  console.warn("[stratum] JWT_AUDIENCE not set. Bearer tokens are not bound to the control plane. Set JWT_AUDIENCE (for example stratum-control-plane).");
44
44
  }
45
+ /**
46
+ * STRATUM_ALLOW_LEGACY_KEY_HASHES: whether API keys stored with the legacy
47
+ * SHA-256 hash still authenticate while STRATUM_API_KEY_HMAC_SECRET is set.
48
+ * Unset keeps the library default (true in 1.x).
49
+ */
50
+ function parseAllowLegacyKeyHashes(raw) {
51
+ if (raw === undefined || raw === "")
52
+ return undefined;
53
+ if (raw === "true" || raw === "1")
54
+ return true;
55
+ if (raw === "false" || raw === "0")
56
+ return false;
57
+ throw new Error(`FATAL: STRATUM_ALLOW_LEGACY_KEY_HASHES must be true or false, got "${raw}". Refusing to start.`);
58
+ }
45
59
  exports.config = {
46
60
  port: parseInt(process.env.PORT || "3001"),
47
61
  databaseUrl: process.env.DATABASE_URL || "postgres://stratum:stratum_dev@localhost:5432/stratum",
62
+ // The admin login (member of the control role of lib migration 032). Unset
63
+ // keeps the single-pool behavior of earlier releases.
64
+ databaseAdminUrl: process.env.DATABASE_ADMIN_URL || undefined,
65
+ // The control role of migration 032. Unset: the database's, else stratum_control.
66
+ controlRole: process.env.STRATUM_CONTROL_ROLE || undefined,
67
+ allowLegacyKeyHashes: parseAllowLegacyKeyHashes(process.env.STRATUM_ALLOW_LEGACY_KEY_HASHES),
48
68
  nodeEnv,
49
69
  jwtSecret: jwtSecretEnv || node_crypto_1.default.randomBytes(32).toString("hex"),
50
70
  jwtAudience: jwtAudienceEnv,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAiC;AAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;AACtD,8EAA8E;AAC9E,8EAA8E;AAC9E,MAAM,oBAAoB,GAAG,OAAO,KAAK,aAAa,IAAI,OAAO,KAAK,MAAM,CAAC;AAE7E,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,IAAI,oBAAoB,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,uBAAuB,CAAC,CAAC;IAC7F,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;IACnH,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,yBAAyB;IACzB,8CAA8C;IAC9C,sCAAsC;CACvC,CAAC,CAAC;AACH,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,IAAI,YAAY,IAAI,oBAAoB,EAAE,CAAC;IACzC,IAAI,uBAAuB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,oBAAoB,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,sCAAsC,oBAAoB,yDAAyD,CAAC,CAAC;IACvI,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,gFAAgF;AAChF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,SAAS,CAAC;AAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,SAAS,CAAC;AAEzD,IAAI,CAAC,cAAc,IAAI,oBAAoB,EAAE,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,yIAAyI,CAAC,CAAC;AAC1J,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;IAC1C,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uDAAuD;IAChG,OAAO;IACP,SAAS,EAAE,YAAY,IAAI,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IACjE,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,YAAY;IACvB,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;QACzC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IACtD,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,KAAK,CAAC;IAC3D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,UAAU;IAC5D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;CAC7C,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,14 @@
1
1
  import pg from "pg";
2
+ /** The application login's pool, from DATABASE_URL. */
2
3
  export declare function getPool(): pg.Pool;
4
+ /**
5
+ * The admin login's pool, from DATABASE_ADMIN_URL, or undefined when it is
6
+ * not set. The admin login is a member of the control role of
7
+ * @stratum-hq/lib migration 032: the library, the migrations and the
8
+ * isolation service run on it, and the library sets no app.bypass_rls.
9
+ */
10
+ export declare function getAdminPool(): pg.Pool | undefined;
11
+ /** The pool for Stratum's own work: the admin pool when configured, else the application pool. */
12
+ export declare function getStratumPool(): pg.Pool;
3
13
  export declare function closePool(): Promise<void>;
4
14
  //# sourceMappingURL=connection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAMpB,wBAAgB,OAAO,IAAI,EAAE,CAAC,IAAI,CAiBjC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/C"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAqBpB,uDAAuD;AACvD,wBAAgB,OAAO,IAAI,EAAE,CAAC,IAAI,CAQjC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,EAAE,CAAC,IAAI,GAAG,SAAS,CAKlD;AAED,kGAAkG;AAClG,wBAAgB,cAAc,IAAI,EAAE,CAAC,IAAI,CAExC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAS/C"}
@@ -4,28 +4,57 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getPool = getPool;
7
+ exports.getAdminPool = getAdminPool;
8
+ exports.getStratumPool = getStratumPool;
7
9
  exports.closePool = closePool;
8
10
  const pg_1 = __importDefault(require("pg"));
9
11
  const { Pool } = pg_1.default;
10
12
  let pool = null;
13
+ let adminPool = null;
14
+ // Note: pg.Pool has no built-in queue depth limit. Under heavy load, excess
15
+ // requests queue in memory until connectionTimeoutMillis elapses. Keep
16
+ // connectionTimeoutMillis short so queued requests fail fast rather than
17
+ // accumulating and exhausting the event loop.
18
+ function createPool(connectionString) {
19
+ return new Pool({
20
+ connectionString,
21
+ max: 20,
22
+ idleTimeoutMillis: 30000,
23
+ connectionTimeoutMillis: 2000,
24
+ allowExitOnIdle: true,
25
+ });
26
+ }
27
+ /** The application login's pool, from DATABASE_URL. */
11
28
  function getPool() {
12
29
  if (!pool) {
13
- // Note: pg.Pool has no built-in queue depth limit. Under heavy load,
14
- // excess requests queue in memory until connectionTimeoutMillis elapses.
15
- // Keep connectionTimeoutMillis short so queued requests fail fast rather
16
- // than accumulating and exhausting the event loop.
17
- pool = new Pool({
18
- connectionString: process.env.DATABASE_URL ||
19
- "postgres://stratum_app:stratum_dev@localhost:5432/stratum",
20
- max: 20,
21
- idleTimeoutMillis: 30000,
22
- connectionTimeoutMillis: 2000,
23
- allowExitOnIdle: true,
24
- });
30
+ pool = createPool(process.env.DATABASE_URL ||
31
+ "postgres://stratum_app:stratum_dev@localhost:5432/stratum");
25
32
  }
26
33
  return pool;
27
34
  }
35
+ /**
36
+ * The admin login's pool, from DATABASE_ADMIN_URL, or undefined when it is
37
+ * not set. The admin login is a member of the control role of
38
+ * @stratum-hq/lib migration 032: the library, the migrations and the
39
+ * isolation service run on it, and the library sets no app.bypass_rls.
40
+ */
41
+ function getAdminPool() {
42
+ const url = process.env.DATABASE_ADMIN_URL;
43
+ if (!url)
44
+ return undefined;
45
+ if (!adminPool)
46
+ adminPool = createPool(url);
47
+ return adminPool;
48
+ }
49
+ /** The pool for Stratum's own work: the admin pool when configured, else the application pool. */
50
+ function getStratumPool() {
51
+ return getAdminPool() ?? getPool();
52
+ }
28
53
  async function closePool() {
54
+ if (adminPool) {
55
+ await adminPool.end();
56
+ adminPool = null;
57
+ }
29
58
  if (pool) {
30
59
  await pool.end();
31
60
  pool = null;
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":";;;;;AAMA,0BAiBC;AAED,8BAKC;AA9BD,4CAAoB;AAEpB,MAAM,EAAE,IAAI,EAAE,GAAG,YAAE,CAAC;AAEpB,IAAI,IAAI,GAAmB,IAAI,CAAC;AAEhC,SAAgB,OAAO;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,qEAAqE;QACrE,yEAAyE;QACzE,yEAAyE;QACzE,mDAAmD;QACnD,IAAI,GAAG,IAAI,IAAI,CAAC;YACd,gBAAgB,EACd,OAAO,CAAC,GAAG,CAAC,YAAY;gBACxB,2DAA2D;YAC7D,GAAG,EAAE,EAAE;YACP,iBAAiB,EAAE,KAAK;YACxB,uBAAuB,EAAE,IAAI;YAC7B,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAEM,KAAK,UAAU,SAAS;IAC7B,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QACjB,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":";;;;;AAsBA,0BAQC;AAQD,oCAKC;AAGD,wCAEC;AAED,8BASC;AA3DD,4CAAoB;AAEpB,MAAM,EAAE,IAAI,EAAE,GAAG,YAAE,CAAC;AAEpB,IAAI,IAAI,GAAmB,IAAI,CAAC;AAChC,IAAI,SAAS,GAAmB,IAAI,CAAC;AAErC,4EAA4E;AAC5E,uEAAuE;AACvE,yEAAyE;AACzE,8CAA8C;AAC9C,SAAS,UAAU,CAAC,gBAAwB;IAC1C,OAAO,IAAI,IAAI,CAAC;QACd,gBAAgB;QAChB,GAAG,EAAE,EAAE;QACP,iBAAiB,EAAE,KAAK;QACxB,uBAAuB,EAAE,IAAI;QAC7B,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;AACL,CAAC;AAED,uDAAuD;AACvD,SAAgB,OAAO;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,UAAU,CACf,OAAO,CAAC,GAAG,CAAC,YAAY;YACtB,2DAA2D,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAC3C,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,CAAC,SAAS;QAAE,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,kGAAkG;AAClG,SAAgB,cAAc;IAC5B,OAAO,YAAY,EAAE,IAAI,OAAO,EAAE,CAAC;AACrC,CAAC;AAEM,KAAK,UAAU,SAAS;IAC7B,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC;QACtB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QACjB,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAGA,iBAAe,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAStC;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AASA,iBAAe,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BtC;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -3,14 +3,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.migrate = migrate;
4
4
  const lib_1 = require("@stratum-hq/lib");
5
5
  const connection_js_1 = require("./connection.js");
6
+ async function currentLogin(pool) {
7
+ const res = await pool.query("SELECT current_user::text AS me");
8
+ return res.rows[0].me;
9
+ }
6
10
  async function migrate() {
7
- const pool = (0, connection_js_1.getPool)();
8
11
  console.log("Running migrations...");
9
- // RLS is enforced everywhere except local development and test runs (an
10
- // unset NODE_ENV counts as development), matching the JWT_SECRET checks.
11
- const nodeEnv = process.env.NODE_ENV || "development";
12
- const enforceRls = nodeEnv !== "development" && nodeEnv !== "test";
13
- await (0, lib_1.migrate)({ pool, enforceRls });
12
+ const adminPool = (0, connection_js_1.getAdminPool)();
13
+ // The control role of lib migration 032 (see config.controlRole). Unset:
14
+ // the database's, else stratum_control.
15
+ const controlRole = process.env.STRATUM_CONTROL_ROLE ? { controlRole: process.env.STRATUM_CONTROL_ROLE } : {};
16
+ if (adminPool) {
17
+ // Migration 032 grants the control role to the admin login, so it must
18
+ // not be the application's login.
19
+ const admin = await currentLogin(adminPool);
20
+ if (admin === (await currentLogin((0, connection_js_1.getPool)()))) {
21
+ throw new Error(`DATABASE_ADMIN_URL and DATABASE_URL log in as the same role "${admin}". DATABASE_ADMIN_URL must be a ` +
22
+ "separate login: the migrations make it a member of the control role, which passes every Stratum policy.");
23
+ }
24
+ // The admin login owns the Stratum objects and is a member of the control
25
+ // role. It may have BYPASSRLS, so the RLS check below is about the
26
+ // application login, which Stratum.initialize() checks in buildApp().
27
+ // It is the admin login, so migration 032 may grant it the control role.
28
+ await (0, lib_1.migrate)({ pool: adminPool, applyControlRole: true, ...controlRole });
29
+ }
30
+ else {
31
+ // RLS is enforced everywhere except local development and test runs (an
32
+ // unset NODE_ENV counts as development), matching the JWT_SECRET checks.
33
+ const nodeEnv = process.env.NODE_ENV || "development";
34
+ const enforceRls = nodeEnv !== "development" && nodeEnv !== "test";
35
+ await (0, lib_1.migrate)({ pool: (0, connection_js_1.getPool)(), enforceRls, ...controlRole });
36
+ }
14
37
  console.log("Migrations complete.");
15
38
  }
16
39
  //# sourceMappingURL=migrate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":";;AAcS,0BAAO;AAdhB,yCAA2D;AAC3D,mDAA0C;AAE1C,KAAK,UAAU,OAAO;IACpB,MAAM,IAAI,GAAG,IAAA,uBAAO,GAAE,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,wEAAwE;IACxE,yEAAyE;IACzE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;IACtD,MAAM,UAAU,GAAG,OAAO,KAAK,aAAa,IAAI,OAAO,KAAK,MAAM,CAAC;IACnE,MAAM,IAAA,aAAa,EAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":";;AAwCS,0BAAO;AAxChB,yCAA2D;AAE3D,mDAAwD;AAExD,KAAK,UAAU,YAAY,CAAC,IAAa;IACvC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAiB,iCAAiC,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,OAAO;IACpB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,IAAA,4BAAY,GAAE,CAAC;IACjC,yEAAyE;IACzE,wCAAwC;IACxC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9G,IAAI,SAAS,EAAE,CAAC;QACd,uEAAuE;QACvE,kCAAkC;QAClC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC,IAAA,uBAAO,GAAE,CAAC,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,gEAAgE,KAAK,kCAAkC;gBACrG,yGAAyG,CAC5G,CAAC;QACJ,CAAC;QACD,0EAA0E;QAC1E,mEAAmE;QACnE,sEAAsE;QACtE,yEAAyE;QACzE,MAAM,IAAA,aAAa,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;IACnF,CAAC;SAAM,CAAC;QACN,wEAAwE;QACxE,yEAAyE;QACzE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;QACtD,MAAM,UAAU,GAAG,OAAO,KAAK,aAAa,IAAI,OAAO,KAAK,MAAM,CAAC;QACnE,MAAM,IAAA,aAAa,EAAC,EAAE,IAAI,EAAE,IAAA,uBAAO,GAAE,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC"}
package/dist/index.js CHANGED
@@ -5,8 +5,7 @@ const config_js_1 = require("./config.js");
5
5
  const migrate_js_1 = require("./db/migrate.js");
6
6
  const connection_js_1 = require("./db/connection.js");
7
7
  async function main() {
8
- // Run database migrations
9
- console.log("Running migrations...");
8
+ // Run database migrations (migrate() reports its own progress)
10
9
  await (0, migrate_js_1.migrate)();
11
10
  // Build and start the app
12
11
  const app = await (0, app_js_1.buildApp)();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qCAAoC;AACpC,2CAAqC;AACrC,gDAA0C;AAC1C,sDAA+C;AAE/C,KAAK,UAAU,IAAI;IACjB,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,MAAM,IAAA,oBAAO,GAAE,CAAC;IAEhB,0BAA0B;IAC1B,MAAM,GAAG,GAAG,MAAM,IAAA,iBAAQ,GAAE,CAAC;IAE7B,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,kBAAM,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,kBAAM,CAAC,IAAI,KAAK,kBAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAE1F,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,oBAAoB,CAAC,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,IAAA,yBAAS,GAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qCAAoC;AACpC,2CAAqC;AACrC,gDAA0C;AAC1C,sDAA+C;AAE/C,KAAK,UAAU,IAAI;IACjB,+DAA+D;IAC/D,MAAM,IAAA,oBAAO,GAAE,CAAC;IAEhB,0BAA0B;IAC1B,MAAM,GAAG,GAAG,MAAM,IAAA,iBAAQ,GAAE,CAAC;IAE7B,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,kBAAM,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,kBAAM,CAAC,IAAI,KAAK,kBAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAE1F,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,oBAAoB,CAAC,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,IAAA,yBAAS,GAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIxE;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,oBAAoB;QAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;KAC/B;CACF;AAED;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAChC,aAAa,GACb;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAMlD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,wBAAwB,GACpC,IAAI,CAkBN;AAED,wBAAgB,yBAAyB,KAErC,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAoCjB"}
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIxE;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,oBAAoB;QAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;KAC/B;CACF;AAED;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAChC,aAAa,GACb;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAMlD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,wBAAwB,GACpC,IAAI,CAkBN;AAED,wBAAgB,yBAAyB,KAErC,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAuCjB"}
@@ -63,8 +63,9 @@ function createAuthorizeMiddleware() {
63
63
  const scopes = request.apiKey.scopes ?? ["read"];
64
64
  // Hierarchical scopes: admin implies write implies read. A granted scope
65
65
  // satisfies any required scope of equal-or-lower rank.
66
- if (!(0, core_1.scopeSatisfies)(scopes, requiredScope === "operator" ? "admin" : requiredScope)) {
67
- throw new core_1.ForbiddenError("Insufficient permissions for this operation");
66
+ const neededScope = requiredScope === "operator" ? "admin" : requiredScope;
67
+ if (!(0, core_1.scopeSatisfies)(scopes, neededScope)) {
68
+ throw new core_1.ForbiddenError(`Insufficient permissions for this operation: it requires the "${neededScope}" scope`);
68
69
  }
69
70
  if (requiredScope === "operator") {
70
71
  (0, tenant_scope_js_1.assertOperator)(request);
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":";;AAuCA,oDAqBC;AAED,8DAwCC;AArGD,2CAAqF;AACrF,uDAAmD;AAyBnD,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAClC,GAAoB,EACpB,WAAqC;IAErC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,YAAY,EAAE,EAAE;QACtC,IAAI,YAAY,CAAC,MAAM,EAAE,aAAa,KAAK,SAAS;YAAE,OAAO;QAC7D,IAAI,KAAgC,CAAC;QACrC,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpC,KAAK,GAAG,WAAW,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC;gBAChD,CAAC,CAAC,YAAY,CAAC,MAAM;gBACrB,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;YAChE,2DAA2D;YAC3D,IAAI,IAAI;gBAAE,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC;iBAC9B,IAAI,MAAM;gBAAE,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAC7C,CAAC;QACD,YAAY,CAAC,MAAM,GAAG,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,yBAAyB;IACvC,OAAO,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,MAAoB;QAEpB,8CAA8C;QAC9C,IACE,OAAO,CAAC,GAAG,KAAK,gBAAgB;YAChC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EACnC,CAAC;YACD,OAAO;QACT,CAAC;QAED,qEAAqE;QACrE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,wBAAiB,CAAC,yBAAyB,CAAC,CAAC;QACzD,CAAC;QAED,yEAAyE;QACzE,4DAA4D;QAC5D,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO;QAE1B,yEAAyE;QACzE,4EAA4E;QAC5E,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC;QAClE,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,qBAAc,CAAC,yCAAyC,CAAC,CAAC;QACtE,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjD,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,CAAC,IAAA,qBAAc,EAAC,MAAM,EAAE,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,qBAAc,CAAC,6CAA6C,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;YACjC,IAAA,gCAAc,EAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"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"}
@@ -38,5 +38,11 @@ export declare function legacyValidationErrorBody(message: string, issues: reado
38
38
  issues: ValidationIssue[];
39
39
  };
40
40
  };
41
+ /**
42
+ * Answers a request that matches no route with the error envelope of every
43
+ * other error. The global hooks run first, so a caller without credentials
44
+ * gets 401 and only an authenticated caller learns that the route is unknown.
45
+ */
46
+ export declare function notFoundHandler(request: FastifyRequest, reply: FastifyReply): void;
41
47
  export declare function errorHandler(error: FastifyError | Error, request: FastifyRequest, reply: FastifyReply): void;
42
48
  //# sourceMappingURL=error-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;EAYlC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,eAAe,EAAE;;;;;;;;;;EAG5F;AAmFD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,GAAG,KAAK,EAC3B,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,GAClB,IAAI,CA2CN"}
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;EAYlC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,eAAe,EAAE;;;;;;;;;;EAG5F;AA4FD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAQlF;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,GAAG,KAAK,EAC3B,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,GAClB,IAAI,CA0CN"}
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validationErrorBody = validationErrorBody;
4
4
  exports.legacyValidationErrorBody = legacyValidationErrorBody;
5
+ exports.notFoundHandler = notFoundHandler;
5
6
  exports.errorHandler = errorHandler;
6
7
  const core_1 = require("@stratum-hq/core");
7
- const config_js_1 = require("../config.js");
8
8
  /**
9
9
  * Returns the body of a 400 VALIDATION_ERROR response.
10
10
  * The issues go in `error.details.issues`, next to any other details.
@@ -94,11 +94,32 @@ function clientErrorCode(error) {
94
94
  return core_1.ErrorCode.VALIDATION_ERROR;
95
95
  return CLIENT_ERROR_CODES[error.statusCode] ?? "BAD_REQUEST";
96
96
  }
97
+ /**
98
+ * Logs an error that the API answers with a 5xx status, in every environment.
99
+ * The request logger adds the request id (reqId), so a report from a client
100
+ * can be matched to the log line.
101
+ */
102
+ function logServerError(request, error) {
103
+ request.log.error({ err: error }, "request failed with a server error");
104
+ }
105
+ /**
106
+ * Answers a request that matches no route with the error envelope of every
107
+ * other error. The global hooks run first, so a caller without credentials
108
+ * gets 401 and only an authenticated caller learns that the route is unknown.
109
+ */
110
+ function notFoundHandler(request, reply) {
111
+ const path = request.url.split("?")[0];
112
+ reply.status(404).send({
113
+ error: {
114
+ code: "NOT_FOUND",
115
+ message: `Route ${request.method} ${path} not found`,
116
+ },
117
+ });
118
+ }
97
119
  function errorHandler(error, request, reply) {
98
- if (config_js_1.config.nodeEnv === "development") {
99
- console.error("[error]", error);
100
- }
101
120
  if (isStratumError(error)) {
121
+ if (error.statusCode >= 500)
122
+ logServerError(request, error);
102
123
  const issues = error.details?.issues;
103
124
  if (error.code === core_1.ErrorCode.VALIDATION_ERROR && isIssueList(issues)) {
104
125
  reply.status(error.statusCode).send(validationErrorBody(error.message, issues, error.details));
@@ -127,6 +148,8 @@ function errorHandler(error, request, reply) {
127
148
  });
128
149
  return;
129
150
  }
151
+ // The client gets no detail of the cause; the log has it, under the request id.
152
+ logServerError(request, error);
130
153
  reply.status(500).send({
131
154
  error: {
132
155
  code: "INTERNAL_SERVER_ERROR",
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
2
+ /**
3
+ * Path parameters that hold the id of a database row. Every such id is a UUID.
4
+ * The other path parameters (a config `:key`, a consent `:purpose`) are free text.
5
+ */
6
+ export declare const UUID_PATH_PARAMS: ReadonlySet<string>;
7
+ /** Returns the names of the path parameters in a route URL, such as `id` in `/tenants/:id`. */
8
+ export declare function pathParamNames(url: string): string[];
9
+ /**
10
+ * Gives every route registered after this call a params schema that requires a
11
+ * UUID for each id parameter in its URL.
12
+ *
13
+ * The route keeps a failed check on the request (attachValidation) instead of
14
+ * answering at once. {@link rejectInvalidPathParams} answers it after the
15
+ * caller is authenticated, so a caller without credentials still gets 401.
16
+ */
17
+ export declare function registerUuidPathParams(app: FastifyInstance): void;
18
+ /**
19
+ * A global preHandler, registered after authentication: answers a request whose
20
+ * schema check failed with 400 VALIDATION_ERROR, one issue per bad path id.
21
+ */
22
+ export declare function rejectInvalidPathParams(request: FastifyRequest, _reply: FastifyReply): Promise<void>;
23
+ /** Query-string parameters that hold a tenant id. Every such id is a UUID. */
24
+ export declare const UUID_QUERY_PARAMS: readonly string[];
25
+ /**
26
+ * A global preHandler, registered after authentication and before the tenant
27
+ * scope enforcer: answers a request whose query string carries a tenant id that
28
+ * is not a single UUID with 400 VALIDATION_ERROR, one issue per bad parameter.
29
+ */
30
+ export declare function rejectInvalidQueryTenantIds(request: FastifyRequest, _reply: FastifyReply): Promise<void>;
31
+ //# sourceMappingURL=path-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-params.d.ts","sourceRoot":"","sources":["../../src/middleware/path-params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGxE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAkE,CAAC;AAIpH,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAmBjE;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1G;AAED,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA0C,CAAC;AAI1F;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ9G"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UUID_QUERY_PARAMS = exports.UUID_PATH_PARAMS = void 0;
4
+ exports.pathParamNames = pathParamNames;
5
+ exports.registerUuidPathParams = registerUuidPathParams;
6
+ exports.rejectInvalidPathParams = rejectInvalidPathParams;
7
+ exports.rejectInvalidQueryTenantIds = rejectInvalidQueryTenantIds;
8
+ const core_1 = require("@stratum-hq/core");
9
+ /**
10
+ * Path parameters that hold the id of a database row. Every such id is a UUID.
11
+ * The other path parameters (a config `:key`, a consent `:purpose`) are free text.
12
+ */
13
+ exports.UUID_PATH_PARAMS = new Set(["id", "tenantId", "policyId", "keyId", "deliveryId"]);
14
+ const UUID_PATTERN = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$";
15
+ /** Returns the names of the path parameters in a route URL, such as `id` in `/tenants/:id`. */
16
+ function pathParamNames(url) {
17
+ return [...url.matchAll(/:([A-Za-z0-9_]+)/g)].map((match) => match[1]);
18
+ }
19
+ /**
20
+ * Gives every route registered after this call a params schema that requires a
21
+ * UUID for each id parameter in its URL.
22
+ *
23
+ * The route keeps a failed check on the request (attachValidation) instead of
24
+ * answering at once. {@link rejectInvalidPathParams} answers it after the
25
+ * caller is authenticated, so a caller without credentials still gets 401.
26
+ */
27
+ function registerUuidPathParams(app) {
28
+ app.addHook("onRoute", (routeOptions) => {
29
+ const names = pathParamNames(routeOptions.url ?? "").filter((name) => exports.UUID_PATH_PARAMS.has(name));
30
+ if (names.length === 0)
31
+ return;
32
+ const existing = (routeOptions.schema?.params ?? {});
33
+ routeOptions.schema = {
34
+ ...routeOptions.schema,
35
+ params: {
36
+ type: "object",
37
+ ...existing,
38
+ properties: {
39
+ ...existing.properties,
40
+ ...Object.fromEntries(names.map((name) => [name, { type: "string", format: "uuid", pattern: UUID_PATTERN }])),
41
+ },
42
+ required: [...new Set([...(existing.required ?? []), ...names])],
43
+ },
44
+ };
45
+ routeOptions.attachValidation = true;
46
+ });
47
+ }
48
+ /**
49
+ * A global preHandler, registered after authentication: answers a request whose
50
+ * schema check failed with 400 VALIDATION_ERROR, one issue per bad path id.
51
+ */
52
+ async function rejectInvalidPathParams(request, _reply) {
53
+ const failure = request.validationError;
54
+ if (!failure)
55
+ return;
56
+ if (failure.validationContext !== "params")
57
+ throw failure;
58
+ const names = new Set((failure.validation ?? []).map((item) => item.instancePath?.replace(/^\//, "") || item.params?.missingProperty || ""));
59
+ const issues = [...names].map((name) => ({ path: ["params", name], message: "Invalid uuid", code: "invalid_string" }));
60
+ throw new core_1.ValidationError("Invalid path parameter", { issues });
61
+ }
62
+ /** Query-string parameters that hold a tenant id. Every such id is a UUID. */
63
+ exports.UUID_QUERY_PARAMS = ["tenant_id", "tenant_a", "tenant_b"];
64
+ const UUID_REGEX = new RegExp(UUID_PATTERN);
65
+ /**
66
+ * A global preHandler, registered after authentication and before the tenant
67
+ * scope enforcer: answers a request whose query string carries a tenant id that
68
+ * is not a single UUID with 400 VALIDATION_ERROR, one issue per bad parameter.
69
+ */
70
+ async function rejectInvalidQueryTenantIds(request, _reply) {
71
+ const query = (request.query ?? {});
72
+ const bad = exports.UUID_QUERY_PARAMS.filter((name) => query[name] !== undefined && !(typeof query[name] === "string" && UUID_REGEX.test(query[name])));
73
+ if (bad.length === 0)
74
+ return;
75
+ const issues = bad.map((name) => ({ path: ["query", name], message: "Invalid uuid", code: "invalid_string" }));
76
+ throw new core_1.ValidationError("Invalid query parameter", { issues });
77
+ }
78
+ //# sourceMappingURL=path-params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-params.js","sourceRoot":"","sources":["../../src/middleware/path-params.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config-diff.d.ts","sourceRoot":"","sources":["../../src/routes/config-diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAS1C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,IAMd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAqC5E"}
1
+ {"version":3,"file":"config-diff.d.ts","sourceRoot":"","sources":["../../src/routes/config-diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAU1C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,IAMd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAqC5E"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createConfigDiffRoutes = createConfigDiffRoutes;
4
4
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
5
5
  const authorize_js_1 = require("../middleware/authorize.js");
6
+ const config_js_1 = require("./config.js");
6
7
  function createConfigDiffRoutes(stratum) {
7
8
  // The diff compares two tenants read from the query string, so both operands
8
9
  // must be authorized against the caller's subtree. The scope declaration below
@@ -33,7 +34,7 @@ function createConfigDiffRoutes(stratum) {
33
34
  });
34
35
  return;
35
36
  }
36
- const diff = await stratum.diffConfig(tenant_a, tenant_b);
37
+ const diff = await stratum.diffConfig(tenant_a, tenant_b, (0, config_js_1.configReadOptions)(request));
37
38
  reply.status(200).send(diff);
38
39
  });
39
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config-diff.js","sourceRoot":"","sources":["../../src/routes/config-diff.ts"],"names":[],"mappings":";;AAUA,wDA2CC;AAnDD,mEAKuC;AACvC,6DAAkE;AAElE,SAAgB,sBAAsB,CAAC,OAAgB;IACrD,6EAA6E;IAC7E,+EAA+E;IAC/E,0DAA0D;IAC1D,MAAM,kBAAkB,GAAG,IAAA,wCAAsB,EAAC,OAAO,EAAE,kCAAgB,CAAC,CAAC;IAE7E,OAAO,KAAK,UAAU,gBAAgB,CAAC,GAAoB;QACzD,6EAA6E;QAC7E,IAAA,oCAAkB,EAAC,GAAG,EAAE,kCAAgB,CAAC,CAAC;QAC1C,IAAA,mCAAoB,EAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAE5D,mGAAmG;QACnG,GAAG,CAAC,GAAG,CACL,OAAO,EACP,EAAE,UAAU,EAAE,kBAAkB,EAAE,EAClC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;YAE7C,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACrB,KAAK,EAAE;wBACL,IAAI,EAAE,kBAAkB;wBACxB,OAAO,EAAE,0DAA0D;qBACpE;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACrB,KAAK,EAAE;wBACL,IAAI,EAAE,kBAAkB;wBACxB,OAAO,EAAE,yCAAyC;qBACnD;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC1D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config-diff.js","sourceRoot":"","sources":["../../src/routes/config-diff.ts"],"names":[],"mappings":";;AAWA,wDA2CC;AApDD,mEAKuC;AACvC,6DAAkE;AAClE,2CAAgD;AAEhD,SAAgB,sBAAsB,CAAC,OAAgB;IACrD,6EAA6E;IAC7E,+EAA+E;IAC/E,0DAA0D;IAC1D,MAAM,kBAAkB,GAAG,IAAA,wCAAsB,EAAC,OAAO,EAAE,kCAAgB,CAAC,CAAC;IAE7E,OAAO,KAAK,UAAU,gBAAgB,CAAC,GAAoB;QACzD,6EAA6E;QAC7E,IAAA,oCAAkB,EAAC,GAAG,EAAE,kCAAgB,CAAC,CAAC;QAC1C,IAAA,mCAAoB,EAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAE5D,mGAAmG;QACnG,GAAG,CAAC,GAAG,CACL,OAAO,EACP,EAAE,UAAU,EAAE,kBAAkB,EAAE,EAClC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;YAE7C,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACrB,KAAK,EAAE;wBACL,IAAI,EAAE,kBAAkB;wBACxB,OAAO,EAAE,0DAA0D;qBACpE;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACrB,KAAK,EAAE;wBACL,IAAI,EAAE,kBAAkB;wBACxB,OAAO,EAAE,yCAAyC;qBACnD;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAA,6BAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YACtF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -1,4 +1,14 @@
1
- import { FastifyInstance } from "fastify";
1
+ import { FastifyInstance, FastifyRequest } from "fastify";
2
+ import { type ResolveConfigOptions } from "@stratum-hq/core";
2
3
  import { Stratum } from "@stratum-hq/lib";
4
+ /**
5
+ * Library read options for a config read made by `request`'s caller.
6
+ *
7
+ * A sensitive value inherited from an ancestor is revealed only to a caller
8
+ * whose key belongs to the tenant that set it. A global key is not that
9
+ * tenant, so it gets no viewer and those values stay masked. The API never
10
+ * asks the library to reveal every sensitive value.
11
+ */
12
+ export declare function configReadOptions(request: FastifyRequest): ResolveConfigOptions;
3
13
  export declare function createConfigRoutes(stratum: Stratum): (app: FastifyInstance) => Promise<void>;
4
14
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAiDxE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAKL,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAuD1C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,oBAAoB,CAG/E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAwFxE"}
@@ -1,10 +1,70 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configReadOptions = configReadOptions;
3
4
  exports.createConfigRoutes = createConfigRoutes;
4
5
  const core_1 = require("@stratum-hq/core");
5
6
  const audit_logs_js_1 = require("./audit-logs.js");
6
7
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
7
8
  const authorize_js_1 = require("../middleware/authorize.js");
9
+ const error_handler_js_1 = require("../middleware/error-handler.js");
10
+ /** The library's reason for an entry that an ancestor's lock refused. */
11
+ const LOCKED_REASON = /is locked by tenant/;
12
+ /**
13
+ * The result of a batch that nothing was written for: every entry failed,
14
+ * with its own reason when it has one.
15
+ */
16
+ function rolledBackResult(keys, reasons) {
17
+ const failedKeys = [...reasons.keys()].map((i) => `'${keys[i]}'`).join(", ");
18
+ return {
19
+ results: keys.map((key, i) => ({
20
+ key,
21
+ status: "error",
22
+ error: reasons.get(i) ?? `Not applied: the batch was rolled back because ${failedKeys} failed`,
23
+ })),
24
+ succeeded: 0,
25
+ failed: keys.length,
26
+ rolled_back: true,
27
+ };
28
+ }
29
+ /**
30
+ * Checks every batch entry and returns the issues, with paths under `entries`.
31
+ * The library refuses the same entries, but checking here keeps them away from it.
32
+ */
33
+ function batchEntryIssues(entries) {
34
+ const issues = [];
35
+ entries.forEach((raw, i) => {
36
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
37
+ issues.push({ path: ["entries", i], message: "Expected object", code: "invalid_type" });
38
+ return;
39
+ }
40
+ const entry = raw;
41
+ if (typeof entry.key !== "string" || entry.key.length === 0) {
42
+ issues.push({ path: ["entries", i, "key"], message: "Config key must be a non-empty string", code: "invalid_type" });
43
+ }
44
+ if (entry.value === undefined) {
45
+ issues.push({ path: ["entries", i, "value"], message: "Required", code: "invalid_type" });
46
+ }
47
+ const parsed = core_1.SetConfigInputSchema.safeParse(entry);
48
+ if (!parsed.success) {
49
+ for (const issue of parsed.error.issues) {
50
+ issues.push({ path: ["entries", i, ...issue.path], message: issue.message, code: issue.code });
51
+ }
52
+ }
53
+ });
54
+ return issues;
55
+ }
56
+ /**
57
+ * Library read options for a config read made by `request`'s caller.
58
+ *
59
+ * A sensitive value inherited from an ancestor is revealed only to a caller
60
+ * whose key belongs to the tenant that set it. A global key is not that
61
+ * tenant, so it gets no viewer and those values stay masked. The API never
62
+ * asks the library to reveal every sensitive value.
63
+ */
64
+ function configReadOptions(request) {
65
+ const viewerTenantId = request.apiKey?.tenant_id;
66
+ return viewerTenantId ? { viewerTenantId } : {};
67
+ }
8
68
  function createConfigRoutes(stratum) {
9
69
  return async function configRoutes(app) {
10
70
  // Tenant-scoped keys can only access config for their own tenant subtree
@@ -12,7 +72,7 @@ function createConfigRoutes(stratum) {
12
72
  (0, authorize_js_1.declareRequiredScope)(app, { read: "read", write: "write" });
13
73
  // GET /api/v1/tenants/:id/config: Get resolved config
14
74
  app.get("/", async (request, reply) => {
15
- const resolved = await stratum.resolveConfig(request.params.id);
75
+ const resolved = await stratum.resolveConfig(request.params.id, configReadOptions(request));
16
76
  reply.status(200).send(resolved);
17
77
  });
18
78
  // PUT /api/v1/tenants/:id/config/:key: Set config value
@@ -37,17 +97,57 @@ function createConfigRoutes(stratum) {
37
97
  reply.status(400).send({ error: { code: "VALIDATION_ERROR", message: "Batch limited to 200 entries" } });
38
98
  return;
39
99
  }
100
+ const keys = body.entries.map((e) => {
101
+ const key = e?.key;
102
+ return typeof key === "string" ? key : "";
103
+ });
104
+ const issues = batchEntryIssues(body.entries);
105
+ if (issues.length > 0) {
106
+ const reasons = new Map();
107
+ for (const issue of issues) {
108
+ const i = issue.path[1];
109
+ if (!reasons.has(i))
110
+ reasons.set(i, issue.message);
111
+ }
112
+ reply.status(400).send((0, error_handler_js_1.validationErrorBody)("Validation failed", issues, { ...rolledBackResult(keys, reasons) }));
113
+ return;
114
+ }
40
115
  const entries = body.entries.map((e) => {
41
116
  const parsed = core_1.SetConfigInputSchema.parse(e);
42
117
  const entry = e;
43
118
  return { key: entry.key, value: parsed.value, locked: parsed.locked, sensitive: parsed.sensitive };
44
119
  });
45
120
  const batchResult = await stratum.batchSetConfig(request.params.id, entries, (0, audit_logs_js_1.buildAuditContext)(request));
121
+ if (batchResult.rolled_back) {
122
+ // Nothing was written. A lock gets the status of a single locked write.
123
+ const refused = batchResult.results
124
+ .map((result, i) => ({ result, i }))
125
+ .filter(({ result }) => result.error && !result.error.startsWith("Not applied:"));
126
+ const locked = refused.filter(({ result }) => LOCKED_REASON.test(result.error ?? ""));
127
+ if (locked.length > 0) {
128
+ const lockedKeys = locked.map(({ result }) => `'${result.key}'`).join(", ");
129
+ reply.status(403).send({
130
+ error: {
131
+ code: core_1.ErrorCode.CONFIG_LOCKED,
132
+ message: `The batch was rolled back and nothing was written: ${lockedKeys} locked by an ancestor`,
133
+ details: { ...batchResult },
134
+ },
135
+ });
136
+ return;
137
+ }
138
+ const refusedIssues = refused.map(({ result, i }) => ({
139
+ path: ["entries", i],
140
+ message: result.error,
141
+ code: "custom",
142
+ }));
143
+ reply.status(400).send((0, error_handler_js_1.validationErrorBody)("Validation failed", refusedIssues, { ...batchResult }));
144
+ return;
145
+ }
46
146
  reply.status(200).send(batchResult);
47
147
  });
48
148
  // GET /api/v1/tenants/:id/config/inheritance: Get full inheritance view
49
149
  app.get("/inheritance", async (request, reply) => {
50
- const inheritance = await stratum.getConfigWithInheritance(request.params.id);
150
+ const inheritance = await stratum.getConfigWithInheritance(request.params.id, configReadOptions(request));
51
151
  reply.status(200).send(inheritance);
52
152
  });
53
153
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG1C,KAAK,kBAAkB,GAAG,MAAM,OAAO,CAAC,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC,CAAC;AAEzF;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,gBAAgB,EAAE,kBAAkB,IAEK,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAsB9E"}
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAY1C,KAAK,kBAAkB,GAAG,MAAM,OAAO,CAAC,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC,CAAC;AAEzF;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,gBAAgB,EAAE,kBAAkB,IAEK,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAkB9E"}
@@ -2,6 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.healthRoutes = healthRoutes;
4
4
  const connection_js_1 = require("../db/connection.js");
5
+ async function poolStatus(pool) {
6
+ try {
7
+ await pool.query("SELECT 1");
8
+ return "connected";
9
+ }
10
+ catch {
11
+ return "disconnected";
12
+ }
13
+ }
5
14
  /**
6
15
  * Health routes factory. Accepts an optional Redis health checker so the
7
16
  * health endpoint can report Redis status without a hard dependency on it.
@@ -9,20 +18,16 @@ const connection_js_1 = require("../db/connection.js");
9
18
  function healthRoutes(checkRedisHealth) {
10
19
  return async function healthRoutesPlugin(app) {
11
20
  app.get("/api/v1/health", async (_request, reply) => {
12
- let dbStatus = "disconnected";
13
- try {
14
- const pool = (0, connection_js_1.getPool)();
15
- await pool.query("SELECT 1");
16
- dbStatus = "connected";
17
- }
18
- catch {
19
- dbStatus = "disconnected";
20
- }
21
+ const dbStatus = await poolStatus((0, connection_js_1.getPool)());
22
+ // Reported only when DATABASE_ADMIN_URL is set.
23
+ const adminPool = (0, connection_js_1.getAdminPool)();
24
+ const adminStatus = adminPool ? await poolStatus(adminPool) : undefined;
21
25
  const redisStatus = await checkRedisHealth();
22
26
  reply.status(200).send({
23
27
  status: "ok",
24
28
  timestamp: new Date().toISOString(),
25
29
  db: dbStatus,
30
+ ...(adminStatus ? { admin_db: adminStatus } : {}),
26
31
  redis: redisStatus,
27
32
  });
28
33
  });
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":";;AASA,oCAyBC;AAjCD,uDAA8C;AAI9C;;;GAGG;AACH,SAAgB,YAAY,CAC1B,gBAAoC;IAEpC,OAAO,KAAK,UAAU,kBAAkB,CAAC,GAAoB;QAC3D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAClD,IAAI,QAAQ,GAAiC,cAAc,CAAC;YAE5D,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAA,uBAAO,GAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC7B,QAAQ,GAAG,WAAW,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,cAAc,CAAC;YAC5B,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,gBAAgB,EAAE,CAAC;YAE7C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACrB,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":";;AAkBA,oCAqBC;AAtCD,uDAA4D;AAE5D,KAAK,UAAU,UAAU,CAAC,IAAkD;IAC1E,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7B,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC;AAID;;;GAGG;AACH,SAAgB,YAAY,CAC1B,gBAAoC;IAEpC,OAAO,KAAK,UAAU,kBAAkB,CAAC,GAAoB;QAC3D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAClD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAA,uBAAO,GAAE,CAAC,CAAC;YAC7C,gDAAgD;YAChD,MAAM,SAAS,GAAG,IAAA,4BAAY,GAAE,CAAC;YACjC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAExE,MAAM,WAAW,GAAG,MAAM,gBAAgB,EAAE,CAAC;YAE7C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACrB,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,EAAE,EAAE,QAAQ;gBACZ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAe1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAY1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IAYd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAoOxE"}
1
+ {"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAe1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAa1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IAYd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAyOxE"}
@@ -8,6 +8,7 @@ const audit_logs_js_1 = require("./audit-logs.js");
8
8
  const error_handler_js_1 = require("../middleware/error-handler.js");
9
9
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
10
10
  const authorize_js_1 = require("../middleware/authorize.js");
11
+ const config_js_1 = require("./config.js");
11
12
  function createTenantRoutes(stratum) {
12
13
  // A move must authorize BOTH ends. The plugin-level guard below only covers
13
14
  // `:id`, the tenant being moved, which a scoped key already owns and which
@@ -214,9 +215,11 @@ function createTenantRoutes(stratum) {
214
215
  const data = await stratum.exportTenantData(request.params.id);
215
216
  reply.status(200).send(data);
216
217
  });
217
- // GET /api/v1/tenants/:id/context: Resolve the flat ResolvedTenantContext (admin scope)
218
- app.get("/:id/context", { config: { requiredScope: "admin" } }, async (request, reply) => {
219
- const { tenant, config, permissions } = await stratum.getTenantContext(request.params.id);
218
+ // GET /api/v1/tenants/:id/context: Resolve the flat ResolvedTenantContext.
219
+ // Read scope: the SDK middleware calls this on every request, so an app
220
+ // server needs only a read key for the tenants its key scope reaches.
221
+ app.get("/:id/context", { config: { requiredScope: "read" } }, async (request, reply) => {
222
+ const { tenant, config, permissions } = await stratum.getTenantContext(request.params.id, (0, config_js_1.configReadOptions)(request));
220
223
  const context = {
221
224
  tenant_id: tenant.id,
222
225
  ancestry_path: tenant.ancestry_path,
@@ -1 +1 @@
1
- {"version":3,"file":"tenants.js","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenants.js","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"isolation-service.d.ts","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":"AAsBA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAErD;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjF"}
1
+ {"version":3,"file":"isolation-service.d.ts","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":"AAsBA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAErD;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD;AAQD,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjF"}
@@ -43,8 +43,13 @@ async function setupAllRLS() {
43
43
  await setupRLSForTable(tableName);
44
44
  }
45
45
  }
46
+ // Schemas and databases of isolated tenants are created and dropped on the
47
+ // admin pool when DATABASE_ADMIN_URL is set (it needs CREATE on the database,
48
+ // or CREATEDB), else on the application pool. The table-level RLS helpers
49
+ // above change application tables, so they run as the application login,
50
+ // which owns them.
46
51
  async function setupSchemaForTenant(tenantSlug, tables) {
47
- return (0, lib_1.withTransaction)((0, connection_js_1.getPool)(), async (client) => {
52
+ return (0, lib_1.withTransaction)((0, connection_js_1.getStratumPool)(), async (client) => {
48
53
  await (0, db_adapters_1.createSchema)(client, tenantSlug);
49
54
  if (tables && tables.length > 0) {
50
55
  const schemaName = (0, db_adapters_1.tenantSchemaName)(tenantSlug);
@@ -55,7 +60,7 @@ async function setupSchemaForTenant(tenantSlug, tables) {
55
60
  });
56
61
  }
57
62
  async function teardownSchemaForTenant(tenantSlug) {
58
- return (0, lib_1.withTransaction)((0, connection_js_1.getPool)(), async (client) => {
63
+ return (0, lib_1.withTransaction)((0, connection_js_1.getStratumPool)(), async (client) => {
59
64
  await (0, db_adapters_1.dropSchema)(client, tenantSlug);
60
65
  });
61
66
  }
@@ -66,7 +71,7 @@ async function teardownSchemaForTenant(tenantSlug) {
66
71
  * standalone client from the pool (no BEGIN/COMMIT wrapping).
67
72
  */
68
73
  async function setupDatabaseForTenant(tenantSlug, templateDb) {
69
- const pool = (0, connection_js_1.getPool)();
74
+ const pool = (0, connection_js_1.getStratumPool)();
70
75
  const client = await pool.connect();
71
76
  try {
72
77
  // Never adopt an existing database: it may hold another tenant's data.
@@ -88,7 +93,7 @@ async function setupDatabaseForTenant(tenantSlug, templateDb) {
88
93
  * standalone client from the pool.
89
94
  */
90
95
  async function teardownDatabaseForTenant(tenantSlug) {
91
- const client = await (0, connection_js_1.getPool)().connect();
96
+ const client = await (0, connection_js_1.getStratumPool)().connect();
92
97
  try {
93
98
  await (0, db_adapters_1.dropDatabase)(client, tenantSlug);
94
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"isolation-service.js","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"isolation-service.js","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stratum-hq/control-plane",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Multi-tenancy REST API server (Fastify): tenants, config, permissions, API keys, webhooks, and audit over HTTP",
5
5
  "keywords": [
6
6
  "multi-tenancy",
@@ -54,8 +54,8 @@
54
54
  "@fastify/rate-limit": "^10.2.0",
55
55
  "@fastify/swagger": "^9.9.0",
56
56
  "@fastify/swagger-ui": "^6.1.1",
57
- "@stratum-hq/core": "^1.5.1",
58
- "@stratum-hq/lib": "^1.7.0",
57
+ "@stratum-hq/core": "^1.6.0",
58
+ "@stratum-hq/lib": "^1.8.0",
59
59
  "fastify": "^5.12.5",
60
60
  "jsonwebtoken": "^9.0.0",
61
61
  "ioredis": "^5.4.0",