@stratum-hq/lib 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__/crypto.test.d.ts +2 -0
- package/dist/__tests__/crypto.test.d.ts.map +1 -0
- package/dist/__tests__/crypto.test.js +41 -0
- package/dist/__tests__/crypto.test.js.map +1 -0
- package/dist/crypto.d.ts +7 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +74 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/pool-helpers.d.ts +4 -0
- package/dist/pool-helpers.d.ts.map +1 -0
- package/dist/pool-helpers.js +31 -0
- package/dist/pool-helpers.js.map +1 -0
- package/dist/services/__tests__/audit-service.test.d.ts +2 -0
- package/dist/services/__tests__/audit-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/audit-service.test.js +220 -0
- package/dist/services/__tests__/audit-service.test.js.map +1 -0
- package/dist/services/__tests__/config-service.test.d.ts +2 -0
- package/dist/services/__tests__/config-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/config-service.test.js +555 -0
- package/dist/services/__tests__/config-service.test.js.map +1 -0
- package/dist/services/__tests__/consent-service.test.d.ts +2 -0
- package/dist/services/__tests__/consent-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/consent-service.test.js +159 -0
- package/dist/services/__tests__/consent-service.test.js.map +1 -0
- package/dist/services/__tests__/event-service.test.d.ts +2 -0
- package/dist/services/__tests__/event-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/event-service.test.js +151 -0
- package/dist/services/__tests__/event-service.test.js.map +1 -0
- package/dist/services/__tests__/permission-service.test.d.ts +2 -0
- package/dist/services/__tests__/permission-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/permission-service.test.js +470 -0
- package/dist/services/__tests__/permission-service.test.js.map +1 -0
- package/dist/services/__tests__/retention-service.test.d.ts +2 -0
- package/dist/services/__tests__/retention-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/retention-service.test.js +126 -0
- package/dist/services/__tests__/retention-service.test.js.map +1 -0
- package/dist/services/__tests__/tenant-service.test.d.ts +2 -0
- package/dist/services/__tests__/tenant-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/tenant-service.test.js +451 -0
- package/dist/services/__tests__/tenant-service.test.js.map +1 -0
- package/dist/services/__tests__/test-helpers.d.ts +9 -0
- package/dist/services/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/services/__tests__/test-helpers.js +20 -0
- package/dist/services/__tests__/test-helpers.js.map +1 -0
- package/dist/services/__tests__/webhook-service.test.d.ts +2 -0
- package/dist/services/__tests__/webhook-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/webhook-service.test.js +174 -0
- package/dist/services/__tests__/webhook-service.test.js.map +1 -0
- package/dist/services/api-key-service.d.ts +61 -0
- package/dist/services/api-key-service.d.ts.map +1 -0
- package/dist/services/api-key-service.js +164 -0
- package/dist/services/api-key-service.js.map +1 -0
- package/dist/services/audit-service.d.ts +6 -0
- package/dist/services/audit-service.d.ts.map +1 -0
- package/dist/services/audit-service.js +85 -0
- package/dist/services/audit-service.js.map +1 -0
- package/dist/services/config-service.d.ts +33 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +271 -0
- package/dist/services/config-service.js.map +1 -0
- package/dist/services/consent-service.d.ts +7 -0
- package/dist/services/consent-service.d.ts.map +1 -0
- package/dist/services/consent-service.js +71 -0
- package/dist/services/consent-service.js.map +1 -0
- package/dist/services/event-service.d.ts +39 -0
- package/dist/services/event-service.d.ts.map +1 -0
- package/dist/services/event-service.js +331 -0
- package/dist/services/event-service.js.map +1 -0
- package/dist/services/key-rotation-service.d.ts +15 -0
- package/dist/services/key-rotation-service.d.ts.map +1 -0
- package/dist/services/key-rotation-service.js +41 -0
- package/dist/services/key-rotation-service.js.map +1 -0
- package/dist/services/permission-service.d.ts +21 -0
- package/dist/services/permission-service.d.ts.map +1 -0
- package/dist/services/permission-service.js +213 -0
- package/dist/services/permission-service.js.map +1 -0
- package/dist/services/region-service.d.ts +9 -0
- package/dist/services/region-service.d.ts.map +1 -0
- package/dist/services/region-service.js +105 -0
- package/dist/services/region-service.js.map +1 -0
- package/dist/services/retention-service.d.ts +19 -0
- package/dist/services/retention-service.d.ts.map +1 -0
- package/dist/services/retention-service.js +88 -0
- package/dist/services/retention-service.js.map +1 -0
- package/dist/services/role-service.d.ts +35 -0
- package/dist/services/role-service.d.ts.map +1 -0
- package/dist/services/role-service.js +101 -0
- package/dist/services/role-service.js.map +1 -0
- package/dist/services/tenant-service.d.ts +25 -0
- package/dist/services/tenant-service.d.ts.map +1 -0
- package/dist/services/tenant-service.js +335 -0
- package/dist/services/tenant-service.js.map +1 -0
- package/dist/services/webhook-service.d.ts +12 -0
- package/dist/services/webhook-service.d.ts.map +1 -0
- package/dist/services/webhook-service.js +129 -0
- package/dist/services/webhook-service.js.map +1 -0
- package/dist/stratum.d.ts +107 -0
- package/dist/stratum.d.ts.map +1 -0
- package/dist/stratum.js +531 -0
- package/dist/stratum.js.map +1 -0
- package/dist/telemetry.d.ts +27 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +94 -0
- package/dist/telemetry.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/crypto.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const crypto_js_1 = require("../crypto.js");
|
|
5
|
+
(0, vitest_1.describe)("crypto", () => {
|
|
6
|
+
(0, vitest_1.it)("encrypts and decrypts round-trip", () => {
|
|
7
|
+
const plaintext = "my-secret-value-for-testing";
|
|
8
|
+
const encrypted = (0, crypto_js_1.encrypt)(plaintext);
|
|
9
|
+
(0, vitest_1.expect)(encrypted).not.toBe(plaintext);
|
|
10
|
+
(0, vitest_1.expect)((0, crypto_js_1.decrypt)(encrypted)).toBe(plaintext);
|
|
11
|
+
});
|
|
12
|
+
(0, vitest_1.it)("produces versioned format v1:iv:tag:ct", () => {
|
|
13
|
+
const encrypted = (0, crypto_js_1.encrypt)("test");
|
|
14
|
+
const parts = encrypted.split(":");
|
|
15
|
+
(0, vitest_1.expect)(parts).toHaveLength(4);
|
|
16
|
+
(0, vitest_1.expect)(parts[0]).toBe("v1");
|
|
17
|
+
});
|
|
18
|
+
(0, vitest_1.it)("decrypts legacy format (no version prefix)", () => {
|
|
19
|
+
// Encrypt, then strip the v1: prefix to simulate legacy
|
|
20
|
+
const encrypted = (0, crypto_js_1.encrypt)("legacy-test");
|
|
21
|
+
const legacy = encrypted.replace(/^v1:/, "");
|
|
22
|
+
(0, vitest_1.expect)((0, crypto_js_1.decrypt)(legacy)).toBe("legacy-test");
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.it)("throws on invalid format", () => {
|
|
25
|
+
(0, vitest_1.expect)(() => (0, crypto_js_1.decrypt)("invalid")).toThrow("Invalid encrypted value format");
|
|
26
|
+
});
|
|
27
|
+
(0, vitest_1.it)("different plaintexts produce different ciphertexts", () => {
|
|
28
|
+
const a = (0, crypto_js_1.encrypt)("value-a");
|
|
29
|
+
const b = (0, crypto_js_1.encrypt)("value-b");
|
|
30
|
+
(0, vitest_1.expect)(a).not.toBe(b);
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.it)("same plaintext produces different ciphertexts (random IV)", () => {
|
|
33
|
+
const a = (0, crypto_js_1.encrypt)("same-value");
|
|
34
|
+
const b = (0, crypto_js_1.encrypt)("same-value");
|
|
35
|
+
(0, vitest_1.expect)(a).not.toBe(b);
|
|
36
|
+
// But both decrypt to same value
|
|
37
|
+
(0, vitest_1.expect)((0, crypto_js_1.decrypt)(a)).toBe("same-value");
|
|
38
|
+
(0, vitest_1.expect)((0, crypto_js_1.decrypt)(b)).toBe("same-value");
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=crypto.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.test.js","sourceRoot":"","sources":["../../src/__tests__/crypto.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,4CAAgD;AAEhD,IAAA,iBAAQ,EAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,SAAS,GAAG,6BAA6B,CAAC;QAChD,MAAM,SAAS,GAAG,IAAA,mBAAO,EAAC,SAAS,CAAC,CAAC;QACrC,IAAA,eAAM,EAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,IAAA,mBAAO,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,SAAS,GAAG,IAAA,mBAAO,EAAC,MAAM,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,wDAAwD;QACxD,MAAM,SAAS,GAAG,IAAA,mBAAO,EAAC,aAAa,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAA,eAAM,EAAC,IAAA,mBAAO,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,mBAAO,EAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,IAAA,mBAAO,EAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,IAAA,mBAAO,EAAC,SAAS,CAAC,CAAC;QAC7B,IAAA,eAAM,EAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,GAAG,IAAA,mBAAO,EAAC,YAAY,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,IAAA,mBAAO,EAAC,YAAY,CAAC,CAAC;QAChC,IAAA,eAAM,EAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,iCAAiC;QACjC,IAAA,eAAM,EAAC,IAAA,mBAAO,EAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,IAAA,mBAAO,EAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Encrypts a value. Returns versioned format: v1:iv:authTag:ciphertext (all hex) */
|
|
2
|
+
export declare function encrypt(plaintext: string): string;
|
|
3
|
+
/** Decrypts a versioned encrypted value. Supports v1 format and legacy (no version prefix). */
|
|
4
|
+
export declare function decrypt(encrypted: string): string;
|
|
5
|
+
/** Re-encrypts a value with a new key. Used for key rotation. Safe under concurrency — does not mutate process.env. */
|
|
6
|
+
export declare function reEncrypt(encrypted: string, oldKeyMaterial: string, newKeyMaterial: string): string;
|
|
7
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AA0DA,qFAAqF;AACrF,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,+FAA+F;AAC/F,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,uHAAuH;AACvH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAGnG"}
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
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.reEncrypt = exports.decrypt = exports.encrypt = void 0;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
const ALGORITHM = "aes-256-gcm";
|
|
9
|
+
const IV_LENGTH = 12;
|
|
10
|
+
const AUTH_TAG_LENGTH = 16;
|
|
11
|
+
const CURRENT_KEY_VERSION = "v1";
|
|
12
|
+
function hkdfDeriveKey(keyMaterial, info = "stratum-aes-key") {
|
|
13
|
+
const salt = Buffer.alloc(32, 0);
|
|
14
|
+
return Buffer.from(node_crypto_1.default.hkdfSync("sha256", Buffer.from(keyMaterial, "utf8"), salt, info, 32));
|
|
15
|
+
}
|
|
16
|
+
function getEncryptionKey() {
|
|
17
|
+
const envKey = process.env.STRATUM_ENCRYPTION_KEY ?? process.env.WEBHOOK_ENCRYPTION_KEY;
|
|
18
|
+
if (envKey) {
|
|
19
|
+
return hkdfDeriveKey(envKey);
|
|
20
|
+
}
|
|
21
|
+
if (process.env.NODE_ENV === "production") {
|
|
22
|
+
throw new Error("STRATUM_ENCRYPTION_KEY must be set in production");
|
|
23
|
+
}
|
|
24
|
+
// Dev-only fallback — never use in staging or production
|
|
25
|
+
return hkdfDeriveKey("stratum-dev-key");
|
|
26
|
+
}
|
|
27
|
+
function deriveKey(keyMaterial) {
|
|
28
|
+
return hkdfDeriveKey(keyMaterial, "stratum-rotation-key");
|
|
29
|
+
}
|
|
30
|
+
function encryptWithKey(plaintext, key) {
|
|
31
|
+
const iv = node_crypto_1.default.randomBytes(IV_LENGTH);
|
|
32
|
+
const cipher = node_crypto_1.default.createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
33
|
+
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
34
|
+
const authTag = cipher.getAuthTag();
|
|
35
|
+
return `${CURRENT_KEY_VERSION}:${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted.toString("hex")}`;
|
|
36
|
+
}
|
|
37
|
+
function decryptWithKey(encrypted, key) {
|
|
38
|
+
const parts = encrypted.split(":");
|
|
39
|
+
let ivHex, authTagHex, ciphertextHex;
|
|
40
|
+
if (parts.length === 4 && parts[0].startsWith("v")) {
|
|
41
|
+
// Versioned: v1:iv:authTag:ciphertext
|
|
42
|
+
[, ivHex, authTagHex, ciphertextHex] = parts;
|
|
43
|
+
}
|
|
44
|
+
else if (parts.length === 3) {
|
|
45
|
+
// Legacy: iv:authTag:ciphertext
|
|
46
|
+
[ivHex, authTagHex, ciphertextHex] = parts;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw new Error("Invalid encrypted value format");
|
|
50
|
+
}
|
|
51
|
+
const iv = Buffer.from(ivHex, "hex");
|
|
52
|
+
const authTag = Buffer.from(authTagHex, "hex");
|
|
53
|
+
const ciphertext = Buffer.from(ciphertextHex, "hex");
|
|
54
|
+
const decipher = node_crypto_1.default.createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
55
|
+
decipher.setAuthTag(authTag);
|
|
56
|
+
return decipher.update(ciphertext).toString("utf8") + decipher.final("utf8");
|
|
57
|
+
}
|
|
58
|
+
/** Encrypts a value. Returns versioned format: v1:iv:authTag:ciphertext (all hex) */
|
|
59
|
+
function encrypt(plaintext) {
|
|
60
|
+
return encryptWithKey(plaintext, getEncryptionKey());
|
|
61
|
+
}
|
|
62
|
+
exports.encrypt = encrypt;
|
|
63
|
+
/** Decrypts a versioned encrypted value. Supports v1 format and legacy (no version prefix). */
|
|
64
|
+
function decrypt(encrypted) {
|
|
65
|
+
return decryptWithKey(encrypted, getEncryptionKey());
|
|
66
|
+
}
|
|
67
|
+
exports.decrypt = decrypt;
|
|
68
|
+
/** Re-encrypts a value with a new key. Used for key rotation. Safe under concurrency — does not mutate process.env. */
|
|
69
|
+
function reEncrypt(encrypted, oldKeyMaterial, newKeyMaterial) {
|
|
70
|
+
const plaintext = decryptWithKey(encrypted, deriveKey(oldKeyMaterial));
|
|
71
|
+
return encryptWithKey(plaintext, deriveKey(newKeyMaterial));
|
|
72
|
+
}
|
|
73
|
+
exports.reEncrypt = reEncrypt;
|
|
74
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Stratum, type StratumOptions } from "./stratum.js";
|
|
2
|
+
export { withClient, withTransaction } from "./pool-helpers.js";
|
|
3
|
+
export { traced, getTracer, isTracingEnabled } from "./telemetry.js";
|
|
4
|
+
export type { TenantNode, TenantContext, CreateTenantInput, UpdateTenantInput, MoveTenantInput, PaginationInput, PaginatedResult, ConfigEntry, SetConfigInput, ResolvedConfigEntry, ResolvedConfig, PermissionPolicy, CreatePermissionInput, UpdatePermissionInput, ResolvedPermission, } from "@stratum-hq/core";
|
|
5
|
+
export type { ApiKeyRecord, CreatedApiKey, ValidatedApiKey, CreateApiKeyOptions } from "./services/api-key-service.js";
|
|
6
|
+
export type { BatchCreateResult } from "./services/tenant-service.js";
|
|
7
|
+
export type { KeyRotationResult } from "./services/key-rotation-service.js";
|
|
8
|
+
export type { DeliveryStats } from "./services/event-service.js";
|
|
9
|
+
export type { Role, CreateRoleInput, UpdateRoleInput } from "./services/role-service.js";
|
|
10
|
+
export type { AuditContext, AuditEntry, AuditLogQuery } from "@stratum-hq/core";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,YAAY,EACV,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACvH,YAAY,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,YAAY,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGzF,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTracingEnabled = exports.getTracer = exports.traced = exports.withTransaction = exports.withClient = exports.Stratum = void 0;
|
|
4
|
+
var stratum_js_1 = require("./stratum.js");
|
|
5
|
+
Object.defineProperty(exports, "Stratum", { enumerable: true, get: function () { return stratum_js_1.Stratum; } });
|
|
6
|
+
var pool_helpers_js_1 = require("./pool-helpers.js");
|
|
7
|
+
Object.defineProperty(exports, "withClient", { enumerable: true, get: function () { return pool_helpers_js_1.withClient; } });
|
|
8
|
+
Object.defineProperty(exports, "withTransaction", { enumerable: true, get: function () { return pool_helpers_js_1.withTransaction; } });
|
|
9
|
+
var telemetry_js_1 = require("./telemetry.js");
|
|
10
|
+
Object.defineProperty(exports, "traced", { enumerable: true, get: function () { return telemetry_js_1.traced; } });
|
|
11
|
+
Object.defineProperty(exports, "getTracer", { enumerable: true, get: function () { return telemetry_js_1.getTracer; } });
|
|
12
|
+
Object.defineProperty(exports, "isTracingEnabled", { enumerable: true, get: function () { return telemetry_js_1.isTracingEnabled; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAA4D;AAAnD,qGAAA,OAAO,OAAA;AAChB,qDAAgE;AAAvD,6GAAA,UAAU,OAAA;AAAE,kHAAA,eAAe,OAAA;AACpC,+CAAqE;AAA5D,sGAAA,MAAM,OAAA;AAAE,yGAAA,SAAS,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
export declare function withClient<T>(pool: pg.Pool, fn: (client: pg.PoolClient) => Promise<T>): Promise<T>;
|
|
3
|
+
export declare function withTransaction<T>(pool: pg.Pool, fn: (client: pg.PoolClient) => Promise<T>): Promise<T>;
|
|
4
|
+
//# sourceMappingURL=pool-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool-helpers.d.ts","sourceRoot":"","sources":["../src/pool-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,wBAAsB,UAAU,CAAC,CAAC,EAChC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED,wBAAsB,eAAe,CAAC,CAAC,EACrC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAaZ"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withTransaction = exports.withClient = void 0;
|
|
4
|
+
async function withClient(pool, fn) {
|
|
5
|
+
const client = await pool.connect();
|
|
6
|
+
try {
|
|
7
|
+
return await fn(client);
|
|
8
|
+
}
|
|
9
|
+
finally {
|
|
10
|
+
client.release();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.withClient = withClient;
|
|
14
|
+
async function withTransaction(pool, fn) {
|
|
15
|
+
const client = await pool.connect();
|
|
16
|
+
try {
|
|
17
|
+
await client.query("BEGIN");
|
|
18
|
+
const result = await fn(client);
|
|
19
|
+
await client.query("COMMIT");
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
await client.query("ROLLBACK");
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
client.release();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.withTransaction = withTransaction;
|
|
31
|
+
//# sourceMappingURL=pool-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool-helpers.js","sourceRoot":"","sources":["../src/pool-helpers.ts"],"names":[],"mappings":";;;AAEO,KAAK,UAAU,UAAU,CAC9B,IAAa,EACb,EAAyC;IAEzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAVD,gCAUC;AAEM,KAAK,UAAU,eAAe,CACnC,IAAa,EACb,EAAyC;IAEzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/B,MAAM,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAhBD,0CAgBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/audit-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const vitest_1 = require("vitest");
|
|
27
|
+
// Mock pool-helpers before importing audit-service
|
|
28
|
+
vitest_1.vi.mock("../../pool-helpers.js", () => ({
|
|
29
|
+
withClient: vitest_1.vi.fn(),
|
|
30
|
+
withTransaction: vitest_1.vi.fn(),
|
|
31
|
+
}));
|
|
32
|
+
const poolHelpers = __importStar(require("../../pool-helpers.js"));
|
|
33
|
+
const auditService = __importStar(require("../audit-service.js"));
|
|
34
|
+
function makeMockPool() {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
const mockAuditContext = {
|
|
38
|
+
actor_id: "key-123",
|
|
39
|
+
actor_type: "api_key",
|
|
40
|
+
source_ip: "192.168.1.1",
|
|
41
|
+
request_id: "req-abc",
|
|
42
|
+
};
|
|
43
|
+
const mockEntry = {
|
|
44
|
+
id: "550e8400-e29b-41d4-a716-446655440000",
|
|
45
|
+
actor_id: "key-123",
|
|
46
|
+
actor_type: "api_key",
|
|
47
|
+
action: "tenant.created",
|
|
48
|
+
resource_type: "tenant",
|
|
49
|
+
resource_id: "tenant-456",
|
|
50
|
+
tenant_id: "tenant-456",
|
|
51
|
+
source_ip: "192.168.1.1",
|
|
52
|
+
request_id: "req-abc",
|
|
53
|
+
before_state: null,
|
|
54
|
+
after_state: { name: "Acme" },
|
|
55
|
+
metadata: {},
|
|
56
|
+
created_at: "2024-01-01T00:00:00.000Z",
|
|
57
|
+
};
|
|
58
|
+
(0, vitest_1.beforeEach)(() => {
|
|
59
|
+
vitest_1.vi.clearAllMocks();
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.describe)("createAuditEntry", () => {
|
|
62
|
+
(0, vitest_1.it)("inserts an audit entry and returns it", async () => {
|
|
63
|
+
const pool = makeMockPool();
|
|
64
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockEntry] });
|
|
65
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
66
|
+
const client = {
|
|
67
|
+
query: mockQuery,
|
|
68
|
+
};
|
|
69
|
+
return fn(client);
|
|
70
|
+
});
|
|
71
|
+
const result = await auditService.createAuditEntry(pool, mockAuditContext, "tenant.created", "tenant", "tenant-456", "tenant-456", null, { name: "Acme" });
|
|
72
|
+
(0, vitest_1.expect)(result).toEqual(mockEntry);
|
|
73
|
+
(0, vitest_1.expect)(mockQuery).toHaveBeenCalledTimes(1);
|
|
74
|
+
const [sql, params] = mockQuery.mock.calls[0];
|
|
75
|
+
(0, vitest_1.expect)(sql).toContain("INSERT INTO audit_logs");
|
|
76
|
+
(0, vitest_1.expect)(params[0]).toBe("key-123"); // actor_id
|
|
77
|
+
(0, vitest_1.expect)(params[1]).toBe("api_key"); // actor_type
|
|
78
|
+
(0, vitest_1.expect)(params[2]).toBe("tenant.created"); // action
|
|
79
|
+
(0, vitest_1.expect)(params[3]).toBe("tenant"); // resource_type
|
|
80
|
+
(0, vitest_1.expect)(params[4]).toBe("tenant-456"); // resource_id
|
|
81
|
+
(0, vitest_1.expect)(params[5]).toBe("tenant-456"); // tenant_id
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.it)("handles optional fields as null", async () => {
|
|
84
|
+
const pool = makeMockPool();
|
|
85
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockEntry] });
|
|
86
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
87
|
+
const client = {
|
|
88
|
+
query: mockQuery,
|
|
89
|
+
};
|
|
90
|
+
return fn(client);
|
|
91
|
+
});
|
|
92
|
+
const context = {
|
|
93
|
+
actor_id: "sys",
|
|
94
|
+
actor_type: "system",
|
|
95
|
+
};
|
|
96
|
+
await auditService.createAuditEntry(pool, context, "tenant.deleted", "tenant", "t-1", null);
|
|
97
|
+
const params = mockQuery.mock.calls[0][1];
|
|
98
|
+
(0, vitest_1.expect)(params[5]).toBeNull(); // tenant_id
|
|
99
|
+
(0, vitest_1.expect)(params[6]).toBeNull(); // source_ip
|
|
100
|
+
(0, vitest_1.expect)(params[7]).toBeNull(); // request_id
|
|
101
|
+
(0, vitest_1.expect)(params[8]).toBeNull(); // before_state
|
|
102
|
+
(0, vitest_1.expect)(params[9]).toBeNull(); // after_state
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
(0, vitest_1.describe)("queryAuditLogs", () => {
|
|
106
|
+
(0, vitest_1.it)("returns all entries when no filters", async () => {
|
|
107
|
+
const pool = makeMockPool();
|
|
108
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockEntry] });
|
|
109
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
110
|
+
const client = {
|
|
111
|
+
query: mockQuery,
|
|
112
|
+
};
|
|
113
|
+
return fn(client);
|
|
114
|
+
});
|
|
115
|
+
const result = await auditService.queryAuditLogs(pool, { limit: 50 });
|
|
116
|
+
(0, vitest_1.expect)(result).toEqual([mockEntry]);
|
|
117
|
+
const [sql, params] = mockQuery.mock.calls[0];
|
|
118
|
+
(0, vitest_1.expect)(sql).not.toContain("WHERE");
|
|
119
|
+
(0, vitest_1.expect)(params).toEqual([50]); // just the limit
|
|
120
|
+
});
|
|
121
|
+
(0, vitest_1.it)("applies tenant_id filter", async () => {
|
|
122
|
+
const pool = makeMockPool();
|
|
123
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockEntry] });
|
|
124
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
125
|
+
const client = {
|
|
126
|
+
query: mockQuery,
|
|
127
|
+
};
|
|
128
|
+
return fn(client);
|
|
129
|
+
});
|
|
130
|
+
await auditService.queryAuditLogs(pool, {
|
|
131
|
+
tenant_id: "tenant-456",
|
|
132
|
+
limit: 10,
|
|
133
|
+
});
|
|
134
|
+
const [sql, params] = mockQuery.mock.calls[0];
|
|
135
|
+
(0, vitest_1.expect)(sql).toContain("tenant_id = $1");
|
|
136
|
+
(0, vitest_1.expect)(params[0]).toBe("tenant-456");
|
|
137
|
+
(0, vitest_1.expect)(params[1]).toBe(10); // limit
|
|
138
|
+
});
|
|
139
|
+
(0, vitest_1.it)("applies action and resource_type filters", async () => {
|
|
140
|
+
const pool = makeMockPool();
|
|
141
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [] });
|
|
142
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
143
|
+
const client = {
|
|
144
|
+
query: mockQuery,
|
|
145
|
+
};
|
|
146
|
+
return fn(client);
|
|
147
|
+
});
|
|
148
|
+
await auditService.queryAuditLogs(pool, {
|
|
149
|
+
action: "tenant.created",
|
|
150
|
+
resource_type: "tenant",
|
|
151
|
+
limit: 25,
|
|
152
|
+
});
|
|
153
|
+
const [sql, params] = mockQuery.mock.calls[0];
|
|
154
|
+
(0, vitest_1.expect)(sql).toContain("action = $1");
|
|
155
|
+
(0, vitest_1.expect)(sql).toContain("resource_type = $2");
|
|
156
|
+
(0, vitest_1.expect)(params).toEqual(["tenant.created", "tenant", 25]);
|
|
157
|
+
});
|
|
158
|
+
(0, vitest_1.it)("applies cursor for pagination", async () => {
|
|
159
|
+
const pool = makeMockPool();
|
|
160
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [] });
|
|
161
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
162
|
+
const client = {
|
|
163
|
+
query: mockQuery,
|
|
164
|
+
};
|
|
165
|
+
return fn(client);
|
|
166
|
+
});
|
|
167
|
+
await auditService.queryAuditLogs(pool, {
|
|
168
|
+
cursor: "550e8400-e29b-41d4-a716-446655440000",
|
|
169
|
+
limit: 50,
|
|
170
|
+
});
|
|
171
|
+
const [sql, params] = mockQuery.mock.calls[0];
|
|
172
|
+
(0, vitest_1.expect)(sql).toContain("id < $1");
|
|
173
|
+
(0, vitest_1.expect)(params[0]).toBe("550e8400-e29b-41d4-a716-446655440000");
|
|
174
|
+
});
|
|
175
|
+
(0, vitest_1.it)("applies date range filters", async () => {
|
|
176
|
+
const pool = makeMockPool();
|
|
177
|
+
const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [] });
|
|
178
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
179
|
+
const client = {
|
|
180
|
+
query: mockQuery,
|
|
181
|
+
};
|
|
182
|
+
return fn(client);
|
|
183
|
+
});
|
|
184
|
+
await auditService.queryAuditLogs(pool, {
|
|
185
|
+
from: "2024-01-01T00:00:00.000Z",
|
|
186
|
+
to: "2024-12-31T23:59:59.000Z",
|
|
187
|
+
limit: 50,
|
|
188
|
+
});
|
|
189
|
+
const [sql, params] = mockQuery.mock.calls[0];
|
|
190
|
+
(0, vitest_1.expect)(sql).toContain("created_at >= $1");
|
|
191
|
+
(0, vitest_1.expect)(sql).toContain("created_at <= $2");
|
|
192
|
+
(0, vitest_1.expect)(params[0]).toBe("2024-01-01T00:00:00.000Z");
|
|
193
|
+
(0, vitest_1.expect)(params[1]).toBe("2024-12-31T23:59:59.000Z");
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
(0, vitest_1.describe)("getAuditEntry", () => {
|
|
197
|
+
(0, vitest_1.it)("returns entry when found", async () => {
|
|
198
|
+
const pool = makeMockPool();
|
|
199
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
200
|
+
const client = {
|
|
201
|
+
query: vitest_1.vi.fn().mockResolvedValue({ rows: [mockEntry] }),
|
|
202
|
+
};
|
|
203
|
+
return fn(client);
|
|
204
|
+
});
|
|
205
|
+
const result = await auditService.getAuditEntry(pool, mockEntry.id);
|
|
206
|
+
(0, vitest_1.expect)(result).toEqual(mockEntry);
|
|
207
|
+
});
|
|
208
|
+
(0, vitest_1.it)("returns null when not found", async () => {
|
|
209
|
+
const pool = makeMockPool();
|
|
210
|
+
vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
|
|
211
|
+
const client = {
|
|
212
|
+
query: vitest_1.vi.fn().mockResolvedValue({ rows: [] }),
|
|
213
|
+
};
|
|
214
|
+
return fn(client);
|
|
215
|
+
});
|
|
216
|
+
const result = await auditService.getAuditEntry(pool, "nonexistent-id");
|
|
217
|
+
(0, vitest_1.expect)(result).toBeNull();
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
//# sourceMappingURL=audit-service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/audit-service.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/config-service.test.ts"],"names":[],"mappings":""}
|