@apart-tech/intelligence-core 1.0.6 → 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.
Files changed (41) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +5 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/__tests__/crypto.test.d.ts +2 -0
  6. package/dist/lib/__tests__/crypto.test.d.ts.map +1 -0
  7. package/dist/lib/__tests__/crypto.test.js +63 -0
  8. package/dist/lib/__tests__/crypto.test.js.map +1 -0
  9. package/dist/lib/crypto.d.ts +14 -0
  10. package/dist/lib/crypto.d.ts.map +1 -0
  11. package/dist/lib/crypto.js +33 -0
  12. package/dist/lib/crypto.js.map +1 -0
  13. package/dist/services/__tests__/pii-detector-service.test.d.ts +2 -0
  14. package/dist/services/__tests__/pii-detector-service.test.d.ts.map +1 -0
  15. package/dist/services/__tests__/pii-detector-service.test.js +75 -0
  16. package/dist/services/__tests__/pii-detector-service.test.js.map +1 -0
  17. package/dist/services/__tests__/pii-encryption-service.test.d.ts +2 -0
  18. package/dist/services/__tests__/pii-encryption-service.test.d.ts.map +1 -0
  19. package/dist/services/__tests__/pii-encryption-service.test.js +151 -0
  20. package/dist/services/__tests__/pii-encryption-service.test.js.map +1 -0
  21. package/dist/services/node-service.d.ts +11 -1
  22. package/dist/services/node-service.d.ts.map +1 -1
  23. package/dist/services/node-service.js +90 -27
  24. package/dist/services/node-service.js.map +1 -1
  25. package/dist/services/org-embedding-config-service.d.ts.map +1 -1
  26. package/dist/services/org-embedding-config-service.js +4 -21
  27. package/dist/services/org-embedding-config-service.js.map +1 -1
  28. package/dist/services/org-pii-config-service.d.ts +30 -0
  29. package/dist/services/org-pii-config-service.d.ts.map +1 -0
  30. package/dist/services/org-pii-config-service.js +97 -0
  31. package/dist/services/org-pii-config-service.js.map +1 -0
  32. package/dist/services/pii-detector-service.d.ts +24 -0
  33. package/dist/services/pii-detector-service.d.ts.map +1 -0
  34. package/dist/services/pii-detector-service.js +89 -0
  35. package/dist/services/pii-detector-service.js.map +1 -0
  36. package/dist/services/pii-encryption-service.d.ts +55 -0
  37. package/dist/services/pii-encryption-service.d.ts.map +1 -0
  38. package/dist/services/pii-encryption-service.js +216 -0
  39. package/dist/services/pii-encryption-service.js.map +1 -0
  40. package/package.json +2 -1
  41. package/prisma/schema.prisma +17 -0
