@dynamatix/gb-schemas 2.17.13 → 2.20.1
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/applicants/applicant-additional-income.model.d.ts +1 -0
- package/dist/applicants/applicant-additional-income.model.d.ts.map +1 -1
- package/dist/applicants/applicant-additional-income.type.d.ts +1 -0
- package/dist/applicants/applicant-additional-income.type.d.ts.map +1 -1
- package/dist/applicants/applicant-commitment-creditCard.model.d.ts +1 -0
- package/dist/applicants/applicant-commitment-creditCard.model.d.ts.map +1 -1
- package/dist/applicants/applicant-commitment-loan.model.d.ts +1 -0
- package/dist/applicants/applicant-commitment-loan.model.d.ts.map +1 -1
- package/dist/applicants/applicant-commitment-mortgage.model.d.ts +1 -0
- package/dist/applicants/applicant-commitment-mortgage.model.d.ts.map +1 -1
- package/dist/applicants/applicant-commitment-residence.model.d.ts +1 -0
- package/dist/applicants/applicant-commitment-residence.model.d.ts.map +1 -1
- package/dist/applicants/applicant-commitment-secureLoan.model.d.ts +1 -0
- package/dist/applicants/applicant-commitment-secureLoan.model.d.ts.map +1 -1
- package/dist/applicants/applicant-commitment-unsecuredLoan.model.d.ts +1 -0
- package/dist/applicants/applicant-commitment-unsecuredLoan.model.d.ts.map +1 -1
- package/dist/applicants/applicant-credit-data.model.d.ts +1 -0
- package/dist/applicants/applicant-credit-data.model.d.ts.map +1 -1
- package/dist/applicants/applicant-credit-profile.model.d.ts +1 -0
- package/dist/applicants/applicant-credit-profile.model.d.ts.map +1 -1
- package/dist/applicants/applicant-credit-report.model.d.ts +1 -0
- package/dist/applicants/applicant-credit-report.model.d.ts.map +1 -1
- package/dist/applicants/applicant-credit-report.type.d.ts +1 -0
- package/dist/applicants/applicant-credit-report.type.d.ts.map +1 -1
- package/dist/applicants/applicant-employment-income.model.d.ts +1 -0
- package/dist/applicants/applicant-employment-income.model.d.ts.map +1 -1
- package/dist/applicants/applicant-employment-income.type.d.ts +1 -0
- package/dist/applicants/applicant-employment-income.type.d.ts.map +1 -1
- package/dist/applicants/applicant-employment.model.d.ts +1 -0
- package/dist/applicants/applicant-employment.model.d.ts.map +1 -1
- package/dist/applicants/applicant-expenditure.model.d.ts +1 -0
- package/dist/applicants/applicant-expenditure.model.d.ts.map +1 -1
- package/dist/applicants/applicant-expenditure.type.d.ts +1 -0
- package/dist/applicants/applicant-expenditure.type.d.ts.map +1 -1
- package/dist/applicants/applicant-income-settings.model.d.ts +1 -0
- package/dist/applicants/applicant-income-settings.model.d.ts.map +1 -1
- package/dist/applicants/applicant-income-settings.type.d.ts +1 -0
- package/dist/applicants/applicant-income-settings.type.d.ts.map +1 -1
- package/dist/applicants/applicant-income-summary.model.d.ts +1 -0
- package/dist/applicants/applicant-income-summary.model.d.ts.map +1 -1
- package/dist/applicants/applicant-income-summary.type.d.ts +1 -0
- package/dist/applicants/applicant-income-summary.type.d.ts.map +1 -1
- package/dist/applicants/applicant-large-exposure.model.d.ts +1 -0
- package/dist/applicants/applicant-large-exposure.model.d.ts.map +1 -1
- package/dist/applicants/applicant-large-exposure.type.d.ts +1 -0
- package/dist/applicants/applicant-large-exposure.type.d.ts.map +1 -1
- package/dist/applicants/applicant-pension-income.model.d.ts +1 -0
- package/dist/applicants/applicant-pension-income.model.d.ts.map +1 -1
- package/dist/applicants/applicant-pension-income.type.d.ts +1 -0
- package/dist/applicants/applicant-pension-income.type.d.ts.map +1 -1
- package/dist/applicants/applicant-property-income.model.d.ts +1 -0
- package/dist/applicants/applicant-property-income.model.d.ts.map +1 -1
- package/dist/applicants/applicant-property-income.type.d.ts +1 -0
- package/dist/applicants/applicant-property-income.type.d.ts.map +1 -1
- package/dist/applicants/applicant-risk-narrative.model.d.ts +1 -0
- package/dist/applicants/applicant-risk-narrative.model.d.ts.map +1 -1
- package/dist/applicants/applicant-self-employed-income.model.d.ts +1 -0
- package/dist/applicants/applicant-self-employed-income.model.d.ts.map +1 -1
- package/dist/applicants/applicant-self-employed-income.type.d.ts +1 -0
- package/dist/applicants/applicant-self-employed-income.type.d.ts.map +1 -1
- package/dist/applicants/applicant-self-employment.model.d.ts +1 -0
- package/dist/applicants/applicant-self-employment.model.d.ts.map +1 -1
- package/dist/applicants/applicant-sole-trader-income.model.d.ts +1 -0
- package/dist/applicants/applicant-sole-trader-income.model.d.ts.map +1 -1
- package/dist/applicants/applicant-sole-trader-income.type.d.ts +1 -0
- package/dist/applicants/applicant-sole-trader-income.type.d.ts.map +1 -1
- package/dist/applicants/applicant-uk-tax-credits.model.d.ts +1 -0
- package/dist/applicants/applicant-uk-tax-credits.model.d.ts.map +1 -1
- package/dist/applicants/applicant-uk-tax-credits.type.d.ts +1 -0
- package/dist/applicants/applicant-uk-tax-credits.type.d.ts.map +1 -1
- package/dist/applicants/applicant-welcome-call.model.d.ts +1 -0
- package/dist/applicants/applicant-welcome-call.model.d.ts.map +1 -1
- package/dist/applicants/applicant-welcome-call.type.d.ts +1 -0
- package/dist/applicants/applicant-welcome-call.type.d.ts.map +1 -1
- package/dist/applicants/applicant.model.d.ts +1 -54
- package/dist/applicants/applicant.model.d.ts.map +1 -1
- package/dist/applicants/applicant.model.js +33 -33
- package/dist/applicants/applicant.type.d.ts +1 -1
- package/dist/applicants/applicant.type.d.ts.map +1 -1
- package/dist/applications/application-audit.model.d.ts +1 -0
- package/dist/applications/application-audit.model.d.ts.map +1 -1
- package/dist/applications/application-checklist-Item.model.d.ts +1 -0
- package/dist/applications/application-checklist-Item.model.d.ts.map +1 -1
- package/dist/applications/application-company-model.d.ts +1 -0
- package/dist/applications/application-company-model.d.ts.map +1 -1
- package/dist/applications/application-credit-profile.model.d.ts +1 -0
- package/dist/applications/application-credit-profile.model.d.ts.map +1 -1
- package/dist/applications/application-direct-debit.model.d.ts +4 -3
- package/dist/applications/application-direct-debit.model.d.ts.map +1 -1
- package/dist/applications/application-direct-debit.model.js +20 -10
- package/dist/applications/application-direct-debit.type.d.ts +1 -0
- package/dist/applications/application-direct-debit.type.d.ts.map +1 -1
- package/dist/applications/application-euc.model.d.ts +1 -0
- package/dist/applications/application-euc.model.d.ts.map +1 -1
- package/dist/applications/application-euc.type.d.ts +1 -0
- package/dist/applications/application-euc.type.d.ts.map +1 -1
- package/dist/applications/application-fieldconfig.model.d.ts +1 -0
- package/dist/applications/application-fieldconfig.model.d.ts.map +1 -1
- package/dist/applications/application-illustration-model.d.ts +1 -0
- package/dist/applications/application-illustration-model.d.ts.map +1 -1
- package/dist/applications/application-legal.model.d.ts +1 -0
- package/dist/applications/application-legal.model.d.ts.map +1 -1
- package/dist/applications/application-mortgage.model.d.ts +1 -0
- package/dist/applications/application-mortgage.model.d.ts.map +1 -1
- package/dist/applications/application-mortgage.type.d.ts +1 -0
- package/dist/applications/application-mortgage.type.d.ts.map +1 -1
- package/dist/applications/application-note.model.d.ts +1 -0
- package/dist/applications/application-note.model.d.ts.map +1 -1
- package/dist/applications/application-note.type.d.ts +1 -0
- package/dist/applications/application-note.type.d.ts.map +1 -1
- package/dist/applications/application-offer.model.d.ts +1 -0
- package/dist/applications/application-offer.model.d.ts.map +1 -1
- package/dist/applications/application-offer.type.d.ts +1 -0
- package/dist/applications/application-offer.type.d.ts.map +1 -1
- package/dist/applications/application-onboarding.model.d.ts +1 -0
- package/dist/applications/application-onboarding.model.d.ts.map +1 -1
- package/dist/applications/application-product.model.d.ts +1 -0
- package/dist/applications/application-product.model.d.ts.map +1 -1
- package/dist/applications/application-product.type.d.ts +1 -0
- package/dist/applications/application-product.type.d.ts.map +1 -1
- package/dist/applications/application-productfeatures.model.d.ts +1 -0
- package/dist/applications/application-productfeatures.model.d.ts.map +1 -1
- package/dist/applications/application-productfeatures.type.d.ts +1 -0
- package/dist/applications/application-productfeatures.type.d.ts.map +1 -1
- package/dist/applications/application-rationale.model.d.ts +1 -0
- package/dist/applications/application-rationale.model.d.ts.map +1 -1
- package/dist/applications/application-rationale.type.d.ts +1 -0
- package/dist/applications/application-rationale.type.d.ts.map +1 -1
- package/dist/applications/application-risk-narrative.model.d.ts +1 -0
- package/dist/applications/application-risk-narrative.model.d.ts.map +1 -1
- package/dist/applications/application-valuation-report.model.d.ts +1 -0
- package/dist/applications/application-valuation-report.model.d.ts.map +1 -1
- package/dist/applications/application-valuation-report.type.d.ts +1 -0
- package/dist/applications/application-valuation-report.type.d.ts.map +1 -1
- package/dist/applications/application-valuation.model.d.ts +1 -0
- package/dist/applications/application-valuation.model.d.ts.map +1 -1
- package/dist/applications/application-valuation.type.d.ts +1 -0
- package/dist/applications/application-valuation.type.d.ts.map +1 -1
- package/dist/applications/application.model.d.ts +1 -0
- package/dist/applications/application.model.d.ts.map +1 -1
- package/dist/applications/applications-task.model.d.ts +1 -0
- package/dist/applications/applications-task.model.d.ts.map +1 -1
- package/dist/applications/applications-task.type.d.ts +1 -0
- package/dist/applications/applications-task.type.d.ts.map +1 -1
- package/dist/applications/broker.model.d.ts +1 -0
- package/dist/applications/broker.model.d.ts.map +1 -1
- package/dist/applications/broker.type.d.ts +1 -0
- package/dist/applications/broker.type.d.ts.map +1 -1
- package/dist/applications/solicitor.model.d.ts +1 -0
- package/dist/applications/solicitor.model.d.ts.map +1 -1
- package/dist/applications/solicitor.type.d.ts +1 -0
- package/dist/applications/solicitor.type.d.ts.map +1 -1
- package/dist/product-catalogues/product-catalogue.model.d.ts +1 -0
- package/dist/product-catalogues/product-catalogue.model.d.ts.map +1 -1
- package/dist/product-catalogues/product-definitions.model.d.ts +1 -0
- package/dist/product-catalogues/product-definitions.model.d.ts.map +1 -1
- package/dist/product-catalogues/product-definitions.type.d.ts +1 -0
- package/dist/product-catalogues/product-definitions.type.d.ts.map +1 -1
- package/dist/product-catalogues/product-variant.model.d.ts +1 -0
- package/dist/product-catalogues/product-variant.model.d.ts.map +1 -1
- package/dist/product-catalogues/product-variant.type.d.ts +1 -0
- package/dist/product-catalogues/product-variant.type.d.ts.map +1 -1
- package/dist/properties/property.model.d.ts +1 -0
- package/dist/properties/property.model.d.ts.map +1 -1
- package/dist/properties/security.model.d.ts +1 -0
- package/dist/properties/security.model.d.ts.map +1 -1
- package/dist/shared/alert.model.d.ts +1 -0
- package/dist/shared/alert.model.d.ts.map +1 -1
- package/dist/shared/api-log.model.d.ts +1 -0
- package/dist/shared/api-log.model.d.ts.map +1 -1
- package/dist/shared/api-performance.model.d.ts +1 -0
- package/dist/shared/api-performance.model.d.ts.map +1 -1
- package/dist/shared/api-performance.type.d.ts +1 -0
- package/dist/shared/api-performance.type.d.ts.map +1 -1
- package/dist/shared/apprivo-sync-journey.model.d.ts +1 -0
- package/dist/shared/apprivo-sync-journey.model.d.ts.map +1 -1
- package/dist/shared/checklist.model.d.ts +1 -0
- package/dist/shared/checklist.model.d.ts.map +1 -1
- package/dist/shared/encryption/encrypted-field-map.d.ts +146 -0
- package/dist/shared/encryption/encrypted-field-map.d.ts.map +1 -0
- package/dist/shared/encryption/encrypted-field-map.js +130 -0
- package/dist/shared/encryption/encryption-filter.guard.d.ts +69 -0
- package/dist/shared/encryption/encryption-filter.guard.d.ts.map +1 -0
- package/dist/shared/encryption/encryption-filter.guard.js +103 -0
- package/dist/shared/encryption/encryption.config.d.ts +55 -0
- package/dist/shared/encryption/encryption.config.d.ts.map +1 -0
- package/dist/shared/encryption/encryption.config.js +76 -0
- package/dist/shared/encryption/encryption.init.d.ts +66 -0
- package/dist/shared/encryption/encryption.init.d.ts.map +1 -0
- package/dist/shared/encryption/encryption.init.js +86 -0
- package/dist/shared/encryption/encryption.plugin.d.ts +225 -0
- package/dist/shared/encryption/encryption.plugin.d.ts.map +1 -0
- package/dist/shared/encryption/encryption.plugin.js +372 -0
- package/dist/shared/encryption/encryption.service.d.ts +110 -0
- package/dist/shared/encryption/encryption.service.d.ts.map +1 -0
- package/dist/shared/encryption/encryption.service.js +151 -0
- package/dist/shared/encryption/index.d.ts +8 -0
- package/dist/shared/encryption/index.d.ts.map +1 -0
- package/dist/shared/encryption/index.js +6 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +2 -0
- package/dist/shared/job-run.model.d.ts +1 -0
- package/dist/shared/job-run.model.d.ts.map +1 -1
- package/dist/shared/job-setting.model.d.ts +1 -0
- package/dist/shared/job-setting.model.d.ts.map +1 -1
- package/dist/shared/lookup-group.model.d.ts +1 -0
- package/dist/shared/lookup-group.model.d.ts.map +1 -1
- package/dist/shared/lookup.model.d.ts +7 -0
- package/dist/shared/lookup.model.d.ts.map +1 -1
- package/dist/shared/lookup.model.js +5 -0
- package/dist/shared/schema-doc.model.d.ts +1 -0
- package/dist/shared/schema-doc.model.d.ts.map +1 -1
- package/dist/shared/system-parameter.model.d.ts +1 -0
- package/dist/shared/system-parameter.model.d.ts.map +1 -1
- package/dist/shared/task-document.model.d.ts +1 -0
- package/dist/shared/task-document.model.d.ts.map +1 -1
- package/dist/shared/task.model.d.ts +1 -0
- package/dist/shared/task.model.d.ts.map +1 -1
- package/dist/shared/webhook-event.model.d.ts +1 -0
- package/dist/shared/webhook-event.model.d.ts.map +1 -1
- package/dist/shared/workflow-trigger.model.d.ts +1 -0
- package/dist/shared/workflow-trigger.model.d.ts.map +1 -1
- package/dist/shared/workflow-trigger.type.d.ts +1 -0
- package/dist/shared/workflow-trigger.type.d.ts.map +1 -1
- package/dist/shared/workflow.middleware.d.ts +1 -0
- package/dist/shared/workflow.middleware.d.ts.map +1 -1
- package/dist/shared/workflow.plugin.d.ts +1 -0
- package/dist/shared/workflow.plugin.d.ts.map +1 -1
- package/dist/types/base.types.d.ts +1 -0
- package/dist/types/base.types.d.ts.map +1 -1
- package/dist/underwriter/underwriter.model.d.ts +1 -0
- package/dist/underwriter/underwriter.model.d.ts.map +1 -1
- package/dist/users/auth-log.model.d.ts +1 -0
- package/dist/users/auth-log.model.d.ts.map +1 -1
- package/dist/users/permission.model.d.ts +1 -0
- package/dist/users/permission.model.d.ts.map +1 -1
- package/dist/users/role-group.model.d.ts +1 -0
- package/dist/users/role-group.model.d.ts.map +1 -1
- package/dist/users/role.model.d.ts +1 -0
- package/dist/users/role.model.d.ts.map +1 -1
- package/dist/users/tasks.model.d.ts +1 -0
- package/dist/users/tasks.model.d.ts.map +1 -1
- package/dist/users/user.model.d.ts +1 -0
- package/dist/users/user.model.d.ts.map +1 -1
- package/dist/users/user.type.d.ts +1 -0
- package/dist/users/user.type.d.ts.map +1 -1
- package/dist/value-objects/account-number.d.ts +1 -0
- package/dist/value-objects/account-number.d.ts.map +1 -1
- package/dist/value-objects/pound.d.ts +1 -0
- package/dist/value-objects/pound.d.ts.map +1 -1
- package/dist/value-objects/sort-code.d.ts +1 -0
- package/dist/value-objects/sort-code.d.ts.map +1 -1
- package/package.json +6 -3
- package/dist/applicants/applicant-direct-debit.model.d.ts +0 -86
- package/dist/applicants/applicant-direct-debit.model.d.ts.map +0 -1
- package/dist/applicants/applicant-direct-debit.model.js +0 -16
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutable configuration for the field-level encryption layer.
|
|
3
|
+
*
|
|
4
|
+
* The master key is supplied via the `GH_ENCRYPTION_MASTER_KEY` environment
|
|
5
|
+
* variable as a base64-encoded 96-byte value and acts as the `local` KMS
|
|
6
|
+
* provider key for MongoDB Client-Side Field Level Encryption. Validation is
|
|
7
|
+
* fail-fast: a missing or malformed key throws at bootstrap so services never
|
|
8
|
+
* start half-configured. Key material is never echoed in error messages.
|
|
9
|
+
*/
|
|
10
|
+
export class EncryptionConfig {
|
|
11
|
+
constructor(
|
|
12
|
+
/** Decoded 96-byte master key used as the `local` KMS provider key. */
|
|
13
|
+
masterKey,
|
|
14
|
+
/** `db.collection` namespace of the key vault. */
|
|
15
|
+
keyVaultNamespace,
|
|
16
|
+
/** keyAltName used to resolve/provision the single shared DEK. */
|
|
17
|
+
keyAltName) {
|
|
18
|
+
this.masterKey = masterKey;
|
|
19
|
+
this.keyVaultNamespace = keyVaultNamespace;
|
|
20
|
+
this.keyAltName = keyAltName;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Builds a validated configuration from an environment map.
|
|
24
|
+
*
|
|
25
|
+
* @param env - Environment map, typically `process.env`.
|
|
26
|
+
* @returns A frozen, validated {@link EncryptionConfig}.
|
|
27
|
+
* @throws Error when the env var is missing, not base64, or not 96 bytes.
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const config = EncryptionConfig.load(process.env);
|
|
31
|
+
* const service = new EncryptionService(config);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
static load(env) {
|
|
35
|
+
const raw = env[EncryptionConfig.MASTER_KEY_ENV_VAR];
|
|
36
|
+
if (!raw) {
|
|
37
|
+
throw new Error(`${EncryptionConfig.MASTER_KEY_ENV_VAR} is not set. ` +
|
|
38
|
+
'Provide a base64-encoded 96-byte master key.');
|
|
39
|
+
}
|
|
40
|
+
const masterKey = EncryptionConfig.decodeMasterKey(raw);
|
|
41
|
+
return new EncryptionConfig(masterKey, EncryptionConfig.KEY_VAULT_NAMESPACE, EncryptionConfig.KEY_ALT_NAME);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Decodes and validates the base64 master key without ever including the
|
|
45
|
+
* supplied value in error messages.
|
|
46
|
+
*
|
|
47
|
+
* @param raw - Raw base64 string from the environment.
|
|
48
|
+
* @returns The decoded 96-byte key.
|
|
49
|
+
* @throws Error when the value is not strict base64 or has a wrong length.
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // internal use only — called by EncryptionConfig.load()
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
static decodeMasterKey(raw) {
|
|
56
|
+
const decoded = Buffer.from(raw, 'base64');
|
|
57
|
+
if (decoded.length === 0 || decoded.toString('base64') !== raw.replace(/\s/g, '')) {
|
|
58
|
+
throw new Error(`${EncryptionConfig.MASTER_KEY_ENV_VAR} is not valid base64. ` +
|
|
59
|
+
'(value withheld from this message)');
|
|
60
|
+
}
|
|
61
|
+
if (decoded.length !== EncryptionConfig.MASTER_KEY_BYTES) {
|
|
62
|
+
throw new Error(`${EncryptionConfig.MASTER_KEY_ENV_VAR} must decode to exactly ` +
|
|
63
|
+
`${EncryptionConfig.MASTER_KEY_BYTES} bytes, got ${decoded.length}. ` +
|
|
64
|
+
'(value withheld from this message)');
|
|
65
|
+
}
|
|
66
|
+
return decoded;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Fixed key vault namespace shared by every Gatehouse service. */
|
|
70
|
+
EncryptionConfig.KEY_VAULT_NAMESPACE = 'encryption.__keyVault';
|
|
71
|
+
/** Alt name of the single shared data encryption key (DEK). */
|
|
72
|
+
EncryptionConfig.KEY_ALT_NAME = 'gatehouse-dek';
|
|
73
|
+
/** Name of the environment variable carrying the master key. */
|
|
74
|
+
EncryptionConfig.MASTER_KEY_ENV_VAR = 'GH_ENCRYPTION_MASTER_KEY';
|
|
75
|
+
/** Required master key length in bytes for the `local` KMS provider. */
|
|
76
|
+
EncryptionConfig.MASTER_KEY_BYTES = 96;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { MongoClient } from 'mongodb';
|
|
2
|
+
import { EncryptionService } from './encryption.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Process-wide bootstrap for the encryption layer, mirroring the
|
|
5
|
+
* `initializeWorkflowMiddleware` pattern used elsewhere in this package.
|
|
6
|
+
*
|
|
7
|
+
* Consumer services call {@link EncryptionBootstrap.initialize} exactly once
|
|
8
|
+
* at startup (right after connecting to MongoDB); everything else — the
|
|
9
|
+
* Mongoose plugin, repositories, adapters — obtains the shared singleton via
|
|
10
|
+
* {@link EncryptionBootstrap.getService}.
|
|
11
|
+
*/
|
|
12
|
+
export declare class EncryptionBootstrap {
|
|
13
|
+
private static service;
|
|
14
|
+
private constructor();
|
|
15
|
+
/**
|
|
16
|
+
* Initializes the singleton {@link EncryptionService} from the
|
|
17
|
+
* environment and a connected client. Idempotent: repeated calls return
|
|
18
|
+
* the already-initialized instance.
|
|
19
|
+
*
|
|
20
|
+
* @param client - A connected {@link MongoClient}.
|
|
21
|
+
* @param env - Environment map, defaults to `process.env`.
|
|
22
|
+
* @returns The initialized singleton service.
|
|
23
|
+
* @throws Error when `GH_ENCRYPTION_MASTER_KEY` is missing or malformed.
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* await mongoose.connect(uri);
|
|
27
|
+
* await EncryptionBootstrap.initialize(
|
|
28
|
+
* mongoose.connection.getClient() as unknown as MongoClient
|
|
29
|
+
* );
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
static initialize(client: MongoClient, env?: Record<string, string | undefined>): Promise<EncryptionService>;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the initialized singleton service.
|
|
35
|
+
*
|
|
36
|
+
* @returns The shared {@link EncryptionService}.
|
|
37
|
+
* @throws Error when called before {@link initialize}.
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const ciphertext = await EncryptionBootstrap.getService().encrypt(value);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
static getService(): EncryptionService;
|
|
44
|
+
/**
|
|
45
|
+
* Reports whether the encryption layer has been bootstrapped.
|
|
46
|
+
*
|
|
47
|
+
* @returns `true` after a successful {@link initialize} call.
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* if (!EncryptionBootstrap.isInitialized()) {
|
|
51
|
+
* await EncryptionBootstrap.initialize(client);
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
static isInitialized(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Tears down the singleton (used by tests and graceful shutdown).
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* await EncryptionBootstrap.reset();
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
static reset(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=encryption.init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.init.d.ts","sourceRoot":"","sources":["../../../shared/encryption/encryption.init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,MAAM,CAAC,OAAO,CAAkC;IAExD,OAAO;IAEP;;;;;;;;;;;;;;;;OAgBG;WACiB,UAAU,CAC1B,MAAM,EAAE,WAAW,EACnB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACtD,OAAO,CAAC,iBAAiB,CAAC;IAU7B;;;;;;;;;OASG;WACW,UAAU,IAAI,iBAAiB;IAU7C;;;;;;;;;;OAUG;WACW,aAAa,IAAI,OAAO;IAItC;;;;;;;OAOG;WACiB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAM7C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { EncryptionConfig } from './encryption.config.js';
|
|
2
|
+
import { EncryptionService } from './encryption.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Process-wide bootstrap for the encryption layer, mirroring the
|
|
5
|
+
* `initializeWorkflowMiddleware` pattern used elsewhere in this package.
|
|
6
|
+
*
|
|
7
|
+
* Consumer services call {@link EncryptionBootstrap.initialize} exactly once
|
|
8
|
+
* at startup (right after connecting to MongoDB); everything else — the
|
|
9
|
+
* Mongoose plugin, repositories, adapters — obtains the shared singleton via
|
|
10
|
+
* {@link EncryptionBootstrap.getService}.
|
|
11
|
+
*/
|
|
12
|
+
export class EncryptionBootstrap {
|
|
13
|
+
constructor() { }
|
|
14
|
+
/**
|
|
15
|
+
* Initializes the singleton {@link EncryptionService} from the
|
|
16
|
+
* environment and a connected client. Idempotent: repeated calls return
|
|
17
|
+
* the already-initialized instance.
|
|
18
|
+
*
|
|
19
|
+
* @param client - A connected {@link MongoClient}.
|
|
20
|
+
* @param env - Environment map, defaults to `process.env`.
|
|
21
|
+
* @returns The initialized singleton service.
|
|
22
|
+
* @throws Error when `GH_ENCRYPTION_MASTER_KEY` is missing or malformed.
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* await mongoose.connect(uri);
|
|
26
|
+
* await EncryptionBootstrap.initialize(
|
|
27
|
+
* mongoose.connection.getClient() as unknown as MongoClient
|
|
28
|
+
* );
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
static async initialize(client, env = process.env) {
|
|
32
|
+
if (EncryptionBootstrap.service) {
|
|
33
|
+
return EncryptionBootstrap.service;
|
|
34
|
+
}
|
|
35
|
+
const service = new EncryptionService(EncryptionConfig.load(env));
|
|
36
|
+
await service.init(client);
|
|
37
|
+
EncryptionBootstrap.service = service;
|
|
38
|
+
return service;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns the initialized singleton service.
|
|
42
|
+
*
|
|
43
|
+
* @returns The shared {@link EncryptionService}.
|
|
44
|
+
* @throws Error when called before {@link initialize}.
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const ciphertext = await EncryptionBootstrap.getService().encrypt(value);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
static getService() {
|
|
51
|
+
if (!EncryptionBootstrap.service) {
|
|
52
|
+
throw new Error('Encryption is not initialized. Call EncryptionBootstrap.initialize(client) ' +
|
|
53
|
+
'(initializeEncryption) at service bootstrap first.');
|
|
54
|
+
}
|
|
55
|
+
return EncryptionBootstrap.service;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Reports whether the encryption layer has been bootstrapped.
|
|
59
|
+
*
|
|
60
|
+
* @returns `true` after a successful {@link initialize} call.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* if (!EncryptionBootstrap.isInitialized()) {
|
|
64
|
+
* await EncryptionBootstrap.initialize(client);
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
static isInitialized() {
|
|
69
|
+
return EncryptionBootstrap.service !== null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Tears down the singleton (used by tests and graceful shutdown).
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* await EncryptionBootstrap.reset();
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
static async reset() {
|
|
80
|
+
if (EncryptionBootstrap.service) {
|
|
81
|
+
await EncryptionBootstrap.service.close();
|
|
82
|
+
EncryptionBootstrap.service = null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
EncryptionBootstrap.service = null;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/// <reference path="../../value-objects/pound.d.ts" />
|
|
2
|
+
/// <reference path="../../value-objects/account-number.d.ts" />
|
|
3
|
+
/// <reference path="encrypted-field-map.d.ts" />
|
|
4
|
+
/// <reference path="../../value-objects/sort-code.d.ts" />
|
|
5
|
+
/// <reference types="mongoose/types/aggregate.js" />
|
|
6
|
+
/// <reference types="mongoose/types/callback.js" />
|
|
7
|
+
/// <reference types="mongoose/types/collection.js" />
|
|
8
|
+
/// <reference types="mongoose/types/connection.js" />
|
|
9
|
+
/// <reference types="mongoose/types/cursor.js" />
|
|
10
|
+
/// <reference types="mongoose/types/document.js" />
|
|
11
|
+
/// <reference types="mongoose/types/error.js" />
|
|
12
|
+
/// <reference types="mongoose/types/expressions.js" />
|
|
13
|
+
/// <reference types="mongoose/types/helpers.js" />
|
|
14
|
+
/// <reference types="mongoose/types/middlewares.js" />
|
|
15
|
+
/// <reference types="mongoose/types/indexes.js" />
|
|
16
|
+
/// <reference types="mongoose/types/models.js" />
|
|
17
|
+
/// <reference types="mongoose/types/mongooseoptions.js" />
|
|
18
|
+
/// <reference types="mongoose/types/pipelinestage.js" />
|
|
19
|
+
/// <reference types="mongoose/types/populate.js" />
|
|
20
|
+
/// <reference types="mongoose/types/query.js" />
|
|
21
|
+
/// <reference types="mongoose/types/schemaoptions.js" />
|
|
22
|
+
/// <reference types="mongoose/types/session.js" />
|
|
23
|
+
/// <reference types="mongoose/types/types.js" />
|
|
24
|
+
/// <reference types="mongoose/types/utility.js" />
|
|
25
|
+
/// <reference types="mongoose/types/validation.js" />
|
|
26
|
+
/// <reference types="mongoose/types/virtuals.js" />
|
|
27
|
+
/// <reference types="mongoose/types/schematypes.js" />
|
|
28
|
+
/// <reference types="mongoose/types/inferschematype.js" />
|
|
29
|
+
/// <reference types="mongoose/types/inferrawdoctype.js" />
|
|
30
|
+
import { Schema } from 'mongoose';
|
|
31
|
+
/**
|
|
32
|
+
* Global Mongoose plugin routing `ghEncrypt: true` fields through the
|
|
33
|
+
* {@link EncryptionService} — plumbing only, no crypto in hooks.
|
|
34
|
+
*
|
|
35
|
+
* Write hooks (`save`, `insertMany`, update/replace queries) encrypt
|
|
36
|
+
* annotated values to BSON Binary subtype 6; read hooks (`find`, `findOne`,
|
|
37
|
+
* `findOneAnd*`, `distinct`) decrypt hydrated docs and `.lean()` results.
|
|
38
|
+
* Filters and sorts on encrypted paths fail loud via
|
|
39
|
+
* {@link EncryptionFilterGuard}. When {@link EncryptionBootstrap} is not
|
|
40
|
+
* initialized, every hook is a transparent pass-through so consumers that
|
|
41
|
+
* have not opted in keep working on plaintext.
|
|
42
|
+
*
|
|
43
|
+
* Annotated paths are re-typed to `Mixed` (original type stashed in
|
|
44
|
+
* `ghOriginalType`) so ciphertext survives Mongoose casting. Aggregation is
|
|
45
|
+
* not interceptable and is handled per call site (Enc-5).
|
|
46
|
+
*/
|
|
47
|
+
export declare class EncryptionPlugin {
|
|
48
|
+
private constructor();
|
|
49
|
+
/**
|
|
50
|
+
* Applies the plugin to a schema: validates and collects annotated
|
|
51
|
+
* paths, re-types them to `Mixed`, and registers guard/write/read hooks.
|
|
52
|
+
* No-op for schemas without annotations; safe to call more than once
|
|
53
|
+
* (encrypt/decrypt transforms are idempotent).
|
|
54
|
+
*
|
|
55
|
+
* @param schema - The Mongoose schema to instrument.
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const applicantSchema = new mongoose.Schema({
|
|
59
|
+
* firstName: { type: String, ghEncrypt: true }
|
|
60
|
+
* });
|
|
61
|
+
* EncryptionPlugin.apply(applicantSchema);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
static apply(schema: Schema): void;
|
|
65
|
+
/**
|
|
66
|
+
* Re-types one annotated path to `Mixed` so Binary ciphertext is not
|
|
67
|
+
* mangled by the original String/Number cast, stashing the original
|
|
68
|
+
* BSON type in `ghOriginalType` for the field-map/tooling.
|
|
69
|
+
*
|
|
70
|
+
* @param schema - The owning schema.
|
|
71
|
+
* @param entry - The annotated path being re-typed.
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* // internal use only — called by apply()
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
private static retypeToMixed;
|
|
78
|
+
/**
|
|
79
|
+
* Registers fail-loud filter/sort guards on every query hook.
|
|
80
|
+
*
|
|
81
|
+
* @param schema - The owning schema.
|
|
82
|
+
* @param paths - Encrypted dot paths of the schema.
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* // internal use only — called by apply()
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
private static registerGuardHooks;
|
|
89
|
+
/**
|
|
90
|
+
* Registers encrypt-on-write hooks: `save`, `insertMany` and the
|
|
91
|
+
* update/replace query family (`$set`, `$setOnInsert`, dot paths,
|
|
92
|
+
* parent-object values and full replacement docs).
|
|
93
|
+
*
|
|
94
|
+
* @param schema - The owning schema.
|
|
95
|
+
* @param paths - Encrypted dot paths of the schema.
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* // internal use only — called by apply()
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
private static registerWriteHooks;
|
|
102
|
+
/**
|
|
103
|
+
* Registers decrypt-on-read hooks: `find`, the `findOne*` family,
|
|
104
|
+
* `distinct`, plus post-`save`/`insertMany` restores so callers keep
|
|
105
|
+
* seeing plaintext on the documents they just persisted.
|
|
106
|
+
*
|
|
107
|
+
* @param schema - The owning schema.
|
|
108
|
+
* @param paths - Encrypted dot paths of the schema.
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* // internal use only — called by apply()
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
private static registerReadHooks;
|
|
115
|
+
/**
|
|
116
|
+
* Encrypts annotated values inside an update object: exact dot-path
|
|
117
|
+
* keys, parent-object values containing encrypted leaves, and full
|
|
118
|
+
* replacement documents (updates without atomic operators).
|
|
119
|
+
*
|
|
120
|
+
* @param update - The mutable update object from `Query.getUpdate()`.
|
|
121
|
+
* @param paths - Encrypted dot paths of the schema.
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* // internal use only — called by the update-query pre hook
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
private static encryptUpdate;
|
|
128
|
+
/**
|
|
129
|
+
* Applies a value transform to every encrypted path of one target,
|
|
130
|
+
* dispatching between hydrated documents (getter-free `get`/`set`) and
|
|
131
|
+
* plain objects (`.lean()` results, insert payloads).
|
|
132
|
+
*
|
|
133
|
+
* @param target - Hydrated document or plain object; non-objects no-op.
|
|
134
|
+
* @param paths - Encrypted dot paths of the schema.
|
|
135
|
+
* @param transform - Value transform (encrypt or decrypt).
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* // internal use only
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
private static transformTarget;
|
|
142
|
+
/**
|
|
143
|
+
* Applies a transform to every encrypted path of one hydrated document.
|
|
144
|
+
*
|
|
145
|
+
* @param doc - The hydrated Mongoose document.
|
|
146
|
+
* @param paths - Encrypted dot paths of the schema.
|
|
147
|
+
* @param transform - Value transform (encrypt or decrypt).
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* // internal use only
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
private static transformDocument;
|
|
154
|
+
/**
|
|
155
|
+
* Transforms one dot path on a hydrated document, reading with getters
|
|
156
|
+
* disabled so value-object formatters never leak into ciphertext.
|
|
157
|
+
*
|
|
158
|
+
* @param doc - The hydrated Mongoose document.
|
|
159
|
+
* @param path - Encrypted dot path.
|
|
160
|
+
* @param transform - Value transform (encrypt or decrypt).
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* // internal use only
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
private static transformDocPath;
|
|
167
|
+
/**
|
|
168
|
+
* Transforms one segmented path on a plain object, descending nested
|
|
169
|
+
* objects and fanning out over arrays.
|
|
170
|
+
*
|
|
171
|
+
* @param target - Plain object (or array element) being walked.
|
|
172
|
+
* @param segments - Remaining path segments.
|
|
173
|
+
* @param transform - Value transform (encrypt or decrypt).
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* // internal use only
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
private static transformPlain;
|
|
180
|
+
/**
|
|
181
|
+
* Builds the encrypt transform: plaintext → Binary; ciphertext and the
|
|
182
|
+
* uninitialized-bootstrap case pass through untouched.
|
|
183
|
+
*
|
|
184
|
+
* @returns Async value transform used by all write hooks.
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* // internal use only
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
private static encryptTransform;
|
|
191
|
+
/**
|
|
192
|
+
* Builds the decrypt transform: Binary → plaintext; non-ciphertext and
|
|
193
|
+
* the uninitialized-bootstrap case pass through untouched.
|
|
194
|
+
*
|
|
195
|
+
* @returns Async value transform used by all read hooks.
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* // internal use only
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
private static decryptTransform;
|
|
202
|
+
/**
|
|
203
|
+
* Returns the bootstrapped service, or `null` when encryption is not
|
|
204
|
+
* initialized (pass-through mode for non-opted-in consumers).
|
|
205
|
+
*
|
|
206
|
+
* @returns The active {@link EncryptionService} or `null`.
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* // internal use only
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
private static activeService;
|
|
213
|
+
/**
|
|
214
|
+
* Duck-type check for BSON Binary subtype 6 (encrypted) values.
|
|
215
|
+
*
|
|
216
|
+
* @param value - Candidate value.
|
|
217
|
+
* @returns `true` when the value is ciphertext.
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* // internal use only
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
private static isCiphertext;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=encryption.plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.plugin.d.ts","sourceRoot":"","sources":["../../../shared/encryption/encryption.plugin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAmB,MAAM,UAAU,CAAC;AAuBnD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;IACzB,OAAO;IAEP;;;;;;;;;;;;;;OAcG;WACW,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAczC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAc5B;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAiBjC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgChC;;;;;;;;;;;OAWG;mBACkB,aAAa;IA0BlC;;;;;;;;;;;;OAYG;mBACkB,eAAe;IAiBpC;;;;;;;;;;OAUG;mBACkB,iBAAiB;IAQtC;;;;;;;;;;;OAWG;mBACkB,gBAAgB;IAarC;;;;;;;;;;;OAWG;mBACkB,cAAc;IAuBnC;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAI5B;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;CAO9B"}
|