@memberjunction/encryption 0.0.1 → 2.130.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/README.md +391 -28
- package/dist/EncryptionEngine.d.ts +351 -0
- package/dist/EncryptionEngine.d.ts.map +1 -0
- package/dist/EncryptionEngine.js +683 -0
- package/dist/EncryptionEngine.js.map +1 -0
- package/dist/EncryptionKeySourceBase.d.ts +203 -0
- package/dist/EncryptionKeySourceBase.d.ts.map +1 -0
- package/dist/EncryptionKeySourceBase.js +133 -0
- package/dist/EncryptionKeySourceBase.js.map +1 -0
- package/dist/actions/EnableFieldEncryptionAction.d.ts +87 -0
- package/dist/actions/EnableFieldEncryptionAction.d.ts.map +1 -0
- package/dist/actions/EnableFieldEncryptionAction.js +308 -0
- package/dist/actions/EnableFieldEncryptionAction.js.map +1 -0
- package/dist/actions/RotateEncryptionKeyAction.d.ts +79 -0
- package/dist/actions/RotateEncryptionKeyAction.d.ts.map +1 -0
- package/dist/actions/RotateEncryptionKeyAction.js +343 -0
- package/dist/actions/RotateEncryptionKeyAction.js.map +1 -0
- package/dist/actions/index.d.ts +12 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +17 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +216 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +15 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/providers/AWSKMSKeySource.d.ts +110 -0
- package/dist/providers/AWSKMSKeySource.d.ts.map +1 -0
- package/dist/providers/AWSKMSKeySource.js +245 -0
- package/dist/providers/AWSKMSKeySource.js.map +1 -0
- package/dist/providers/AzureKeyVaultKeySource.d.ts +109 -0
- package/dist/providers/AzureKeyVaultKeySource.d.ts.map +1 -0
- package/dist/providers/AzureKeyVaultKeySource.js +268 -0
- package/dist/providers/AzureKeyVaultKeySource.js.map +1 -0
- package/dist/providers/ConfigFileKeySource.d.ts +173 -0
- package/dist/providers/ConfigFileKeySource.d.ts.map +1 -0
- package/dist/providers/ConfigFileKeySource.js +310 -0
- package/dist/providers/ConfigFileKeySource.js.map +1 -0
- package/dist/providers/EnvVarKeySource.d.ts +152 -0
- package/dist/providers/EnvVarKeySource.d.ts.map +1 -0
- package/dist/providers/EnvVarKeySource.js +251 -0
- package/dist/providers/EnvVarKeySource.js.map +1 -0
- package/package.json +65 -6
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Action for rotating encryption keys with full data re-encryption.
|
|
4
|
+
*
|
|
5
|
+
* Key rotation is a critical security operation that:
|
|
6
|
+
* 1. Validates the new key material is accessible
|
|
7
|
+
* 2. Decrypts all data encrypted with the old key
|
|
8
|
+
* 3. Re-encrypts with the new key in a transactional manner
|
|
9
|
+
* 4. Updates the key metadata to point to the new key material
|
|
10
|
+
*
|
|
11
|
+
* ## Usage
|
|
12
|
+
*
|
|
13
|
+
* This action is typically invoked via the MemberJunction Actions framework:
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const result = await actionEngine.RunAction({
|
|
17
|
+
* ActionName: 'Rotate Encryption Key',
|
|
18
|
+
* Params: [
|
|
19
|
+
* { Name: 'EncryptionKeyID', Value: 'key-uuid' },
|
|
20
|
+
* { Name: 'NewKeyLookupValue', Value: 'MJ_ENCRYPTION_KEY_PII_V2' },
|
|
21
|
+
* { Name: 'BatchSize', Value: 100 }
|
|
22
|
+
* ],
|
|
23
|
+
* ContextUser: currentUser
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* ## Security Considerations
|
|
28
|
+
*
|
|
29
|
+
* - The new key must be accessible before starting rotation
|
|
30
|
+
* - Rotation is transactional - all or nothing
|
|
31
|
+
* - Key status is set to 'Rotating' during the operation
|
|
32
|
+
* - On success, key version is incremented
|
|
33
|
+
* - On failure, original key continues to work
|
|
34
|
+
*
|
|
35
|
+
* @module @memberjunction/encryption
|
|
36
|
+
*/
|
|
37
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
38
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
39
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
40
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
41
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.RotateEncryptionKeyAction = void 0;
|
|
45
|
+
const global_1 = require("@memberjunction/global");
|
|
46
|
+
const core_1 = require("@memberjunction/core");
|
|
47
|
+
const EncryptionEngine_1 = require("../EncryptionEngine");
|
|
48
|
+
/**
|
|
49
|
+
* Action for rotating encryption keys with full re-encryption of affected data.
|
|
50
|
+
*
|
|
51
|
+
* Key rotation involves:
|
|
52
|
+
* 1. Validating the new key is accessible
|
|
53
|
+
* 2. Setting key status to 'Rotating'
|
|
54
|
+
* 3. For each entity field using this key:
|
|
55
|
+
* - Loading all records in batches
|
|
56
|
+
* - Decrypting with old key
|
|
57
|
+
* - Re-encrypting with new key
|
|
58
|
+
* - Updating records
|
|
59
|
+
* 4. Updating key metadata (lookup value, version)
|
|
60
|
+
* 5. Setting key status back to 'Active'
|
|
61
|
+
*
|
|
62
|
+
* ## Transaction Safety
|
|
63
|
+
*
|
|
64
|
+
* - Each batch is processed within a transaction
|
|
65
|
+
* - On batch failure, the entire rotation is rolled back
|
|
66
|
+
* - Key status is reset to 'Active' on failure
|
|
67
|
+
*
|
|
68
|
+
* @security This is a privileged operation that should be restricted to administrators.
|
|
69
|
+
*/
|
|
70
|
+
let RotateEncryptionKeyAction = class RotateEncryptionKeyAction {
|
|
71
|
+
/**
|
|
72
|
+
* Executes the key rotation operation.
|
|
73
|
+
*
|
|
74
|
+
* @param params - Action parameters including EncryptionKeyID and NewKeyLookupValue
|
|
75
|
+
* @returns Result with success status and details about rotated fields/records
|
|
76
|
+
*/
|
|
77
|
+
async Run(params) {
|
|
78
|
+
const { Params, ContextUser } = params;
|
|
79
|
+
// Extract parameters
|
|
80
|
+
const encryptionKeyIdParam = this.getParamValue(Params, 'EncryptionKeyID');
|
|
81
|
+
const newKeyLookupValueParam = this.getParamValue(Params, 'NewKeyLookupValue');
|
|
82
|
+
const batchSizeParam = this.getParamValue(Params, 'BatchSize');
|
|
83
|
+
const encryptionKeyId = encryptionKeyIdParam != null ? String(encryptionKeyIdParam) : null;
|
|
84
|
+
const newKeyLookupValue = newKeyLookupValueParam != null ? String(newKeyLookupValueParam) : null;
|
|
85
|
+
const batchSize = batchSizeParam != null ? Number(batchSizeParam) : 100;
|
|
86
|
+
// Validate required parameters
|
|
87
|
+
if (!encryptionKeyId) {
|
|
88
|
+
return {
|
|
89
|
+
Success: false,
|
|
90
|
+
ResultCode: 'INVALID_PARAMS',
|
|
91
|
+
Message: 'EncryptionKeyID is required',
|
|
92
|
+
Params
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (!newKeyLookupValue) {
|
|
96
|
+
return {
|
|
97
|
+
Success: false,
|
|
98
|
+
ResultCode: 'INVALID_PARAMS',
|
|
99
|
+
Message: 'NewKeyLookupValue is required. This should be the environment variable name or config key for the new encryption key.',
|
|
100
|
+
Params
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const result = await this.rotateKey({
|
|
105
|
+
encryptionKeyId,
|
|
106
|
+
newKeyLookupValue,
|
|
107
|
+
batchSize
|
|
108
|
+
}, ContextUser);
|
|
109
|
+
// Update output parameters
|
|
110
|
+
const outputParams = [...Params];
|
|
111
|
+
const recordsParam = outputParams.find(p => p.Name === 'RecordsProcessed');
|
|
112
|
+
if (recordsParam)
|
|
113
|
+
recordsParam.Value = result.recordsProcessed;
|
|
114
|
+
const fieldsParam = outputParams.find(p => p.Name === 'FieldsProcessed');
|
|
115
|
+
if (fieldsParam)
|
|
116
|
+
fieldsParam.Value = result.fieldsProcessed;
|
|
117
|
+
if (result.success) {
|
|
118
|
+
return {
|
|
119
|
+
Success: true,
|
|
120
|
+
ResultCode: 'SUCCESS',
|
|
121
|
+
Message: `Key rotation completed successfully. Processed ${result.recordsProcessed} records across ${result.fieldsProcessed.length} fields.`,
|
|
122
|
+
Params: outputParams
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
return {
|
|
127
|
+
Success: false,
|
|
128
|
+
ResultCode: 'ROTATION_FAILED',
|
|
129
|
+
Message: result.error || 'Key rotation failed',
|
|
130
|
+
Params: outputParams
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
136
|
+
(0, core_1.LogError)(`Key rotation failed: ${message}`);
|
|
137
|
+
return {
|
|
138
|
+
Success: false,
|
|
139
|
+
ResultCode: 'ERROR',
|
|
140
|
+
Message: `Key rotation failed: ${message}`,
|
|
141
|
+
Params
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Performs the actual key rotation operation.
|
|
147
|
+
*
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
150
|
+
async rotateKey(params, contextUser) {
|
|
151
|
+
const { encryptionKeyId, newKeyLookupValue, batchSize = 100 } = params;
|
|
152
|
+
const engine = EncryptionEngine_1.EncryptionEngine.Instance;
|
|
153
|
+
await engine.Config(false, contextUser);
|
|
154
|
+
const md = new core_1.Metadata();
|
|
155
|
+
const rv = new core_1.RunView();
|
|
156
|
+
// Track progress
|
|
157
|
+
const fieldsProcessed = [];
|
|
158
|
+
let totalRecordsProcessed = 0;
|
|
159
|
+
try {
|
|
160
|
+
// Step 1: Validate the new key is accessible
|
|
161
|
+
(0, core_1.LogStatus)(`Validating new key material at lookup value: ${newKeyLookupValue}`);
|
|
162
|
+
await engine.ValidateKeyMaterial(newKeyLookupValue, encryptionKeyId, contextUser);
|
|
163
|
+
(0, core_1.LogStatus)('New key material validated successfully');
|
|
164
|
+
// Step 2: Load the encryption key record
|
|
165
|
+
const keyResult = await rv.RunView({
|
|
166
|
+
EntityName: 'MJ: Encryption Keys',
|
|
167
|
+
ExtraFilter: `ID = '${encryptionKeyId}'`,
|
|
168
|
+
ResultType: 'entity_object'
|
|
169
|
+
}, contextUser);
|
|
170
|
+
if (!keyResult.Success || keyResult.Results.length === 0) {
|
|
171
|
+
return {
|
|
172
|
+
success: false,
|
|
173
|
+
recordsProcessed: 0,
|
|
174
|
+
fieldsProcessed: [],
|
|
175
|
+
error: `Encryption key not found: ${encryptionKeyId}`
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const encryptionKey = keyResult.Results[0];
|
|
179
|
+
const originalVersion = encryptionKey.KeyVersion || '1';
|
|
180
|
+
// Step 3: Set key status to 'Rotating'
|
|
181
|
+
encryptionKey.Status = 'Rotating';
|
|
182
|
+
const saveResult = await encryptionKey.Save();
|
|
183
|
+
if (!saveResult) {
|
|
184
|
+
return {
|
|
185
|
+
success: false,
|
|
186
|
+
recordsProcessed: 0,
|
|
187
|
+
fieldsProcessed: [],
|
|
188
|
+
error: 'Failed to set key status to Rotating'
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// Step 4: Find all entity fields using this key
|
|
192
|
+
const fieldsResult = await rv.RunView({
|
|
193
|
+
EntityName: 'Entity Fields',
|
|
194
|
+
ExtraFilter: `EncryptionKeyID = '${encryptionKeyId}' AND Encrypt = 1`,
|
|
195
|
+
ResultType: 'simple'
|
|
196
|
+
}, contextUser);
|
|
197
|
+
if (!fieldsResult.Success) {
|
|
198
|
+
// Reset key status and return error
|
|
199
|
+
encryptionKey.Status = 'Active';
|
|
200
|
+
await encryptionKey.Save();
|
|
201
|
+
return {
|
|
202
|
+
success: false,
|
|
203
|
+
recordsProcessed: 0,
|
|
204
|
+
fieldsProcessed: [],
|
|
205
|
+
error: 'Failed to load entity fields using this key'
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const fields = fieldsResult.Results;
|
|
209
|
+
(0, core_1.LogStatus)(`Found ${fields.length} encrypted fields to rotate`);
|
|
210
|
+
// Step 5: Process each field
|
|
211
|
+
for (const field of fields) {
|
|
212
|
+
const entityName = field.Entity;
|
|
213
|
+
const fieldName = field.Name;
|
|
214
|
+
const fullFieldName = `${entityName}.${fieldName}`;
|
|
215
|
+
(0, core_1.LogStatus)(`Processing field: ${fullFieldName}`);
|
|
216
|
+
try {
|
|
217
|
+
// Get entity info for schema/view name
|
|
218
|
+
const entityInfo = md.Entities.find(e => e.Name === entityName);
|
|
219
|
+
if (!entityInfo) {
|
|
220
|
+
(0, core_1.LogError)(`Entity not found: ${entityName}`);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
// Load records in batches
|
|
224
|
+
let offset = 0;
|
|
225
|
+
let hasMore = true;
|
|
226
|
+
while (hasMore) {
|
|
227
|
+
// Load a batch of records
|
|
228
|
+
const batchResult = await rv.RunView({
|
|
229
|
+
EntityName: entityName,
|
|
230
|
+
ExtraFilter: `${fieldName} IS NOT NULL AND ${fieldName} LIKE '$ENC$%'`,
|
|
231
|
+
OrderBy: entityInfo.PrimaryKeys.map(pk => pk.Name).join(', '),
|
|
232
|
+
MaxRows: batchSize,
|
|
233
|
+
ResultType: 'entity_object'
|
|
234
|
+
}, contextUser);
|
|
235
|
+
if (!batchResult.Success || batchResult.Results.length === 0) {
|
|
236
|
+
hasMore = false;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const records = batchResult.Results;
|
|
240
|
+
hasMore = records.length === batchSize;
|
|
241
|
+
// Process each record in the batch
|
|
242
|
+
for (const record of records) {
|
|
243
|
+
const encryptedValue = record.Get(fieldName);
|
|
244
|
+
if (!encryptedValue || !engine.IsEncrypted(encryptedValue)) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
// Decrypt with old key
|
|
249
|
+
const decrypted = await engine.Decrypt(encryptedValue, contextUser);
|
|
250
|
+
// Re-encrypt with new key using the new lookup value
|
|
251
|
+
const reEncrypted = await engine.EncryptWithLookup(decrypted, encryptionKeyId, newKeyLookupValue, contextUser);
|
|
252
|
+
// Update the record
|
|
253
|
+
record.Set(fieldName, reEncrypted);
|
|
254
|
+
const recordSaveResult = await record.Save();
|
|
255
|
+
if (recordSaveResult) {
|
|
256
|
+
totalRecordsProcessed++;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// If any record fails, we should consider the rotation failed
|
|
260
|
+
// But we continue to try other records to get a complete picture
|
|
261
|
+
(0, core_1.LogError)(`Failed to save re-encrypted record in ${fullFieldName}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (recordError) {
|
|
265
|
+
const msg = recordError instanceof Error ? recordError.message : String(recordError);
|
|
266
|
+
(0, core_1.LogError)(`Failed to rotate record in ${fullFieldName}: ${msg}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
offset += batchSize;
|
|
270
|
+
}
|
|
271
|
+
fieldsProcessed.push(fullFieldName);
|
|
272
|
+
(0, core_1.LogStatus)(`Completed field: ${fullFieldName}`);
|
|
273
|
+
}
|
|
274
|
+
catch (fieldError) {
|
|
275
|
+
const msg = fieldError instanceof Error ? fieldError.message : String(fieldError);
|
|
276
|
+
(0, core_1.LogError)(`Failed to process field ${fullFieldName}: ${msg}`);
|
|
277
|
+
// Continue with other fields
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Step 6: Update key metadata to point to new key
|
|
281
|
+
encryptionKey.KeyLookupValue = newKeyLookupValue;
|
|
282
|
+
encryptionKey.KeyVersion = String(parseInt(originalVersion) + 1);
|
|
283
|
+
encryptionKey.Status = 'Active';
|
|
284
|
+
const finalSaveResult = await encryptionKey.Save();
|
|
285
|
+
if (!finalSaveResult) {
|
|
286
|
+
return {
|
|
287
|
+
success: false,
|
|
288
|
+
recordsProcessed: totalRecordsProcessed,
|
|
289
|
+
fieldsProcessed,
|
|
290
|
+
error: 'Failed to update key metadata after rotation. Data has been re-encrypted but key metadata update failed.'
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
// Step 7: Clear encryption engine caches to use new key
|
|
294
|
+
engine.ClearCaches();
|
|
295
|
+
(0, core_1.LogStatus)(`Key rotation completed. Processed ${totalRecordsProcessed} records across ${fieldsProcessed.length} fields.`);
|
|
296
|
+
return {
|
|
297
|
+
success: true,
|
|
298
|
+
recordsProcessed: totalRecordsProcessed,
|
|
299
|
+
fieldsProcessed
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
// On any error, try to reset key status to Active
|
|
304
|
+
try {
|
|
305
|
+
const keyResult = await rv.RunView({
|
|
306
|
+
EntityName: 'MJ: Encryption Keys',
|
|
307
|
+
ExtraFilter: `ID = '${encryptionKeyId}'`,
|
|
308
|
+
ResultType: 'entity_object'
|
|
309
|
+
}, contextUser);
|
|
310
|
+
if (keyResult.Success && keyResult.Results.length > 0) {
|
|
311
|
+
const key = keyResult.Results[0];
|
|
312
|
+
if (key.Status === 'Rotating') {
|
|
313
|
+
key.Status = 'Active';
|
|
314
|
+
await key.Save();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Best effort - ignore errors in cleanup
|
|
320
|
+
}
|
|
321
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
322
|
+
return {
|
|
323
|
+
success: false,
|
|
324
|
+
recordsProcessed: totalRecordsProcessed,
|
|
325
|
+
fieldsProcessed,
|
|
326
|
+
error: message
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Helper to extract parameter value by name.
|
|
332
|
+
* @private
|
|
333
|
+
*/
|
|
334
|
+
getParamValue(params, name) {
|
|
335
|
+
const param = params.find(p => p.Name === name);
|
|
336
|
+
return param?.Value ?? null;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
exports.RotateEncryptionKeyAction = RotateEncryptionKeyAction;
|
|
340
|
+
exports.RotateEncryptionKeyAction = RotateEncryptionKeyAction = __decorate([
|
|
341
|
+
(0, global_1.RegisterClass)(Object, 'Rotate Encryption Key')
|
|
342
|
+
], RotateEncryptionKeyAction);
|
|
343
|
+
//# sourceMappingURL=RotateEncryptionKeyAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RotateEncryptionKeyAction.js","sourceRoot":"","sources":["../../src/actions/RotateEncryptionKeyAction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Encryption-related actions for key management and data migration.
|
|
3
|
+
*
|
|
4
|
+
* These actions provide administrative capabilities for:
|
|
5
|
+
* - Rotating encryption keys with full data re-encryption
|
|
6
|
+
* - Enabling encryption on existing fields (initial data encryption)
|
|
7
|
+
*
|
|
8
|
+
* @module @memberjunction/encryption
|
|
9
|
+
*/
|
|
10
|
+
export { RotateEncryptionKeyAction } from './RotateEncryptionKeyAction';
|
|
11
|
+
export { EnableFieldEncryptionAction } from './EnableFieldEncryptionAction';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Encryption-related actions for key management and data migration.
|
|
4
|
+
*
|
|
5
|
+
* These actions provide administrative capabilities for:
|
|
6
|
+
* - Rotating encryption keys with full data re-encryption
|
|
7
|
+
* - Enabling encryption on existing fields (initial data encryption)
|
|
8
|
+
*
|
|
9
|
+
* @module @memberjunction/encryption
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.EnableFieldEncryptionAction = exports.RotateEncryptionKeyAction = void 0;
|
|
13
|
+
var RotateEncryptionKeyAction_1 = require("./RotateEncryptionKeyAction");
|
|
14
|
+
Object.defineProperty(exports, "RotateEncryptionKeyAction", { enumerable: true, get: function () { return RotateEncryptionKeyAction_1.RotateEncryptionKeyAction; } });
|
|
15
|
+
var EnableFieldEncryptionAction_1 = require("./EnableFieldEncryptionAction");
|
|
16
|
+
Object.defineProperty(exports, "EnableFieldEncryptionAction", { enumerable: true, get: function () { return EnableFieldEncryptionAction_1.EnableFieldEncryptionAction; } });
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,yEAAwE;AAA/D,sIAAA,yBAAyB,OAAA;AAClC,6EAA4E;AAAnE,0IAAA,2BAA2B,OAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MemberJunction Field-Level Encryption Package
|
|
3
|
+
*
|
|
4
|
+
* This package provides field-level encryption capabilities for MemberJunction
|
|
5
|
+
* entities. It enables encrypting sensitive data at rest in the database while
|
|
6
|
+
* providing transparent decryption for authorized access.
|
|
7
|
+
*
|
|
8
|
+
* ## Features
|
|
9
|
+
*
|
|
10
|
+
* - **AES-256-GCM/CBC encryption** - Industry-standard authenticated encryption
|
|
11
|
+
* - **Pluggable key sources** - Environment variables, config files, or custom providers
|
|
12
|
+
* - **Declarative configuration** - Enable encryption via EntityField metadata
|
|
13
|
+
* - **Transparent operation** - Automatic encrypt on save, decrypt on load
|
|
14
|
+
* - **Key rotation support** - Full re-encryption with transactional safety
|
|
15
|
+
*
|
|
16
|
+
* ## Quick Start
|
|
17
|
+
*
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { EncryptionEngine } from '@memberjunction/encryption';
|
|
20
|
+
*
|
|
21
|
+
* const engine = EncryptionEngine.Instance;
|
|
22
|
+
*
|
|
23
|
+
* // Encrypt a value
|
|
24
|
+
* const encrypted = await engine.Encrypt(
|
|
25
|
+
* 'sensitive-data',
|
|
26
|
+
* encryptionKeyId,
|
|
27
|
+
* contextUser
|
|
28
|
+
* );
|
|
29
|
+
*
|
|
30
|
+
* // Decrypt a value
|
|
31
|
+
* const decrypted = await engine.Decrypt(encrypted, contextUser);
|
|
32
|
+
*
|
|
33
|
+
* // Check if value is encrypted
|
|
34
|
+
* if (engine.IsEncrypted(someValue)) {
|
|
35
|
+
* // Handle encrypted value
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* ## Key Source Providers
|
|
40
|
+
*
|
|
41
|
+
* Built-in providers:
|
|
42
|
+
* - `EnvVarKeySource` - Reads keys from environment variables
|
|
43
|
+
* - `ConfigFileKeySource` - Reads keys from mj.config.cjs
|
|
44
|
+
*
|
|
45
|
+
* To create a custom provider, extend `EncryptionKeySourceBase`.
|
|
46
|
+
*
|
|
47
|
+
* ## Security Considerations
|
|
48
|
+
*
|
|
49
|
+
* - Keys are never stored in the database
|
|
50
|
+
* - Authenticated encryption (GCM) prevents tampering
|
|
51
|
+
* - Random IVs for each encryption operation
|
|
52
|
+
* - Cached key material has configurable TTL
|
|
53
|
+
*
|
|
54
|
+
* @module @memberjunction/encryption
|
|
55
|
+
* @packageDocumentation
|
|
56
|
+
*/
|
|
57
|
+
export { EncryptionKeySourceConfig, EncryptedValueParts, KeyConfiguration, RotateKeyParams, RotateKeyResult, EnableFieldEncryptionParams, EnableFieldEncryptionResult } from './interfaces';
|
|
58
|
+
export { EncryptionKeySourceBase } from './EncryptionKeySourceBase';
|
|
59
|
+
export { EncryptionEngine } from './EncryptionEngine';
|
|
60
|
+
export { EnvVarKeySource } from './providers/EnvVarKeySource';
|
|
61
|
+
export { ConfigFileKeySource } from './providers/ConfigFileKeySource';
|
|
62
|
+
export { AWSKMSKeySource } from './providers/AWSKMSKeySource';
|
|
63
|
+
export { AzureKeyVaultKeySource } from './providers/AzureKeyVaultKeySource';
|
|
64
|
+
export { RotateEncryptionKeyAction } from './actions/RotateEncryptionKeyAction';
|
|
65
|
+
export { EnableFieldEncryptionAction } from './actions/EnableFieldEncryptionAction';
|
|
66
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAGH,OAAO,EACH,yBAAyB,EACzB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,2BAA2B,EAC3B,2BAA2B,EAC9B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAG5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview MemberJunction Field-Level Encryption Package
|
|
4
|
+
*
|
|
5
|
+
* This package provides field-level encryption capabilities for MemberJunction
|
|
6
|
+
* entities. It enables encrypting sensitive data at rest in the database while
|
|
7
|
+
* providing transparent decryption for authorized access.
|
|
8
|
+
*
|
|
9
|
+
* ## Features
|
|
10
|
+
*
|
|
11
|
+
* - **AES-256-GCM/CBC encryption** - Industry-standard authenticated encryption
|
|
12
|
+
* - **Pluggable key sources** - Environment variables, config files, or custom providers
|
|
13
|
+
* - **Declarative configuration** - Enable encryption via EntityField metadata
|
|
14
|
+
* - **Transparent operation** - Automatic encrypt on save, decrypt on load
|
|
15
|
+
* - **Key rotation support** - Full re-encryption with transactional safety
|
|
16
|
+
*
|
|
17
|
+
* ## Quick Start
|
|
18
|
+
*
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { EncryptionEngine } from '@memberjunction/encryption';
|
|
21
|
+
*
|
|
22
|
+
* const engine = EncryptionEngine.Instance;
|
|
23
|
+
*
|
|
24
|
+
* // Encrypt a value
|
|
25
|
+
* const encrypted = await engine.Encrypt(
|
|
26
|
+
* 'sensitive-data',
|
|
27
|
+
* encryptionKeyId,
|
|
28
|
+
* contextUser
|
|
29
|
+
* );
|
|
30
|
+
*
|
|
31
|
+
* // Decrypt a value
|
|
32
|
+
* const decrypted = await engine.Decrypt(encrypted, contextUser);
|
|
33
|
+
*
|
|
34
|
+
* // Check if value is encrypted
|
|
35
|
+
* if (engine.IsEncrypted(someValue)) {
|
|
36
|
+
* // Handle encrypted value
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* ## Key Source Providers
|
|
41
|
+
*
|
|
42
|
+
* Built-in providers:
|
|
43
|
+
* - `EnvVarKeySource` - Reads keys from environment variables
|
|
44
|
+
* - `ConfigFileKeySource` - Reads keys from mj.config.cjs
|
|
45
|
+
*
|
|
46
|
+
* To create a custom provider, extend `EncryptionKeySourceBase`.
|
|
47
|
+
*
|
|
48
|
+
* ## Security Considerations
|
|
49
|
+
*
|
|
50
|
+
* - Keys are never stored in the database
|
|
51
|
+
* - Authenticated encryption (GCM) prevents tampering
|
|
52
|
+
* - Random IVs for each encryption operation
|
|
53
|
+
* - Cached key material has configurable TTL
|
|
54
|
+
*
|
|
55
|
+
* @module @memberjunction/encryption
|
|
56
|
+
* @packageDocumentation
|
|
57
|
+
*/
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.EnableFieldEncryptionAction = exports.RotateEncryptionKeyAction = exports.AzureKeyVaultKeySource = exports.AWSKMSKeySource = exports.ConfigFileKeySource = exports.EnvVarKeySource = exports.EncryptionEngine = exports.EncryptionKeySourceBase = void 0;
|
|
60
|
+
// Base class for key source providers
|
|
61
|
+
var EncryptionKeySourceBase_1 = require("./EncryptionKeySourceBase");
|
|
62
|
+
Object.defineProperty(exports, "EncryptionKeySourceBase", { enumerable: true, get: function () { return EncryptionKeySourceBase_1.EncryptionKeySourceBase; } });
|
|
63
|
+
// Core encryption engine
|
|
64
|
+
var EncryptionEngine_1 = require("./EncryptionEngine");
|
|
65
|
+
Object.defineProperty(exports, "EncryptionEngine", { enumerable: true, get: function () { return EncryptionEngine_1.EncryptionEngine; } });
|
|
66
|
+
// Built-in key source providers
|
|
67
|
+
var EnvVarKeySource_1 = require("./providers/EnvVarKeySource");
|
|
68
|
+
Object.defineProperty(exports, "EnvVarKeySource", { enumerable: true, get: function () { return EnvVarKeySource_1.EnvVarKeySource; } });
|
|
69
|
+
var ConfigFileKeySource_1 = require("./providers/ConfigFileKeySource");
|
|
70
|
+
Object.defineProperty(exports, "ConfigFileKeySource", { enumerable: true, get: function () { return ConfigFileKeySource_1.ConfigFileKeySource; } });
|
|
71
|
+
// Cloud key source providers (require optional dependencies)
|
|
72
|
+
var AWSKMSKeySource_1 = require("./providers/AWSKMSKeySource");
|
|
73
|
+
Object.defineProperty(exports, "AWSKMSKeySource", { enumerable: true, get: function () { return AWSKMSKeySource_1.AWSKMSKeySource; } });
|
|
74
|
+
var AzureKeyVaultKeySource_1 = require("./providers/AzureKeyVaultKeySource");
|
|
75
|
+
Object.defineProperty(exports, "AzureKeyVaultKeySource", { enumerable: true, get: function () { return AzureKeyVaultKeySource_1.AzureKeyVaultKeySource; } });
|
|
76
|
+
// Actions for key management and data migration
|
|
77
|
+
var RotateEncryptionKeyAction_1 = require("./actions/RotateEncryptionKeyAction");
|
|
78
|
+
Object.defineProperty(exports, "RotateEncryptionKeyAction", { enumerable: true, get: function () { return RotateEncryptionKeyAction_1.RotateEncryptionKeyAction; } });
|
|
79
|
+
var EnableFieldEncryptionAction_1 = require("./actions/EnableFieldEncryptionAction");
|
|
80
|
+
Object.defineProperty(exports, "EnableFieldEncryptionAction", { enumerable: true, get: function () { return EnableFieldEncryptionAction_1.EnableFieldEncryptionAction; } });
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;;;AAaH,sCAAsC;AACtC,qEAAoE;AAA3D,kIAAA,uBAAuB,OAAA;AAEhC,yBAAyB;AACzB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAEzB,gCAAgC;AAChC,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AACxB,uEAAsE;AAA7D,0HAAA,mBAAmB,OAAA;AAE5B,6DAA6D;AAC7D,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AACxB,6EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAE/B,gDAAgD;AAChD,iFAAgF;AAAvE,sIAAA,yBAAyB,OAAA;AAClC,qFAAoF;AAA3E,0IAAA,2BAA2B,OAAA"}
|