@@ -0,0 +1,216 @@
1
+ import { encryptAesGcm, decryptAesGcm } from "../lib/crypto.js";
2
+ const PII_TOKEN_REGEX = /\[PII:(\w+):([A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+)\]/g;
3
+ const MAX_METADATA_DEPTH = 5;
4
+ export class PiiEncryptionService {
5
+ detector;
6
+ constructor(detector) {
7
+ this.detector = detector;
8
+ }
9
+ /**
10
+ * Process a text string: detect PII and optionally encrypt matches.
11
+ */
12
+ processText(text, options) {
13
+ const emptyReport = {
14
+ matchCount: 0,
15
+ encryptedCount: 0,
16
+ bypassedCount: 0,
17
+ types: [],
18
+ mode: options.mode,
19
+ bypassed: options.bypass ?? false,
20
+ };
21
+ if (options.mode === "disabled") {
22
+ return { text, report: emptyReport };
23
+ }
24
+ const detection = this.detector.detect(text);
25
+ if (!detection.hasPii) {
26
+ return { text, report: emptyReport };
27
+ }
28
+ const types = [...new Set(detection.matches.map((m) => m.type))];
29
+ const allowedTypes = new Set(options.allowedPiiTypes ?? []);
30
+ // Filter out matches whose type is explicitly allowed
31
+ const matchesToProcess = detection.matches.filter((m) => !allowedTypes.has(m.type));
32
+ const skippedCount = detection.matches.length - matchesToProcess.length;
33
+ if (options.mode === "detect-warn" || options.bypass || !options.orgKey) {
34
+ return {
35
+ text,
36
+ report: {
37
+ matchCount: detection.matches.length,
38
+ encryptedCount: 0,
39
+ bypassedCount: detection.matches.length,
40
+ types,
41
+ mode: options.mode,
42
+ bypassed: options.bypass ?? (options.mode === "detect-warn"),
43
+ },
44
+ };
45
+ }
46
+ // Mode is "encrypt" — replace PII matches with encrypted tokens
47
+ // Process matches in reverse order to preserve string offsets
48
+ let result = text;
49
+ let encryptedCount = 0;
50
+ const reversedMatches = [...matchesToProcess].reverse();
51
+ for (const match of reversedMatches) {
52
+ const encrypted = encryptAesGcm(match.value, options.orgKey);
53
+ const token = `[PII:${match.type}:${encrypted}]`;
54
+ result = result.slice(0, match.start) + token + result.slice(match.end);
55
+ encryptedCount++;
56
+ }
57
+ return {
58
+ text: result,
59
+ report: {
60
+ matchCount: detection.matches.length,
61
+ encryptedCount,
62
+ bypassedCount: skippedCount,
63
+ types,
64
+ mode: options.mode,
65
+ bypassed: false,
66
+ },
67
+ };
68
+ }
69
+ /**
70
+ * Process node fields (title, content, metadata) for PII.
71
+ */
72
+ processNodeFields(input, options) {
73
+ if (options.mode === "disabled") {
74
+ return {
75
+ ...input,
76
+ report: {
77
+ matchCount: 0,
78
+ encryptedCount: 0,
79
+ bypassedCount: 0,
80
+ types: [],
81
+ mode: "disabled",
82
+ bypassed: false,
83
+ },
84
+ };
85
+ }
86
+ const titleResult = this.processText(input.title, options);
87
+ const contentResult = this.processText(input.content, options);
88
+ let processedMetadata = input.metadata;
89
+ let metadataMatchCount = 0;
90
+ let metadataEncryptedCount = 0;
91
+ const metadataTypes = [];
92
+ if (input.metadata && options.mode === "encrypt" && !options.bypass && options.orgKey) {
93
+ const { result, matchCount, encryptedCount, types } = this.processMetadata(input.metadata, options, 0);
94
+ processedMetadata = result;
95
+ metadataMatchCount = matchCount;
96
+ metadataEncryptedCount = encryptedCount;
97
+ metadataTypes.push(...types);
98
+ }
99
+ const allTypes = [
100
+ ...new Set([
101
+ ...titleResult.report.types,
102
+ ...contentResult.report.types,
103
+ ...metadataTypes,
104
+ ]),
105
+ ];
106
+ return {
107
+ title: titleResult.text,
108
+ content: contentResult.text,
109
+ metadata: processedMetadata,
110
+ report: {
111
+ matchCount: titleResult.report.matchCount +
112
+ contentResult.report.matchCount +
113
+ metadataMatchCount,
114
+ encryptedCount: titleResult.report.encryptedCount +
115
+ contentResult.report.encryptedCount +
116
+ metadataEncryptedCount,
117
+ bypassedCount: titleResult.report.bypassedCount +
118
+ contentResult.report.bypassedCount,
119
+ types: allTypes,
120
+ mode: options.mode,
121
+ bypassed: options.bypass ?? false,
122
+ },
123
+ };
124
+ }
125
+ /**
126
+ * Decrypt all PII tokens in a text string.
127
+ */
128
+ decryptText(text, orgKey) {
129
+ return text.replace(PII_TOKEN_REGEX, (_fullMatch, _type, encrypted) => {
130
+ try {
131
+ return decryptAesGcm(encrypted, orgKey);
132
+ }
133
+ catch {
134
+ // If decryption fails (wrong key, corrupted), leave token as-is
135
+ return _fullMatch;
136
+ }
137
+ });
138
+ }
139
+ /**
140
+ * Decrypt PII tokens in node fields.
141
+ */
142
+ decryptNodeFields(node, orgKey) {
143
+ return {
144
+ ...node,
145
+ title: this.decryptText(node.title, orgKey),
146
+ content: this.decryptText(node.content, orgKey),
147
+ metadata: this.decryptMetadataValues(node.metadata, orgKey, 0),
148
+ };
149
+ }
150
+ processMetadata(value, options, depth) {
151
+ if (depth > MAX_METADATA_DEPTH) {
152
+ return { result: value, matchCount: 0, encryptedCount: 0, types: [] };
153
+ }
154
+ if (typeof value === "string") {
155
+ const processed = this.processText(value, options);
156
+ return {
157
+ result: processed.text,
158
+ matchCount: processed.report.matchCount,
159
+ encryptedCount: processed.report.encryptedCount,
160
+ types: processed.report.types,
161
+ };
162
+ }
163
+ if (Array.isArray(value)) {
164
+ let totalMatches = 0;
165
+ let totalEncrypted = 0;
166
+ const allTypes = [];
167
+ const result = value.map((item) => {
168
+ const processed = this.processMetadata(item, options, depth + 1);
169
+ totalMatches += processed.matchCount;
170
+ totalEncrypted += processed.encryptedCount;
171
+ allTypes.push(...processed.types);
172
+ return processed.result;
173
+ });
174
+ return { result, matchCount: totalMatches, encryptedCount: totalEncrypted, types: allTypes };
175
+ }
176
+ if (value !== null && typeof value === "object") {
177
+ let totalMatches = 0;
178
+ let totalEncrypted = 0;
179
+ const allTypes = [];
180
+ const result = {};
181
+ for (const [key, val] of Object.entries(value)) {
182
+ // Skip internal PII report field
183
+ if (key === "_piiReport") {
184
+ result[key] = val;
185
+ continue;
186
+ }
187
+ const processed = this.processMetadata(val, options, depth + 1);
188
+ result[key] = processed.result;
189
+ totalMatches += processed.matchCount;
190
+ totalEncrypted += processed.encryptedCount;
191
+ allTypes.push(...processed.types);
192
+ }
193
+ return { result, matchCount: totalMatches, encryptedCount: totalEncrypted, types: allTypes };
194
+ }
195
+ return { result: value, matchCount: 0, encryptedCount: 0, types: [] };
196
+ }
197
+ decryptMetadataValues(value, orgKey, depth) {
198
+ if (depth > MAX_METADATA_DEPTH)
199
+ return value;
200
+ if (typeof value === "string") {
201
+ return this.decryptText(value, orgKey);
202
+ }
203
+ if (Array.isArray(value)) {
204
+ return value.map((item) => this.decryptMetadataValues(item, orgKey, depth + 1));
205
+ }
206
+ if (value !== null && typeof value === "object") {
207
+ const result = {};
208
+ for (const [key, val] of Object.entries(value)) {
209
+ result[key] = this.decryptMetadataValues(val, orgKey, depth + 1);
210
+ }
211
+ return result;
212
+ }
213
+ return value;
214
+ }
215
+ }
216
+ //# sourceMappingURL=pii-encryption-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii-encryption-service.js","sourceRoot":"","sources":["../../src/services/pii-encryption-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apart-tech/intelligence-core",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "Core library: database, services, and providers for Apart Intelligence",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,6 +19,7 @@
19
19
  "access": "public"
20
20
  },
