@apart-tech/intelligence-core 1.0.7 → 1.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/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/crypto.test.d.ts +2 -0
- package/dist/lib/__tests__/crypto.test.d.ts.map +1 -0
- package/dist/lib/__tests__/crypto.test.js +63 -0
- package/dist/lib/__tests__/crypto.test.js.map +1 -0
- package/dist/lib/crypto.d.ts +14 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +33 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/services/__tests__/pii-detector-service.test.d.ts +2 -0
- package/dist/services/__tests__/pii-detector-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/pii-detector-service.test.js +75 -0
- package/dist/services/__tests__/pii-detector-service.test.js.map +1 -0
- package/dist/services/__tests__/pii-encryption-service.test.d.ts +2 -0
- package/dist/services/__tests__/pii-encryption-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/pii-encryption-service.test.js +151 -0
- package/dist/services/__tests__/pii-encryption-service.test.js.map +1 -0
- package/dist/services/node-service.d.ts +10 -1
- package/dist/services/node-service.d.ts.map +1 -1
- package/dist/services/node-service.js +57 -22
- package/dist/services/node-service.js.map +1 -1
- package/dist/services/org-embedding-config-service.d.ts.map +1 -1
- package/dist/services/org-embedding-config-service.js +4 -21
- package/dist/services/org-embedding-config-service.js.map +1 -1
- package/dist/services/org-pii-config-service.d.ts +30 -0
- package/dist/services/org-pii-config-service.d.ts.map +1 -0
- package/dist/services/org-pii-config-service.js +97 -0
- package/dist/services/org-pii-config-service.js.map +1 -0
- package/dist/services/pii-detector-service.d.ts +24 -0
- package/dist/services/pii-detector-service.d.ts.map +1 -0
- package/dist/services/pii-detector-service.js +89 -0
- package/dist/services/pii-detector-service.js.map +1 -0
- package/dist/services/pii-encryption-service.d.ts +55 -0
- package/dist/services/pii-encryption-service.d.ts.map +1 -0
- package/dist/services/pii-encryption-service.js +216 -0
- package/dist/services/pii-encryption-service.js.map +1 -0
- package/package.json +2 -1
- package/prisma/schema.prisma +17 -0
|
@@ -2,28 +2,36 @@ import { tenantWhere, SINGLE_TENANT_ORG_ID } from "../db/tenant.js";
|
|
|
2
2
|
export class NodeService {
|
|
3
3
|
db;
|
|
4
4
|
embeddings;
|
|
5
|
+
piiEncryption;
|
|
6
|
+
piiOptions;
|
|
5
7
|
tenantCtx;
|
|
6
|
-
constructor(db, embeddings, tenantCtx) {
|
|
8
|
+
constructor(db, embeddings, tenantCtx, piiEncryption, piiOptions) {
|
|
7
9
|
this.db = db;
|
|
8
10
|
this.embeddings = embeddings;
|
|
11
|
+
this.piiEncryption = piiEncryption;
|
|
12
|
+
this.piiOptions = piiOptions;
|
|
9
13
|
this.tenantCtx = tenantCtx ?? { organizationId: SINGLE_TENANT_ORG_ID };
|
|
10
14
|
}
|
|
11
15
|
async create(input) {
|
|
16
|
+
// Generate embedding from ORIGINAL text (before PII encryption)
|
|
12
17
|
const embedding = await this.embeddings.embed(`${input.title}\n\n${input.content}`);
|
|
13
18
|
const embeddingStr = `[${embedding.join(",")}]`;
|
|
19
|
+
// Process PII if configured
|
|
20
|
+
const { title, content, metadata, hasPii } = this.applyPii(input.title, input.content, input.metadata);
|
|
14
21
|
const node = await this.db.node.create({
|
|
15
22
|
data: {
|
|
16
23
|
type: input.type,
|
|
17
|
-
title
|
|
18
|
-
content
|
|
19
|
-
metadata: (
|
|
24
|
+
title,
|
|
25
|
+
content,
|
|
26
|
+
metadata: (metadata ?? {}),
|
|
20
27
|
status: input.status ?? "draft",
|
|
21
28
|
createdBy: input.createdBy,
|
|
22
29
|
domainId: input.domainId ?? null,
|
|
30
|
+
hasPii,
|
|
23
31
|
organizationId: this.tenantCtx.organizationId,
|
|
24
32
|
},
|
|
25
33
|
});
|
|
26
|
-
// Update embedding and tsvector via raw SQL
|
|
34
|
+
// Update embedding and tsvector via raw SQL using ORIGINAL text
|
|
27
35
|
const orgFilter = tenantWhere(this.tenantCtx);
|
|
28
36
|
await this.db.$executeRaw `
|
|
29
37
|
UPDATE nodes
|
|
@@ -36,15 +44,17 @@ export class NodeService {
|
|
|
36
44
|
}
|
|
37
45
|
async createWithEmbedding(input, embedding) {
|
|
38
46
|
const embeddingStr = `[${embedding.join(",")}]`;
|
|
47
|
+
const { title, content, metadata, hasPii } = this.applyPii(input.title, input.content, input.metadata);
|
|
39
48
|
const node = await this.db.node.create({
|
|
40
49
|
data: {
|
|
41
50
|
type: input.type,
|
|
42
|
-
title
|
|
43
|
-
content
|
|
44
|
-
metadata: (
|
|
51
|
+
title,
|
|
52
|
+
content,
|
|
53
|
+
metadata: (metadata ?? {}),
|
|
45
54
|
status: input.status ?? "draft",
|
|
46
55
|
createdBy: input.createdBy,
|
|
47
56
|
domainId: input.domainId ?? null,
|
|
57
|
+
hasPii,
|
|
48
58
|
organizationId: this.tenantCtx.organizationId,
|
|
49
59
|
},
|
|
50
60
|
});
|
|
@@ -62,16 +72,18 @@ export class NodeService {
|
|
|
62
72
|
const existing = await this.getById(id);
|
|
63
73
|
if (!existing)
|
|
64
74
|
return null;
|
|
65
|
-
const
|
|
66
|
-
const
|
|
75
|
+
const originalTitle = input.title ?? existing.title;
|
|
76
|
+
const originalContent = input.content ?? existing.content;
|
|
77
|
+
const { title, content, metadata, hasPii } = this.applyPii(input.title ?? existing.title, input.content ?? existing.content, input.metadata);
|
|
67
78
|
const updated = await this.db.node.update({
|
|
68
79
|
where: { id },
|
|
69
80
|
data: {
|
|
70
|
-
...(input.title !== undefined && { title
|
|
71
|
-
...(input.content !== undefined && { content
|
|
72
|
-
...(input.metadata !== undefined && { metadata:
|
|
81
|
+
...(input.title !== undefined && { title }),
|
|
82
|
+
...(input.content !== undefined && { content }),
|
|
83
|
+
...(input.metadata !== undefined && { metadata: metadata }),
|
|
73
84
|
...(input.type !== undefined && { type: input.type }),
|
|
74
85
|
...(input.domainId !== undefined && { domainId: input.domainId }),
|
|
86
|
+
hasPii,
|
|
75
87
|
updatedAt: new Date(),
|
|
76
88
|
version: existing.version + 1,
|
|
77
89
|
},
|
|
@@ -81,7 +93,7 @@ export class NodeService {
|
|
|
81
93
|
await this.db.$executeRaw `
|
|
82
94
|
UPDATE nodes
|
|
83
95
|
SET embedding = ${embeddingStr}::vector,
|
|
84
|
-
search_vector = to_tsvector('english', ${
|
|
96
|
+
search_vector = to_tsvector('english', ${originalTitle} || ' ' || ${originalContent})
|
|
85
97
|
WHERE id = ${id}::uuid
|
|
86
98
|
AND ${orgFilter}
|
|
87
99
|
`;
|
|
@@ -117,29 +129,31 @@ export class NodeService {
|
|
|
117
129
|
const existing = await this.getById(id);
|
|
118
130
|
if (!existing)
|
|
119
131
|
return null;
|
|
120
|
-
const
|
|
121
|
-
const
|
|
132
|
+
const originalTitle = input.title ?? existing.title;
|
|
133
|
+
const originalContent = input.content ?? existing.content;
|
|
134
|
+
const { title, content, metadata, hasPii } = this.applyPii(originalTitle, originalContent, input.metadata);
|
|
122
135
|
const updated = await this.db.node.update({
|
|
123
136
|
where: { id },
|
|
124
137
|
data: {
|
|
125
|
-
...(input.title !== undefined && { title
|
|
126
|
-
...(input.content !== undefined && { content
|
|
127
|
-
...(input.metadata !== undefined && { metadata:
|
|
138
|
+
...(input.title !== undefined && { title }),
|
|
139
|
+
...(input.content !== undefined && { content }),
|
|
140
|
+
...(input.metadata !== undefined && { metadata: metadata }),
|
|
128
141
|
...(input.type !== undefined && { type: input.type }),
|
|
129
142
|
...(input.domainId !== undefined && { domainId: input.domainId }),
|
|
143
|
+
hasPii,
|
|
130
144
|
updatedAt: new Date(),
|
|
131
145
|
version: existing.version + 1,
|
|
132
146
|
},
|
|
133
147
|
});
|
|
134
|
-
// Re-embed and update tsvector if content changed
|
|
148
|
+
// Re-embed and update tsvector if content changed (use ORIGINAL text)
|
|
135
149
|
if (input.title || input.content) {
|
|
136
|
-
const embedding = await this.embeddings.embed(`${
|
|
150
|
+
const embedding = await this.embeddings.embed(`${originalTitle}\n\n${originalContent}`);
|
|
137
151
|
const embeddingStr = `[${embedding.join(",")}]`;
|
|
138
152
|
const orgFilter = tenantWhere(this.tenantCtx);
|
|
139
153
|
await this.db.$executeRaw `
|
|
140
154
|
UPDATE nodes
|
|
141
155
|
SET embedding = ${embeddingStr}::vector,
|
|
142
|
-
search_vector = to_tsvector('english', ${
|
|
156
|
+
search_vector = to_tsvector('english', ${originalTitle} || ' ' || ${originalContent})
|
|
143
157
|
WHERE id = ${id}::uuid
|
|
144
158
|
AND ${orgFilter}
|
|
145
159
|
`;
|
|
@@ -190,5 +204,26 @@ export class NodeService {
|
|
|
190
204
|
});
|
|
191
205
|
return result.map((r) => ({ type: r.type, count: r._count.type }));
|
|
192
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Apply PII detection/encryption to node fields.
|
|
209
|
+
* Returns processed fields and whether PII was found.
|
|
210
|
+
*/
|
|
211
|
+
applyPii(title, content, metadata) {
|
|
212
|
+
if (!this.piiEncryption || !this.piiOptions || this.piiOptions.mode === "disabled") {
|
|
213
|
+
return { title, content, metadata, hasPii: false };
|
|
214
|
+
}
|
|
215
|
+
const result = this.piiEncryption.processNodeFields({ title, content, metadata }, this.piiOptions);
|
|
216
|
+
// Store the PII report in metadata
|
|
217
|
+
const finalMetadata = {
|
|
218
|
+
...(result.metadata ?? metadata ?? {}),
|
|
219
|
+
...(result.report.matchCount > 0 ? { _piiReport: result.report } : {}),
|
|
220
|
+
};
|
|
221
|
+
return {
|
|
222
|
+
title: result.title,
|
|
223
|
+
content: result.content,
|
|
224
|
+
metadata: finalMetadata,
|
|
225
|
+
hasPii: result.report.matchCount > 0,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
193
228
|
}
|
|
194
229
|
//# sourceMappingURL=node-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-service.js","sourceRoot":"","sources":["../../src/services/node-service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAsB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"node-service.js","sourceRoot":"","sources":["../../src/services/node-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"org-embedding-config-service.d.ts","sourceRoot":"","sources":["../../src/services/org-embedding-config-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"org-embedding-config-service.d.ts","sourceRoot":"","sources":["../../src/services/org-embedding-config-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgBnD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,yBAAyB;IACxB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAE9B,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAc/D,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;IAe7E,GAAG,CACP,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACjG,OAAO,CAAC,kBAAkB,CAAC;IA8BxB,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAQvD"}
|
|
@@ -1,30 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const ALGORITHM = "aes-256-gcm";
|
|
3
|
-
const IV_LENGTH = 16;
|
|
4
|
-
const TAG_LENGTH = 16;
|
|
1
|
+
import { encryptAesGcm, decryptAesGcm, deriveKey } from "../lib/crypto.js";
|
|
5
2
|
function getEncryptionKey() {
|
|
6
3
|
const secret = process.env.EMBEDDING_KEY_SECRET ?? "apart-default-embedding-key-secret-change-me";
|
|
7
|
-
|
|
8
|
-
return createHash("sha256").update(secret).digest();
|
|
4
|
+
return deriveKey(secret);
|
|
9
5
|
}
|
|
10
6
|
function encrypt(plaintext) {
|
|
11
|
-
|
|
12
|
-
const iv = randomBytes(IV_LENGTH);
|
|
13
|
-
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
14
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
15
|
-
const tag = cipher.getAuthTag();
|
|
16
|
-
// Format: iv:tag:ciphertext (all base64)
|
|
17
|
-
return `${iv.toString("base64")}:${tag.toString("base64")}:${encrypted.toString("base64")}`;
|
|
7
|
+
return encryptAesGcm(plaintext, getEncryptionKey());
|
|
18
8
|
}
|
|
19
9
|
function decrypt(encoded) {
|
|
20
|
-
|
|
21
|
-
const [ivB64, tagB64, ciphertextB64] = encoded.split(":");
|
|
22
|
-
const iv = Buffer.from(ivB64, "base64");
|
|
23
|
-
const tag = Buffer.from(tagB64, "base64");
|
|
24
|
-
const ciphertext = Buffer.from(ciphertextB64, "base64");
|
|
25
|
-
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
26
|
-
decipher.setAuthTag(tag);
|
|
27
|
-
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
10
|
+
return decryptAesGcm(encoded, getEncryptionKey());
|
|
28
11
|
}
|
|
29
12
|
export class OrgEmbeddingConfigService {
|
|
30
13
|
db;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"org-embedding-config-service.js","sourceRoot":"","sources":["../../src/services/org-embedding-config-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"org-embedding-config-service.js","sourceRoot":"","sources":["../../src/services/org-embedding-config-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PrismaClient } from "@prisma/client";
|
|
2
|
+
export type PiiMode = "encrypt" | "detect-warn" | "disabled";
|
|
3
|
+
export interface OrgPiiConfig {
|
|
4
|
+
mode: PiiMode;
|
|
5
|
+
allowedPiiTypes: string[];
|
|
6
|
+
allowBypass: boolean;
|
|
7
|
+
updatedAt: Date;
|
|
8
|
+
updatedBy: string;
|
|
9
|
+
}
|
|
10
|
+
export interface OrgPiiConfigWithKey extends OrgPiiConfig {
|
|
11
|
+
piiKey: Buffer;
|
|
12
|
+
}
|
|
13
|
+
export declare class OrgPiiConfigService {
|
|
14
|
+
private db;
|
|
15
|
+
constructor(db: PrismaClient);
|
|
16
|
+
get(organizationId: string): Promise<OrgPiiConfig | null>;
|
|
17
|
+
getWithKey(organizationId: string): Promise<OrgPiiConfigWithKey | null>;
|
|
18
|
+
set(organizationId: string, input: {
|
|
19
|
+
mode: PiiMode;
|
|
20
|
+
allowedPiiTypes?: string[];
|
|
21
|
+
allowBypass?: boolean;
|
|
22
|
+
updatedBy?: string;
|
|
23
|
+
}): Promise<OrgPiiConfig>;
|
|
24
|
+
delete(organizationId: string): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Generate a random 32-byte encryption key.
|
|
27
|
+
*/
|
|
28
|
+
generateKey(): Buffer;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=org-pii-config-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-pii-config-service.d.ts","sourceRoot":"","sources":["../../src/services/org-pii-config-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgBnD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,mBAAmB;IAClB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAE9B,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAczD,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAevE,GAAG,CACP,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE;QACL,IAAI,EAAE,OAAO,CAAC;QACd,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,YAAY,CAAC;IAsClB,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAStD;;OAEG;IACH,WAAW,IAAI,MAAM;CAGtB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { encryptAesGcm, decryptAesGcm, deriveKey } from "../lib/crypto.js";
|
|
3
|
+
function getPiiEncryptionKey() {
|
|
4
|
+
const secret = process.env.PII_KEY_SECRET ?? "apart-default-pii-key-secret-change-me";
|
|
5
|
+
return deriveKey(secret);
|
|
6
|
+
}
|
|
7
|
+
function encryptPiiKey(plaintext) {
|
|
8
|
+
return encryptAesGcm(plaintext, getPiiEncryptionKey());
|
|
9
|
+
}
|
|
10
|
+
function decryptPiiKey(encoded) {
|
|
11
|
+
return decryptAesGcm(encoded, getPiiEncryptionKey());
|
|
12
|
+
}
|
|
13
|
+
export class OrgPiiConfigService {
|
|
14
|
+
db;
|
|
15
|
+
constructor(db) {
|
|
16
|
+
this.db = db;
|
|
17
|
+
}
|
|
18
|
+
async get(organizationId) {
|
|
19
|
+
const config = await this.db.orgPiiConfig.findUnique({
|
|
20
|
+
where: { organizationId },
|
|
21
|
+
});
|
|
22
|
+
if (!config)
|
|
23
|
+
return null;
|
|
24
|
+
return {
|
|
25
|
+
mode: config.mode,
|
|
26
|
+
allowedPiiTypes: config.allowedPiiTypes,
|
|
27
|
+
allowBypass: config.allowBypass,
|
|
28
|
+
updatedAt: config.updatedAt,
|
|
29
|
+
updatedBy: config.updatedBy,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async getWithKey(organizationId) {
|
|
33
|
+
const config = await this.db.orgPiiConfig.findUnique({
|
|
34
|
+
where: { organizationId },
|
|
35
|
+
});
|
|
36
|
+
if (!config)
|
|
37
|
+
return null;
|
|
38
|
+
return {
|
|
39
|
+
mode: config.mode,
|
|
40
|
+
allowedPiiTypes: config.allowedPiiTypes,
|
|
41
|
+
allowBypass: config.allowBypass,
|
|
42
|
+
piiKey: Buffer.from(decryptPiiKey(config.piiKeyEncrypted), "hex"),
|
|
43
|
+
updatedAt: config.updatedAt,
|
|
44
|
+
updatedBy: config.updatedBy,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async set(organizationId, input) {
|
|
48
|
+
// Check if config already exists to preserve existing key
|
|
49
|
+
const existing = await this.db.orgPiiConfig.findUnique({
|
|
50
|
+
where: { organizationId },
|
|
51
|
+
});
|
|
52
|
+
const piiKeyEncrypted = existing
|
|
53
|
+
? existing.piiKeyEncrypted
|
|
54
|
+
: encryptPiiKey(this.generateKey().toString("hex"));
|
|
55
|
+
const config = await this.db.orgPiiConfig.upsert({
|
|
56
|
+
where: { organizationId },
|
|
57
|
+
create: {
|
|
58
|
+
organizationId,
|
|
59
|
+
mode: input.mode,
|
|
60
|
+
piiKeyEncrypted,
|
|
61
|
+
allowedPiiTypes: (input.allowedPiiTypes ?? []),
|
|
62
|
+
allowBypass: input.allowBypass ?? false,
|
|
63
|
+
updatedBy: input.updatedBy ?? "api",
|
|
64
|
+
},
|
|
65
|
+
update: {
|
|
66
|
+
mode: input.mode,
|
|
67
|
+
allowedPiiTypes: (input.allowedPiiTypes ?? existing?.allowedPiiTypes ?? []),
|
|
68
|
+
allowBypass: input.allowBypass ?? existing?.allowBypass ?? false,
|
|
69
|
+
updatedAt: new Date(),
|
|
70
|
+
updatedBy: input.updatedBy ?? "api",
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
mode: config.mode,
|
|
75
|
+
allowedPiiTypes: config.allowedPiiTypes,
|
|
76
|
+
allowBypass: config.allowBypass,
|
|
77
|
+
updatedAt: config.updatedAt,
|
|
78
|
+
updatedBy: config.updatedBy,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async delete(organizationId) {
|
|
82
|
+
try {
|
|
83
|
+
await this.db.orgPiiConfig.delete({ where: { organizationId } });
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generate a random 32-byte encryption key.
|
|
92
|
+
*/
|
|
93
|
+
generateKey() {
|
|
94
|
+
return randomBytes(32);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=org-pii-config-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-pii-config-service.js","sourceRoot":"","sources":["../../src/services/org-pii-config-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PiiPattern } from "@cdssnc/sanitize-pii";
|
|
2
|
+
export interface PiiMatch {
|
|
3
|
+
type: string;
|
|
4
|
+
value: string;
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
}
|
|
8
|
+
export interface PiiDetectionResult {
|
|
9
|
+
hasPii: boolean;
|
|
10
|
+
matches: PiiMatch[];
|
|
11
|
+
}
|
|
12
|
+
export declare class PiiDetectorService {
|
|
13
|
+
private sanitizer;
|
|
14
|
+
constructor(customPatterns?: PiiPattern[]);
|
|
15
|
+
/**
|
|
16
|
+
* Detect PII in a text string. Returns matches with their positions.
|
|
17
|
+
*/
|
|
18
|
+
detect(text: string): PiiDetectionResult;
|
|
19
|
+
/**
|
|
20
|
+
* Detect PII in all string values of an object (shallow — top-level keys only).
|
|
21
|
+
*/
|
|
22
|
+
detectInObject(obj: Record<string, unknown>): Record<string, PiiDetectionResult>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=pii-detector-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii-detector-service.d.ts","sourceRoot":"","sources":["../../src/services/pii-detector-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB;AAgBD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAAe;gBAEpB,cAAc,CAAC,EAAE,UAAU,EAAE;IAOzC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB;IAiCxC;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC;CASjF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { PiiSanitizer, defaultPatterns } from "@cdssnc/sanitize-pii";
|
|
2
|
+
/** Additional patterns not included in @cdssnc/sanitize-pii defaults */
|
|
3
|
+
const extraPatterns = [
|
|
4
|
+
{
|
|
5
|
+
name: "email",
|
|
6
|
+
regex: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
|
|
7
|
+
description: "Email address",
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: "ssn_us",
|
|
11
|
+
regex: /\b\d{3}-\d{2}-\d{4}\b/g,
|
|
12
|
+
description: "US Social Security Number",
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
export class PiiDetectorService {
|
|
16
|
+
sanitizer;
|
|
17
|
+
constructor(customPatterns) {
|
|
18
|
+
this.sanitizer = new PiiSanitizer({
|
|
19
|
+
patterns: [...defaultPatterns, ...extraPatterns, ...(customPatterns ?? [])],
|
|
20
|
+
useDefaultPatterns: false,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect PII in a text string. Returns matches with their positions.
|
|
25
|
+
*/
|
|
26
|
+
detect(text) {
|
|
27
|
+
if (!text)
|
|
28
|
+
return { hasPii: false, matches: [] };
|
|
29
|
+
const detections = this.sanitizer.detectPii(text);
|
|
30
|
+
const matches = [];
|
|
31
|
+
for (const detection of detections) {
|
|
32
|
+
// Find all occurrences of this match in the text
|
|
33
|
+
let searchFrom = 0;
|
|
34
|
+
while (searchFrom < text.length) {
|
|
35
|
+
const idx = text.indexOf(detection.match, searchFrom);
|
|
36
|
+
if (idx === -1)
|
|
37
|
+
break;
|
|
38
|
+
matches.push({
|
|
39
|
+
type: detection.pattern,
|
|
40
|
+
value: detection.match,
|
|
41
|
+
start: idx,
|
|
42
|
+
end: idx + detection.match.length,
|
|
43
|
+
});
|
|
44
|
+
searchFrom = idx + detection.match.length;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Sort by position (start offset) and deduplicate overlapping matches
|
|
48
|
+
matches.sort((a, b) => a.start - b.start);
|
|
49
|
+
const deduplicated = deduplicateMatches(matches);
|
|
50
|
+
return {
|
|
51
|
+
hasPii: deduplicated.length > 0,
|
|
52
|
+
matches: deduplicated,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Detect PII in all string values of an object (shallow — top-level keys only).
|
|
57
|
+
*/
|
|
58
|
+
detectInObject(obj) {
|
|
59
|
+
const results = {};
|
|
60
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
61
|
+
if (typeof value === "string") {
|
|
62
|
+
results[key] = this.detect(value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return results;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Remove overlapping matches, keeping the longer (more specific) one.
|
|
70
|
+
*/
|
|
71
|
+
function deduplicateMatches(sorted) {
|
|
72
|
+
if (sorted.length <= 1)
|
|
73
|
+
return sorted;
|
|
74
|
+
const result = [sorted[0]];
|
|
75
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
76
|
+
const prev = result[result.length - 1];
|
|
77
|
+
const curr = sorted[i];
|
|
78
|
+
if (curr.start >= prev.end) {
|
|
79
|
+
result.push(curr);
|
|
80
|
+
}
|
|
81
|
+
else if (curr.end - curr.start > prev.end - prev.start) {
|
|
82
|
+
// Current match is longer — replace previous
|
|
83
|
+
result[result.length - 1] = curr;
|
|
84
|
+
}
|
|
85
|
+
// Otherwise skip (previous match covers this one)
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=pii-detector-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii-detector-service.js","sourceRoot":"","sources":["../../src/services/pii-detector-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAerE,wEAAwE;AACxE,MAAM,aAAa,GAAiB;IAClC;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,qDAAqD;QAC5D,WAAW,EAAE,eAAe;KAC7B;IACD;QACE,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,2BAA2B;KACzC;CACF,CAAC;AAEF,MAAM,OAAO,kBAAkB;IACrB,SAAS,CAAe;IAEhC,YAAY,cAA6B;QACvC,IAAI,CAAC,SAAS,GAAG,IAAI,YAAY,CAAC;YAChC,QAAQ,EAAE,CAAC,GAAG,eAAe,EAAE,GAAG,aAAa,EAAE,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;YAC3E,kBAAkB,EAAE,KAAK;SAC1B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAEjD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,OAAO,GAAe,EAAE,CAAC;QAE/B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,iDAAiD;YACjD,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,OAAO,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtD,IAAI,GAAG,KAAK,CAAC,CAAC;oBAAE,MAAM;gBAEtB,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,SAAS,CAAC,OAAO;oBACvB,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,KAAK,EAAE,GAAG;oBACV,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM;iBAClC,CAAC,CAAC;gBACH,UAAU,GAAG,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAEjD,OAAO;YACL,MAAM,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;YAC/B,OAAO,EAAE,YAAY;SACtB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,GAA4B;QACzC,MAAM,OAAO,GAAuC,EAAE,CAAC;QACvD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAkB;IAC5C,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAEtC,MAAM,MAAM,GAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YACzD,6CAA6C;YAC7C,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;QACnC,CAAC;QACD,kDAAkD;IACpD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { PiiDetectorService } from "./pii-detector-service.js";
|
|
2
|
+
export interface PiiEncryptionOptions {
|
|
3
|
+
orgKey?: Buffer;
|
|
4
|
+
mode: "encrypt" | "detect-warn" | "disabled";
|
|
5
|
+
allowedPiiTypes?: string[];
|
|
6
|
+
bypass?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface PiiReport {
|
|
9
|
+
matchCount: number;
|
|
10
|
+
encryptedCount: number;
|
|
11
|
+
bypassedCount: number;
|
|
12
|
+
types: string[];
|
|
13
|
+
mode: string;
|
|
14
|
+
bypassed: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface PiiProcessingResult {
|
|
17
|
+
text: string;
|
|
18
|
+
report: PiiReport;
|
|
19
|
+
}
|
|
20
|
+
export declare class PiiEncryptionService {
|
|
21
|
+
private detector;
|
|
22
|
+
constructor(detector: PiiDetectorService);
|
|
23
|
+
/**
|
|
24
|
+
* Process a text string: detect PII and optionally encrypt matches.
|
|
25
|
+
*/
|
|
26
|
+
processText(text: string, options: PiiEncryptionOptions): PiiProcessingResult;
|
|
27
|
+
/**
|
|
28
|
+
* Process node fields (title, content, metadata) for PII.
|
|
29
|
+
*/
|
|
30
|
+
processNodeFields(input: {
|
|
31
|
+
title: string;
|
|
32
|
+
content: string;
|
|
33
|
+
metadata?: Record<string, unknown>;
|
|
34
|
+
}, options: PiiEncryptionOptions): {
|
|
35
|
+
title: string;
|
|
36
|
+
content: string;
|
|
37
|
+
metadata?: Record<string, unknown>;
|
|
38
|
+
report: PiiReport;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Decrypt all PII tokens in a text string.
|
|
42
|
+
*/
|
|
43
|
+
decryptText(text: string, orgKey: Buffer): string;
|
|
44
|
+
/**
|
|
45
|
+
* Decrypt PII tokens in node fields.
|
|
46
|
+
*/
|
|
47
|
+
decryptNodeFields<T extends {
|
|
48
|
+
title: string;
|
|
49
|
+
content: string;
|
|
50
|
+
metadata: unknown;
|
|
51
|
+
}>(node: T, orgKey: Buffer): T;
|
|
52
|
+
private processMetadata;
|
|
53
|
+
private decryptMetadataValues;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=pii-encryption-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii-encryption-service.d.ts","sourceRoot":"","sources":["../../src/services/pii-encryption-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;IAC7C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;CACnB;AAKD,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,kBAAkB;IAEhD;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,mBAAmB;IAkE7E;;OAEG;IACH,iBAAiB,CACf,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAC7E,OAAO,EAAE,oBAAoB,GAC5B;QACD,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,MAAM,EAAE,SAAS,CAAC;KACnB;IAkED;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAWjD;;OAEG;IACH,iBAAiB,CAAC,CAAC,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,EAC/E,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,MAAM,GACb,CAAC;IASJ,OAAO,CAAC,eAAe;IAyDvB,OAAO,CAAC,qBAAqB;CAqB9B"}
|