@stratum-hq/control-plane 0.1.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/__tests__/api-keys.test.d.ts +2 -0
- package/dist/__tests__/api-keys.test.d.ts.map +1 -0
- package/dist/__tests__/api-keys.test.js +240 -0
- package/dist/__tests__/api-keys.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +2 -0
- package/dist/__tests__/auth.test.d.ts.map +1 -0
- package/dist/__tests__/auth.test.js +227 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +201 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/tenants.test.d.ts +2 -0
- package/dist/__tests__/tenants.test.d.ts.map +1 -0
- package/dist/__tests__/tenants.test.js +214 -0
- package/dist/__tests__/tenants.test.js.map +1 -0
- package/dist/__tests__/test-helpers.d.ts +71 -0
- package/dist/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/__tests__/test-helpers.js +172 -0
- package/dist/__tests__/test-helpers.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +114 -0
- package/dist/app.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +26 -0
- package/dist/config.js.map +1 -0
- package/dist/db/connection.d.ts +4 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +30 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/migrate.d.ts +3 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +56 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/regional-pool-router.d.ts +9 -0
- package/dist/db/regional-pool-router.d.ts.map +1 -0
- package/dist/db/regional-pool-router.js +29 -0
- package/dist/db/regional-pool-router.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +21 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +70 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/authorize.d.ts +3 -0
- package/dist/middleware/authorize.d.ts.map +1 -0
- package/dist/middleware/authorize.js +54 -0
- package/dist/middleware/authorize.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +3 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +48 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/per-key-rate-limit.d.ts +3 -0
- package/dist/middleware/per-key-rate-limit.d.ts.map +1 -0
- package/dist/middleware/per-key-rate-limit.js +62 -0
- package/dist/middleware/per-key-rate-limit.js.map +1 -0
- package/dist/middleware/rate-limit-redis.d.ts +16 -0
- package/dist/middleware/rate-limit-redis.d.ts.map +1 -0
- package/dist/middleware/rate-limit-redis.js +118 -0
- package/dist/middleware/rate-limit-redis.js.map +1 -0
- package/dist/middleware/telemetry.d.ts +14 -0
- package/dist/middleware/telemetry.d.ts.map +1 -0
- package/dist/middleware/telemetry.js +81 -0
- package/dist/middleware/telemetry.js.map +1 -0
- package/dist/middleware/tenant-scope.d.ts +20 -0
- package/dist/middleware/tenant-scope.d.ts.map +1 -0
- package/dist/middleware/tenant-scope.js +60 -0
- package/dist/middleware/tenant-scope.js.map +1 -0
- package/dist/openapi.d.ts +3 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +44 -0
- package/dist/openapi.js.map +1 -0
- package/dist/redis.d.ts +16 -0
- package/dist/redis.d.ts.map +1 -0
- package/dist/redis.js +71 -0
- package/dist/redis.js.map +1 -0
- package/dist/routes/api-keys.d.ts +4 -0
- package/dist/routes/api-keys.d.ts.map +1 -0
- package/dist/routes/api-keys.js +78 -0
- package/dist/routes/api-keys.js.map +1 -0
- package/dist/routes/audit-logs.d.ts +6 -0
- package/dist/routes/audit-logs.d.ts.map +1 -0
- package/dist/routes/audit-logs.js +43 -0
- package/dist/routes/audit-logs.js.map +1 -0
- package/dist/routes/config-diff.d.ts +4 -0
- package/dist/routes/config-diff.d.ts.map +1 -0
- package/dist/routes/config-diff.js +33 -0
- package/dist/routes/config-diff.js.map +1 -0
- package/dist/routes/config.d.ts +4 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +54 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/consent.d.ts +4 -0
- package/dist/routes/consent.d.ts.map +1 -0
- package/dist/routes/consent.js +45 -0
- package/dist/routes/consent.js.map +1 -0
- package/dist/routes/health.d.ts +9 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +32 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/maintenance.d.ts +4 -0
- package/dist/routes/maintenance.d.ts.map +1 -0
- package/dist/routes/maintenance.js +35 -0
- package/dist/routes/maintenance.js.map +1 -0
- package/dist/routes/permissions.d.ts +4 -0
- package/dist/routes/permissions.d.ts.map +1 -0
- package/dist/routes/permissions.js +36 -0
- package/dist/routes/permissions.js.map +1 -0
- package/dist/routes/regions.d.ts +4 -0
- package/dist/routes/regions.d.ts.map +1 -0
- package/dist/routes/regions.js +38 -0
- package/dist/routes/regions.js.map +1 -0
- package/dist/routes/roles.d.ts +4 -0
- package/dist/routes/roles.d.ts.map +1 -0
- package/dist/routes/roles.js +95 -0
- package/dist/routes/roles.js.map +1 -0
- package/dist/routes/tenants.d.ts +4 -0
- package/dist/routes/tenants.d.ts.map +1 -0
- package/dist/routes/tenants.js +112 -0
- package/dist/routes/tenants.js.map +1 -0
- package/dist/routes/webhooks.d.ts +4 -0
- package/dist/routes/webhooks.d.ts.map +1 -0
- package/dist/routes/webhooks.js +116 -0
- package/dist/routes/webhooks.js.map +1 -0
- package/dist/services/isolation-service.d.ts +22 -0
- package/dist/services/isolation-service.d.ts.map +1 -0
- package/dist/services/isolation-service.js +94 -0
- package/dist/services/isolation-service.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SAMPLE_CHILD_TENANT = exports.SAMPLE_TENANT = exports.setupWriteApiKey = exports.setupReadOnlyApiKey = exports.setupAdminApiKey = exports.jwtHeaders = exports.authHeaders = exports.buildTestApp = exports.createMockStratum = exports.TEST_JWT_SECRET = void 0;
|
|
7
|
+
const fastify_1 = __importDefault(require("fastify"));
|
|
8
|
+
const vitest_1 = require("vitest");
|
|
9
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
10
|
+
const error_handler_js_1 = require("../middleware/error-handler.js");
|
|
11
|
+
const auth_js_1 = require("../middleware/auth.js");
|
|
12
|
+
const authorize_js_1 = require("../middleware/authorize.js");
|
|
13
|
+
const health_js_1 = require("../routes/health.js");
|
|
14
|
+
const tenants_js_1 = require("../routes/tenants.js");
|
|
15
|
+
const config_js_1 = require("../routes/config.js");
|
|
16
|
+
const api_keys_js_1 = require("../routes/api-keys.js");
|
|
17
|
+
// The JWT secret used in dev mode (from config.ts fallback)
|
|
18
|
+
exports.TEST_JWT_SECRET = "dev-secret-change-in-production";
|
|
19
|
+
/**
|
|
20
|
+
* Create a mock Stratum instance with all methods stubbed via vi.fn().
|
|
21
|
+
* Tests override individual method implementations as needed.
|
|
22
|
+
*/
|
|
23
|
+
function createMockStratum() {
|
|
24
|
+
return {
|
|
25
|
+
// Tenant methods
|
|
26
|
+
createTenant: vitest_1.vi.fn(),
|
|
27
|
+
getTenant: vitest_1.vi.fn(),
|
|
28
|
+
listTenants: vitest_1.vi.fn(),
|
|
29
|
+
updateTenant: vitest_1.vi.fn(),
|
|
30
|
+
deleteTenant: vitest_1.vi.fn(),
|
|
31
|
+
batchCreateTenants: vitest_1.vi.fn(),
|
|
32
|
+
moveTenant: vitest_1.vi.fn(),
|
|
33
|
+
getAncestors: vitest_1.vi.fn(),
|
|
34
|
+
getDescendants: vitest_1.vi.fn(),
|
|
35
|
+
getChildren: vitest_1.vi.fn(),
|
|
36
|
+
purgeTenant: vitest_1.vi.fn(),
|
|
37
|
+
exportTenantData: vitest_1.vi.fn(),
|
|
38
|
+
migrateRegion: vitest_1.vi.fn(),
|
|
39
|
+
// Config methods
|
|
40
|
+
resolveConfig: vitest_1.vi.fn(),
|
|
41
|
+
setConfig: vitest_1.vi.fn(),
|
|
42
|
+
deleteConfig: vitest_1.vi.fn(),
|
|
43
|
+
batchSetConfig: vitest_1.vi.fn(),
|
|
44
|
+
getConfigWithInheritance: vitest_1.vi.fn(),
|
|
45
|
+
// Permission methods
|
|
46
|
+
resolvePermissions: vitest_1.vi.fn(),
|
|
47
|
+
// API key methods
|
|
48
|
+
createApiKey: vitest_1.vi.fn(),
|
|
49
|
+
validateApiKey: vitest_1.vi.fn(),
|
|
50
|
+
revokeApiKey: vitest_1.vi.fn(),
|
|
51
|
+
rotateApiKey: vitest_1.vi.fn(),
|
|
52
|
+
listApiKeys: vitest_1.vi.fn(),
|
|
53
|
+
listDormantKeys: vitest_1.vi.fn(),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
exports.createMockStratum = createMockStratum;
|
|
57
|
+
/**
|
|
58
|
+
* Build a test Fastify app with routes registered and middleware wired up.
|
|
59
|
+
* Uses the provided mock Stratum instance.
|
|
60
|
+
*
|
|
61
|
+
* We skip OpenAPI/swagger, helmet, cors, and rate-limit plugins to keep tests fast
|
|
62
|
+
* and focused on the HTTP/route/middleware layer.
|
|
63
|
+
*/
|
|
64
|
+
async function buildTestApp(stratum) {
|
|
65
|
+
const app = (0, fastify_1.default)({ logger: false });
|
|
66
|
+
// Wire up the same middleware chain as the real app
|
|
67
|
+
app.addHook("preHandler", (0, auth_js_1.createAuthMiddleware)(stratum));
|
|
68
|
+
app.addHook("preHandler", (0, authorize_js_1.createAuthorizeMiddleware)());
|
|
69
|
+
app.setErrorHandler(error_handler_js_1.errorHandler);
|
|
70
|
+
// Register routes (pass a stub Redis health checker — Redis is not used in tests)
|
|
71
|
+
const noopRedisHealth = async () => "not_configured";
|
|
72
|
+
await app.register((0, health_js_1.healthRoutes)(noopRedisHealth));
|
|
73
|
+
await app.register((0, tenants_js_1.createTenantRoutes)(stratum), { prefix: "/api/v1/tenants" });
|
|
74
|
+
await app.register((0, config_js_1.createConfigRoutes)(stratum), { prefix: "/api/v1/tenants/:id/config" });
|
|
75
|
+
await app.register((0, api_keys_js_1.createApiKeyRoutes)(stratum), { prefix: "/api/v1/api-keys" });
|
|
76
|
+
await app.ready();
|
|
77
|
+
return app;
|
|
78
|
+
}
|
|
79
|
+
exports.buildTestApp = buildTestApp;
|
|
80
|
+
/**
|
|
81
|
+
* Helper: returns headers object with a valid API key authentication.
|
|
82
|
+
* The mock stratum.validateApiKey must be configured to accept this key.
|
|
83
|
+
*/
|
|
84
|
+
function authHeaders(apiKey = "sk_test_valid_key") {
|
|
85
|
+
return { "x-api-key": apiKey };
|
|
86
|
+
}
|
|
87
|
+
exports.authHeaders = authHeaders;
|
|
88
|
+
/**
|
|
89
|
+
* Helper: returns headers object with a valid JWT Bearer token.
|
|
90
|
+
*/
|
|
91
|
+
function jwtHeaders(payload = {}, secret = exports.TEST_JWT_SECRET) {
|
|
92
|
+
const token = jsonwebtoken_1.default.sign({
|
|
93
|
+
sub: "test-user-id",
|
|
94
|
+
scopes: ["read", "write", "admin"],
|
|
95
|
+
...payload,
|
|
96
|
+
}, secret, { algorithm: "HS256", expiresIn: "1h" });
|
|
97
|
+
return { authorization: `Bearer ${token}` };
|
|
98
|
+
}
|
|
99
|
+
exports.jwtHeaders = jwtHeaders;
|
|
100
|
+
/**
|
|
101
|
+
* Configure the mock stratum to accept the default test API key
|
|
102
|
+
* with admin scopes (read + write + admin). This is the common case.
|
|
103
|
+
*/
|
|
104
|
+
function setupAdminApiKey(stratum) {
|
|
105
|
+
stratum.validateApiKey.mockResolvedValue({
|
|
106
|
+
key_id: "test-key-id",
|
|
107
|
+
tenant_id: null,
|
|
108
|
+
scopes: ["read", "write", "admin"],
|
|
109
|
+
rate_limit_max: null,
|
|
110
|
+
rate_limit_window: null,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
exports.setupAdminApiKey = setupAdminApiKey;
|
|
114
|
+
/**
|
|
115
|
+
* Configure the mock stratum to accept the default test API key
|
|
116
|
+
* with read-only scope.
|
|
117
|
+
*/
|
|
118
|
+
function setupReadOnlyApiKey(stratum) {
|
|
119
|
+
stratum.validateApiKey.mockResolvedValue({
|
|
120
|
+
key_id: "test-key-id-readonly",
|
|
121
|
+
tenant_id: null,
|
|
122
|
+
scopes: ["read"],
|
|
123
|
+
rate_limit_max: null,
|
|
124
|
+
rate_limit_window: null,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
exports.setupReadOnlyApiKey = setupReadOnlyApiKey;
|
|
128
|
+
/**
|
|
129
|
+
* Configure the mock stratum to accept the default test API key
|
|
130
|
+
* with write scope (read + write but not admin).
|
|
131
|
+
*/
|
|
132
|
+
function setupWriteApiKey(stratum) {
|
|
133
|
+
stratum.validateApiKey.mockResolvedValue({
|
|
134
|
+
key_id: "test-key-id-write",
|
|
135
|
+
tenant_id: null,
|
|
136
|
+
scopes: ["read", "write"],
|
|
137
|
+
rate_limit_max: null,
|
|
138
|
+
rate_limit_window: null,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
exports.setupWriteApiKey = setupWriteApiKey;
|
|
142
|
+
/** A sample tenant object for test assertions */
|
|
143
|
+
exports.SAMPLE_TENANT = {
|
|
144
|
+
id: "t-uuid-1",
|
|
145
|
+
slug: "acme-corp",
|
|
146
|
+
name: "Acme Corp",
|
|
147
|
+
parent_id: null,
|
|
148
|
+
ancestry_path: "/t-uuid-1",
|
|
149
|
+
depth: 0,
|
|
150
|
+
metadata: {},
|
|
151
|
+
isolation_strategy: "SHARED_RLS",
|
|
152
|
+
region_id: null,
|
|
153
|
+
created_at: new Date("2025-01-01").toISOString(),
|
|
154
|
+
updated_at: new Date("2025-01-01").toISOString(),
|
|
155
|
+
deleted_at: null,
|
|
156
|
+
};
|
|
157
|
+
/** A second sample tenant (child) */
|
|
158
|
+
exports.SAMPLE_CHILD_TENANT = {
|
|
159
|
+
id: "t-uuid-2",
|
|
160
|
+
slug: "acme-division",
|
|
161
|
+
name: "Acme Division",
|
|
162
|
+
parent_id: "t-uuid-1",
|
|
163
|
+
ancestry_path: "/t-uuid-1/t-uuid-2",
|
|
164
|
+
depth: 1,
|
|
165
|
+
metadata: {},
|
|
166
|
+
isolation_strategy: "SHARED_RLS",
|
|
167
|
+
region_id: null,
|
|
168
|
+
created_at: new Date("2025-01-02").toISOString(),
|
|
169
|
+
updated_at: new Date("2025-01-02").toISOString(),
|
|
170
|
+
deleted_at: null,
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/__tests__/test-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA0CnD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAyEzD"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildApp = void 0;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
const fastify_1 = __importDefault(require("fastify"));
|
|
9
|
+
const cors_1 = __importDefault(require("@fastify/cors"));
|
|
10
|
+
const rate_limit_1 = __importDefault(require("@fastify/rate-limit"));
|
|
11
|
+
const helmet_1 = __importDefault(require("@fastify/helmet"));
|
|
12
|
+
const lib_1 = require("@stratum-hq/lib");
|
|
13
|
+
const openapi_js_1 = require("./openapi.js");
|
|
14
|
+
const error_handler_js_1 = require("./middleware/error-handler.js");
|
|
15
|
+
const auth_js_1 = require("./middleware/auth.js");
|
|
16
|
+
const authorize_js_1 = require("./middleware/authorize.js");
|
|
17
|
+
const per_key_rate_limit_js_1 = require("./middleware/per-key-rate-limit.js");
|
|
18
|
+
const rate_limit_redis_js_1 = require("./middleware/rate-limit-redis.js");
|
|
19
|
+
const redis_js_1 = require("./redis.js");
|
|
20
|
+
const health_js_1 = require("./routes/health.js");
|
|
21
|
+
const tenants_js_1 = require("./routes/tenants.js");
|
|
22
|
+
const config_js_1 = require("./routes/config.js");
|
|
23
|
+
const permissions_js_1 = require("./routes/permissions.js");
|
|
24
|
+
const api_keys_js_1 = require("./routes/api-keys.js");
|
|
25
|
+
const webhooks_js_1 = require("./routes/webhooks.js");
|
|
26
|
+
const audit_logs_js_1 = require("./routes/audit-logs.js");
|
|
27
|
+
const consent_js_1 = require("./routes/consent.js");
|
|
28
|
+
const maintenance_js_1 = require("./routes/maintenance.js");
|
|
29
|
+
const regions_js_1 = require("./routes/regions.js");
|
|
30
|
+
const roles_js_1 = require("./routes/roles.js");
|
|
31
|
+
const config_diff_js_1 = require("./routes/config-diff.js");
|
|
32
|
+
const telemetry_js_1 = require("./middleware/telemetry.js");
|
|
33
|
+
const config_js_2 = require("./config.js");
|
|
34
|
+
const connection_js_1 = require("./db/connection.js");
|
|
35
|
+
/** Parse a duration string like "1 minute" into milliseconds. */
|
|
36
|
+
function parseWindowForApp(window) {
|
|
37
|
+
const match = window.match(/^(\d+)\s*(second|minute|hour|day)s?$/i);
|
|
38
|
+
if (!match)
|
|
39
|
+
return 60_000;
|
|
40
|
+
const value = parseInt(match[1], 10);
|
|
41
|
+
switch (match[2].toLowerCase()) {
|
|
42
|
+
case "second": return value * 1_000;
|
|
43
|
+
case "minute": return value * 60_000;
|
|
44
|
+
case "hour": return value * 3_600_000;
|
|
45
|
+
case "day": return value * 86_400_000;
|
|
46
|
+
default: return 60_000;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function buildApp() {
|
|
50
|
+
const app = (0, fastify_1.default)({
|
|
51
|
+
logger: {
|
|
52
|
+
level: config_js_2.config.nodeEnv === "production" ? "info" : "debug",
|
|
53
|
+
redact: ["req.headers.authorization", "req.headers['x-api-key']"],
|
|
54
|
+
},
|
|
55
|
+
genReqId: () => node_crypto_1.default.randomUUID(),
|
|
56
|
+
});
|
|
57
|
+
const stratum = new lib_1.Stratum({
|
|
58
|
+
pool: (0, connection_js_1.getPool)(),
|
|
59
|
+
keyPrefix: config_js_2.config.nodeEnv === "production" ? "sk_live_" : "sk_test_",
|
|
60
|
+
});
|
|
61
|
+
await app.register(helmet_1.default, {
|
|
62
|
+
contentSecurityPolicy: {
|
|
63
|
+
directives: {
|
|
64
|
+
defaultSrc: ["'self'"],
|
|
65
|
+
scriptSrc: ["'self'", "'unsafe-inline'"],
|
|
66
|
+
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
67
|
+
imgSrc: ["'self'", "data:", "https://fastify.dev"],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
await app.register(cors_1.default, {
|
|
72
|
+
origin: config_js_2.config.allowedOrigins,
|
|
73
|
+
credentials: true,
|
|
74
|
+
});
|
|
75
|
+
await app.register(rate_limit_1.default, {
|
|
76
|
+
max: config_js_2.config.rateLimitMax,
|
|
77
|
+
timeWindow: config_js_2.config.rateLimitWindow,
|
|
78
|
+
});
|
|
79
|
+
// OpenTelemetry request tracing (no-op if @opentelemetry/api is absent)
|
|
80
|
+
(0, telemetry_js_1.registerTelemetryHooks)(app);
|
|
81
|
+
await (0, openapi_js_1.registerOpenApi)(app);
|
|
82
|
+
app.addHook("preHandler", (0, auth_js_1.createAuthMiddleware)(stratum));
|
|
83
|
+
app.addHook("preHandler", (0, authorize_js_1.createAuthorizeMiddleware)());
|
|
84
|
+
// Use Redis-backed rate limiting when REDIS_URL is configured, otherwise in-memory
|
|
85
|
+
const redisClient = (0, redis_js_1.createRedisClient)();
|
|
86
|
+
if (redisClient) {
|
|
87
|
+
const windowMs = parseWindowForApp(config_js_2.config.rateLimitWindow);
|
|
88
|
+
app.addHook("preHandler", (0, rate_limit_redis_js_1.createRedisRateLimiter)(redisClient, {
|
|
89
|
+
maxRequests: config_js_2.config.rateLimitMax,
|
|
90
|
+
windowMs,
|
|
91
|
+
}));
|
|
92
|
+
app.log.info("Per-key rate limiting: Redis-backed (REDIS_URL configured)");
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
app.addHook("preHandler", (0, per_key_rate_limit_js_1.createPerKeyRateLimitMiddleware)());
|
|
96
|
+
app.log.info("Per-key rate limiting: in-memory (no REDIS_URL)");
|
|
97
|
+
}
|
|
98
|
+
app.setErrorHandler(error_handler_js_1.errorHandler);
|
|
99
|
+
await app.register((0, health_js_1.healthRoutes)(redis_js_1.checkRedisHealth));
|
|
100
|
+
await app.register((0, tenants_js_1.createTenantRoutes)(stratum), { prefix: "/api/v1/tenants" });
|
|
101
|
+
await app.register((0, config_js_1.createConfigRoutes)(stratum), { prefix: "/api/v1/tenants/:id/config" });
|
|
102
|
+
await app.register((0, permissions_js_1.createPermissionRoutes)(stratum), { prefix: "/api/v1/tenants/:id/permissions" });
|
|
103
|
+
await app.register((0, api_keys_js_1.createApiKeyRoutes)(stratum), { prefix: "/api/v1/api-keys" });
|
|
104
|
+
await app.register((0, webhooks_js_1.createWebhookRoutes)(stratum), { prefix: "/api/v1/webhooks" });
|
|
105
|
+
await app.register((0, audit_logs_js_1.createAuditLogRoutes)(stratum), { prefix: "/api/v1/audit-logs" });
|
|
106
|
+
await app.register((0, consent_js_1.createConsentRoutes)(stratum), { prefix: "/api/v1/tenants/:tenantId/consent" });
|
|
107
|
+
await app.register((0, regions_js_1.createRegionRoutes)(stratum), { prefix: "/api/v1/regions" });
|
|
108
|
+
await app.register((0, roles_js_1.createRoleRoutes)(stratum), { prefix: "/api/v1/roles" });
|
|
109
|
+
await app.register((0, maintenance_js_1.createMaintenanceRoutes)(stratum), { prefix: "/api/v1/maintenance" });
|
|
110
|
+
await app.register((0, config_diff_js_1.createConfigDiffRoutes)(stratum), { prefix: "/api/v1/config" });
|
|
111
|
+
return app;
|
|
112
|
+
}
|
|
113
|
+
exports.buildApp = buildApp;
|
|
114
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const config: {
|
|
2
|
+
port: number;
|
|
3
|
+
databaseUrl: string;
|
|
4
|
+
nodeEnv: string;
|
|
5
|
+
jwtSecret: string;
|
|
6
|
+
allowedOrigins: string[];
|
|
7
|
+
rateLimitMax: number;
|
|
8
|
+
rateLimitWindow: string;
|
|
9
|
+
redisUrl: string | undefined;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM;;;;;;;;;CAWlB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
const jwtSecretEnv = process.env.JWT_SECRET;
|
|
5
|
+
const nodeEnv = process.env.NODE_ENV || "development";
|
|
6
|
+
if (!jwtSecretEnv) {
|
|
7
|
+
if (nodeEnv === "production") {
|
|
8
|
+
throw new Error("FATAL: JWT_SECRET must be set in production. Refusing to start.");
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
console.warn("[stratum] JWT_SECRET not set — using dev fallback. Set JWT_SECRET before deploying to production.");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.config = {
|
|
15
|
+
port: parseInt(process.env.PORT || "3001"),
|
|
16
|
+
databaseUrl: process.env.DATABASE_URL || "postgres://stratum:stratum_dev@localhost:5432/stratum",
|
|
17
|
+
nodeEnv,
|
|
18
|
+
jwtSecret: jwtSecretEnv || "dev-secret-change-in-production",
|
|
19
|
+
allowedOrigins: process.env.ALLOWED_ORIGINS
|
|
20
|
+
? process.env.ALLOWED_ORIGINS.split(",").map((o) => o.trim())
|
|
21
|
+
: ["http://localhost:3000", "http://localhost:3300"],
|
|
22
|
+
rateLimitMax: parseInt(process.env.RATE_LIMIT_MAX || "100"),
|
|
23
|
+
rateLimitWindow: process.env.RATE_LIMIT_WINDOW || "1 minute",
|
|
24
|
+
redisUrl: process.env.REDIS_URL || undefined,
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAA,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;AAEtD,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;IACpH,CAAC;AACH,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,iCAAiC;IAC5D,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"}
|
|
@@ -0,0 +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,CAYjC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/C"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.closePool = exports.getPool = void 0;
|
|
7
|
+
const pg_1 = __importDefault(require("pg"));
|
|
8
|
+
const { Pool } = pg_1.default;
|
|
9
|
+
let pool = null;
|
|
10
|
+
function getPool() {
|
|
11
|
+
if (!pool) {
|
|
12
|
+
pool = new Pool({
|
|
13
|
+
connectionString: process.env.DATABASE_URL ||
|
|
14
|
+
"postgres://stratum:stratum_dev@localhost:5432/stratum",
|
|
15
|
+
max: 20,
|
|
16
|
+
idleTimeoutMillis: 30000,
|
|
17
|
+
connectionTimeoutMillis: 5000,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return pool;
|
|
21
|
+
}
|
|
22
|
+
exports.getPool = getPool;
|
|
23
|
+
async function closePool() {
|
|
24
|
+
if (pool) {
|
|
25
|
+
await pool.end();
|
|
26
|
+
pool = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.closePool = closePool;
|
|
30
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":";;;;;;AAAA,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,IAAI,GAAG,IAAI,IAAI,CAAC;YACd,gBAAgB,EACd,OAAO,CAAC,GAAG,CAAC,YAAY;gBACxB,uDAAuD;YACzD,GAAG,EAAE,EAAE;YACP,iBAAiB,EAAE,KAAK;YACxB,uBAAuB,EAAE,IAAI;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAZD,0BAYC;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;AALD,8BAKC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAIA,iBAAe,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAmDtC;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.migrate = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const connection_js_1 = require("./connection.js");
|
|
10
|
+
async function migrate() {
|
|
11
|
+
const pool = (0, connection_js_1.getPool)();
|
|
12
|
+
// Create migrations tracking table
|
|
13
|
+
await pool.query(`
|
|
14
|
+
CREATE TABLE IF NOT EXISTS _migrations (
|
|
15
|
+
id SERIAL PRIMARY KEY,
|
|
16
|
+
name TEXT NOT NULL UNIQUE,
|
|
17
|
+
applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
18
|
+
)
|
|
19
|
+
`);
|
|
20
|
+
// Get applied migrations
|
|
21
|
+
const { rows: applied } = await pool.query("SELECT name FROM _migrations ORDER BY id");
|
|
22
|
+
const appliedSet = new Set(applied.map((r) => r.name));
|
|
23
|
+
// Get migration files
|
|
24
|
+
const migrationsDir = node_path_1.default.resolve(__dirname, "migrations");
|
|
25
|
+
const files = node_fs_1.default
|
|
26
|
+
.readdirSync(migrationsDir)
|
|
27
|
+
.filter((f) => f.endsWith(".sql"))
|
|
28
|
+
.sort();
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
if (appliedSet.has(file)) {
|
|
31
|
+
console.log(` Skipping ${file} (already applied)`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
console.log(` Applying ${file}...`);
|
|
35
|
+
const sql = node_fs_1.default.readFileSync(node_path_1.default.join(migrationsDir, file), "utf-8");
|
|
36
|
+
const client = await pool.connect();
|
|
37
|
+
try {
|
|
38
|
+
await client.query("BEGIN");
|
|
39
|
+
await client.query(sql);
|
|
40
|
+
await client.query("INSERT INTO _migrations (name) VALUES ($1)", [file]);
|
|
41
|
+
await client.query("COMMIT");
|
|
42
|
+
console.log(` Applied ${file}`);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
await client.query("ROLLBACK");
|
|
46
|
+
console.error(` Failed to apply ${file}:`, err);
|
|
47
|
+
throw err;
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
client.release();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
console.log("Migrations complete.");
|
|
54
|
+
}
|
|
55
|
+
exports.migrate = migrate;
|
|
56
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":";;;;;;AAAA,sDAAyB;AACzB,0DAA6B;AAC7B,mDAA0C;AAE1C,KAAK,UAAU,OAAO;IACpB,MAAM,IAAI,GAAG,IAAA,uBAAO,GAAE,CAAC;IAEvB,mCAAmC;IACnC,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;GAMhB,CAAC,CAAC;IAEH,yBAAyB;IACzB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CACxC,0CAA0C,CAC3C,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzE,sBAAsB;IACtB,MAAM,aAAa,GAAG,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,iBAAE;SACb,WAAW,CAAC,aAAa,CAAC;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACjC,IAAI,EAAE,CAAC;IAEV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,oBAAoB,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,KAAK,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,iBAAE,CAAC,YAAY,CAAC,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAErE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5B,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxB,MAAM,MAAM,CAAC,KAAK,CAAC,4CAA4C,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,qBAAqB,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;YACjD,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC;AAEQ,0BAAO"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
export interface RegionalPoolRouter {
|
|
3
|
+
getPool(regionId: string): pg.Pool;
|
|
4
|
+
getGlobalPool(): pg.Pool;
|
|
5
|
+
registerPool(regionId: string, pool: pg.Pool): void;
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createRegionalPoolRouter(globalPool: pg.Pool): RegionalPoolRouter;
|
|
9
|
+
//# sourceMappingURL=regional-pool-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regional-pool-router.d.ts","sourceRoot":"","sources":["../../src/db/regional-pool-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC;IACnC,aAAa,IAAI,EAAE,CAAC,IAAI,CAAC;IACzB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC;IACpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,GAAG,kBAAkB,CAwBhF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRegionalPoolRouter = void 0;
|
|
4
|
+
function createRegionalPoolRouter(globalPool) {
|
|
5
|
+
const pools = new Map();
|
|
6
|
+
return {
|
|
7
|
+
getPool(regionId) {
|
|
8
|
+
const pool = pools.get(regionId);
|
|
9
|
+
if (!pool) {
|
|
10
|
+
// Fall back to global pool if region-specific pool not registered
|
|
11
|
+
return globalPool;
|
|
12
|
+
}
|
|
13
|
+
return pool;
|
|
14
|
+
},
|
|
15
|
+
getGlobalPool() {
|
|
16
|
+
return globalPool;
|
|
17
|
+
},
|
|
18
|
+
registerPool(regionId, pool) {
|
|
19
|
+
pools.set(regionId, pool);
|
|
20
|
+
},
|
|
21
|
+
async close() {
|
|
22
|
+
const closePromises = Array.from(pools.values()).map(p => p.end());
|
|
23
|
+
await Promise.all(closePromises);
|
|
24
|
+
pools.clear();
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
exports.createRegionalPoolRouter = createRegionalPoolRouter;
|
|
29
|
+
//# sourceMappingURL=regional-pool-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regional-pool-router.js","sourceRoot":"","sources":["../../src/db/regional-pool-router.ts"],"names":[],"mappings":";;;AASA,SAAgB,wBAAwB,CAAC,UAAmB;IAC1D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEzC,OAAO;QACL,OAAO,CAAC,QAAgB;YACtB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,kEAAkE;gBAClE,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,aAAa;YACX,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,YAAY,CAAC,QAAgB,EAAE,IAAa;YAC1C,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACnE,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACjC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAxBD,4DAwBC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const app_js_1 = require("./app.js");
|
|
4
|
+
const config_js_1 = require("./config.js");
|
|
5
|
+
const migrate_js_1 = require("./db/migrate.js");
|
|
6
|
+
const connection_js_1 = require("./db/connection.js");
|
|
7
|
+
async function main() {
|
|
8
|
+
// Run database migrations
|
|
9
|
+
console.log("Running migrations...");
|
|
10
|
+
await (0, migrate_js_1.migrate)();
|
|
11
|
+
// Build and start the app
|
|
12
|
+
const app = await (0, app_js_1.buildApp)();
|
|
13
|
+
await app.listen({ port: config_js_1.config.port, host: "0.0.0.0" });
|
|
14
|
+
console.log(`Stratum Control Plane listening on port ${config_js_1.config.port} (${config_js_1.config.nodeEnv})`);
|
|
15
|
+
// Graceful shutdown
|
|
16
|
+
const shutdown = async (signal) => {
|
|
17
|
+
console.log(`Received ${signal}, shutting down...`);
|
|
18
|
+
try {
|
|
19
|
+
await app.close();
|
|
20
|
+
await (0, connection_js_1.closePool)();
|
|
21
|
+
console.log("Shutdown complete.");
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.error("Error during shutdown:", err);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
30
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
31
|
+
}
|
|
32
|
+
main().catch((err) => {
|
|
33
|
+
console.error("Failed to start server:", err);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
+
import { Stratum } from "@stratum-hq/lib";
|
|
3
|
+
interface ApiKeyRecord {
|
|
4
|
+
id: string;
|
|
5
|
+
tenant_id: string | null;
|
|
6
|
+
key_hash: string;
|
|
7
|
+
name: string;
|
|
8
|
+
created_at: Date;
|
|
9
|
+
scopes: string[];
|
|
10
|
+
rate_limit_max: number | null;
|
|
11
|
+
rate_limit_window: string | null;
|
|
12
|
+
}
|
|
13
|
+
declare module "fastify" {
|
|
14
|
+
interface FastifyRequest {
|
|
15
|
+
apiKey?: ApiKeyRecord;
|
|
16
|
+
authMethod?: "api_key" | "jwt";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export declare function createAuthMiddleware(stratum: Stratum): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;KAChC;CACF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,aAExC,cAAc,SAChB,YAAY,KAClB,QAAQ,IAAI,CAAC,CA+DjB"}
|