21
21
  "dependencies": {
22
+ "@cdssnc/sanitize-pii": "^2.1.2",
22
23
  "@prisma/client": "^6.6.0",
23
24
  "@prisma/extension-accelerate": "^3.0.1",
24
25
  "prisma": "^6.6.0",
@@ -20,6 +20,7 @@ model Organization {
20
20
  apiKeys ApiKey[]
21
21
  workspaces Workspace[]
22
22
  embeddingConfig OrgEmbeddingConfig?
23
+ piiConfig OrgPiiConfig?
23
24
 
24
25
  @@map("organizations")
25
26
  }
@@ -39,6 +40,21 @@ model OrgEmbeddingConfig {
39
40
  @@map("org_embedding_config")
40
41
  }
41
42
 
43
+ model OrgPiiConfig {
44
+ id String @id @default(uuid()) @db.Uuid
45
+ organizationId String @unique @map("organization_id") @db.Uuid
46
+ mode String @default("encrypt") @db.VarChar(20)
47
+ piiKeyEncrypted String @map("pii_key_encrypted") @db.Text
48
+ allowedPiiTypes Json @default("[]") @map("allowed_pii_types")
49
+ allowBypass Boolean @default(false) @map("allow_bypass")
50
+ updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz
51
+ updatedBy String @default("api") @map("updated_by") @db.VarChar(255)
52
+
53
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
54
+
55
+ @@map("org_pii_config")
56
+ }
57
+
42
58
  model Domain {
43
59
  id String @id @default(uuid()) @db.Uuid
44
60
  name String @db.VarChar(200)
@@ -75,6 +91,7 @@ model Node {
75
91
  createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
76
92
  updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz
77
93
  version Int @default(1)
94
+ hasPii Boolean @default(false) @map("has_pii")
78
95
  domainId String? @map("domain_id") @db.Uuid
79
96
  organizationId String @map("organization_id") @db.Uuid
80
97