@dynamatix/gb-schemas 0.21.12 → 0.21.14
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/applicants/applicant-employment.model.js +3 -3
- package/applicants/applicant-income.model.js +3 -3
- package/applicants/applicant.model.js +4 -4
- package/applications/application-audit.model.js +1 -1
- package/applications/application-checklist-Item.model.js +11 -11
- package/applications/application-document.model.js +1 -1
- package/applications/application-note.model.js +2 -2
- package/applications/application-offer.model.js +1 -1
- package/applications/application-onboarding.model.js +1 -1
- package/applications/application.model.js +3 -3
- package/applications/document.model.js +1 -1
- package/applications/productfeatures.model.js +6 -6
- package/package.json +1 -1
- package/product-catalogues/product-catalogue.model.js +3 -3
- package/shared/apprivo-sync-journey.model.js +1 -2
- package/shared/error-log.model.js +2 -2
- package/users/user.model.js +3 -3
- package/utils/encryption.js +35 -37
- package/utils/encryption.middleware.js +47 -105
|
@@ -18,7 +18,7 @@ const applicantEmploymentSchema = new mongoose.Schema({
|
|
|
18
18
|
|
|
19
19
|
classLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
20
20
|
contractRemaining: { type: String },
|
|
21
|
-
dateJoined: { type:
|
|
21
|
+
dateJoined: { type: String },
|
|
22
22
|
disabilityLiving: { type: String },
|
|
23
23
|
employerName: { type: String },
|
|
24
24
|
employerTelephone: { type: String },
|
|
@@ -37,8 +37,8 @@ const applicantEmploymentSchema = new mongoose.Schema({
|
|
|
37
37
|
previousAddressLine3: { type: String },
|
|
38
38
|
previousAddressPostCode: { type: String },
|
|
39
39
|
previousBasicGrossIncome: { type: String },
|
|
40
|
-
previousDateJoined: { type:
|
|
41
|
-
previousDateLeft: { type:
|
|
40
|
+
previousDateJoined: { type: String },
|
|
41
|
+
previousDateLeft: { type: String },
|
|
42
42
|
previousEmployerName: { type: String },
|
|
43
43
|
previousEmployerTelephone: { type: String },
|
|
44
44
|
previousJobTitle: { type: String },
|
|
@@ -20,8 +20,8 @@ const incomeSchema = new mongoose.Schema({
|
|
|
20
20
|
businessType: { type: String, default: '4' },
|
|
21
21
|
charteredCertifiedOrOther: { type: String, default: '' },
|
|
22
22
|
contactName: { type: String, default: '' },
|
|
23
|
-
currentYearEnd: { type:
|
|
24
|
-
dateEstablished: { type:
|
|
23
|
+
currentYearEnd: { type: String, default: null },
|
|
24
|
+
dateEstablished: { type: String, default: null },
|
|
25
25
|
doYouHaveAccountant: { type: String, default: false },
|
|
26
26
|
isBusinessAddressDifferent: { type: String, default: false },
|
|
27
27
|
nameOfBusiness: { type: String, default: '' },
|
|
@@ -38,7 +38,7 @@ const incomeSchema = new mongoose.Schema({
|
|
|
38
38
|
registeredCountry: { type: String, default: 'GBR' },
|
|
39
39
|
registeredPostCode: { type: String, default: '' },
|
|
40
40
|
registeredTelephone: { type: String, default: '' },
|
|
41
|
-
selfEmployedDate: { type:
|
|
41
|
+
selfEmployedDate: { type: String, default: null },
|
|
42
42
|
turnover1: { type: String, default: 0.0 },
|
|
43
43
|
turnover2: { type: String, default: 0.0 },
|
|
44
44
|
turnover3: { type: String, default: 0.0 },
|
|
@@ -18,7 +18,7 @@ const applicantSchema = new mongoose.Schema({
|
|
|
18
18
|
addressLine1: { type: String, default: null },
|
|
19
19
|
addressLine2: { type: String, default: null },
|
|
20
20
|
addressLine3: { type: String, default: null },
|
|
21
|
-
addressMovedDate: { type:
|
|
21
|
+
addressMovedDate: { type: String, default: null },
|
|
22
22
|
addressPostCode: { type: String, default: null },
|
|
23
23
|
correspondenceAddressCity: { type: String, default: null },
|
|
24
24
|
correspondenceAddressCountry: { type: String, default: null },
|
|
@@ -27,7 +27,7 @@ const applicantSchema = new mongoose.Schema({
|
|
|
27
27
|
correspondenceAddressLine3: { type: String, default: null },
|
|
28
28
|
correspondenceAddressPostCode: { type: String, default: null },
|
|
29
29
|
countryOfResidenceLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
30
|
-
dateOfBirth: { type:
|
|
30
|
+
dateOfBirth: { type: String, default: null },
|
|
31
31
|
dependant10Age: { type: String, default: 0 },
|
|
32
32
|
dependant1Age: { type: String, default: 0 },
|
|
33
33
|
dependant2Age: { type: String, default: 0 },
|
|
@@ -74,7 +74,7 @@ const applicantSchema = new mongoose.Schema({
|
|
|
74
74
|
previous1AddressLine1: { type: String, default: null },
|
|
75
75
|
previous1AddressLine2: { type: String, default: null },
|
|
76
76
|
previous1AddressLine3: { type: String, default: null },
|
|
77
|
-
previous1AddressMovedDate: { type:
|
|
77
|
+
previous1AddressMovedDate: { type: String, default: null },
|
|
78
78
|
previous1AddressPostCode: { type: String, default: null },
|
|
79
79
|
previous1AddressPropertyOwnedBy: { type: String, default: null },
|
|
80
80
|
previous2AddressCity: { type: String, default: null },
|
|
@@ -82,7 +82,7 @@ const applicantSchema = new mongoose.Schema({
|
|
|
82
82
|
previous2AddressLine1: { type: String, default: null },
|
|
83
83
|
previous2AddressLine2: { type: String, default: null },
|
|
84
84
|
previous2AddressLine3: { type: String, default: null },
|
|
85
|
-
previous2AddressMovedDate: { type:
|
|
85
|
+
previous2AddressMovedDate: { type: String, default: null },
|
|
86
86
|
previous2AddressPostCode: { type: String, default: null },
|
|
87
87
|
previous2AddressPropertyOwnedBy: { type: String, default: null },
|
|
88
88
|
relationshipToOthersLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", default: null },
|
|
@@ -4,19 +4,19 @@ import mongooseEncryption from "../utils/encryption.middleware.js";
|
|
|
4
4
|
const checkListItemSchema = new mongoose.Schema({
|
|
5
5
|
additionalOfferConditions: { type: String, default: "" },
|
|
6
6
|
appFormSignedNotes: { type: String, default: "" },
|
|
7
|
-
applicationCompletionDate: { type:
|
|
7
|
+
applicationCompletionDate: { type: String },
|
|
8
8
|
buildingInsuranceInsurerName: { type: String, default: "" },
|
|
9
9
|
buildingInsurancePolicyNumber: { type: String, default: "" },
|
|
10
10
|
buildingInsuranceReceived: { type: String, default: "" },
|
|
11
|
-
buildingInsuranceRenewalDate: { type:
|
|
12
|
-
dateOfValuationReceived: { type:
|
|
11
|
+
buildingInsuranceRenewalDate: { type: String },
|
|
12
|
+
dateOfValuationReceived: { type: String },
|
|
13
13
|
feePaidDocumentsDownloaded: { type: String, default: "" },
|
|
14
14
|
feePaidNotes: { type: String, default: "" },
|
|
15
15
|
fundsNotes: { type: String, default: "" },
|
|
16
|
-
fundsReleasedDate: { type:
|
|
16
|
+
fundsReleasedDate: { type: String },
|
|
17
17
|
hasAllDocsReviewedAndAccepted: { type: String, default: "" },
|
|
18
18
|
idnPorReceived: { type: String, default: "" },
|
|
19
|
-
legalCompletionDate: { type:
|
|
19
|
+
legalCompletionDate: { type: String },
|
|
20
20
|
legalDocsReceived: { type: String, default: "" },
|
|
21
21
|
legalNotes: { type: String, default: "" },
|
|
22
22
|
ninetyDaysValuationAmount: { type: String, default: "" },
|
|
@@ -26,21 +26,21 @@ const checkListItemSchema = new mongoose.Schema({
|
|
|
26
26
|
offerOfferPrepared: { type: String, default: "" },
|
|
27
27
|
offerOfferReviewed: { type: String, default: "" },
|
|
28
28
|
offerSignedNotes: { type: String, default: "" },
|
|
29
|
-
offerSolicitorInstructedDate: { type:
|
|
29
|
+
offerSolicitorInstructedDate: { type: String },
|
|
30
30
|
packagingNotes: { type: String, default: "" },
|
|
31
31
|
preOfferNotes: { type: String, default: "" },
|
|
32
32
|
reinstatementAmount: { type: String, default: "" },
|
|
33
33
|
rotReceived: { type: String, default: "" },
|
|
34
|
-
rotReceivedDate: { type:
|
|
34
|
+
rotReceivedDate: { type: String },
|
|
35
35
|
salesContractReceived: { type: String, default: "" },
|
|
36
36
|
underwritingNotes: { type: String, default: "" },
|
|
37
37
|
underwritingValuationNotes: { type: String, default: "" },
|
|
38
|
-
valuationAccepted: { type:
|
|
38
|
+
valuationAccepted: { type: String },
|
|
39
39
|
valuationFurtherConditions: { type: String, default: "" },
|
|
40
40
|
valuationNotes: { type: String, default: "" },
|
|
41
|
-
valuationReceived: { type:
|
|
42
|
-
valuationRequestedDate: { type:
|
|
43
|
-
valuationScheduledDate: { type:
|
|
41
|
+
valuationReceived: { type: String },
|
|
42
|
+
valuationRequestedDate: { type: String },
|
|
43
|
+
valuationScheduledDate: { type: String },
|
|
44
44
|
valuationSurveyorDetails: { type: String, default: "" }
|
|
45
45
|
});
|
|
46
46
|
|
|
@@ -17,7 +17,7 @@ const documentSchema = new mongoose.Schema({
|
|
|
17
17
|
documentTypeId: { type: String, required: false },
|
|
18
18
|
fileName: { type: String, required: false },
|
|
19
19
|
contentType: { type: String, required: false },
|
|
20
|
-
created: { type:
|
|
20
|
+
created: { type: String, required: false },
|
|
21
21
|
createdBy: { type: String, required: false },
|
|
22
22
|
isGenerated: { type: String, required: false },
|
|
23
23
|
data: { type: String, required: false },
|
|
@@ -8,7 +8,7 @@ const noteSchema = new mongoose.Schema({
|
|
|
8
8
|
default: null
|
|
9
9
|
},
|
|
10
10
|
createdOn: {
|
|
11
|
-
type:
|
|
11
|
+
type: String,
|
|
12
12
|
default: null
|
|
13
13
|
},
|
|
14
14
|
createdBy: {
|
|
@@ -29,7 +29,7 @@ const noteSchema = new mongoose.Schema({
|
|
|
29
29
|
required: true
|
|
30
30
|
},
|
|
31
31
|
reminderDate: {
|
|
32
|
-
type:
|
|
32
|
+
type: String,
|
|
33
33
|
default: null
|
|
34
34
|
},
|
|
35
35
|
attachmentDocumentId: {
|
|
@@ -2,7 +2,7 @@ import mongoose from "mongoose";
|
|
|
2
2
|
import mongooseEncryption from "../utils/encryption.middleware.js";
|
|
3
3
|
|
|
4
4
|
const offerSchema = new mongoose.Schema({
|
|
5
|
-
date: { type:
|
|
5
|
+
date: { type: String } // The date associated with the offer
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
|
|
@@ -4,7 +4,7 @@ import mongooseEncryption from "../utils/encryption.middleware.js";
|
|
|
4
4
|
const onboardingSchema = new mongoose.Schema({
|
|
5
5
|
errors: { type: String, default: "" },
|
|
6
6
|
status: { type: String, default: "" },
|
|
7
|
-
statusDate: { type:
|
|
7
|
+
statusDate: { type: String },
|
|
8
8
|
warnings: { type: String, default: "" }
|
|
9
9
|
});
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ const applicationSchema = new mongoose.Schema(
|
|
|
27
27
|
isBrokerAssigned: { type: String, default: false },
|
|
28
28
|
isFinanceRecommendedToApplicant: { type: String, required: true },
|
|
29
29
|
isWorkflowTaskCreated: { type: String, required: true },
|
|
30
|
-
lastUpdated: { type:
|
|
30
|
+
lastUpdated: { type: String },
|
|
31
31
|
lendingTypeLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", required: true },
|
|
32
32
|
networkClubName: { type: String, default: "" },
|
|
33
33
|
isNetworkClubSubmission: { type: String, required: true },
|
|
@@ -44,7 +44,7 @@ const applicationSchema = new mongoose.Schema(
|
|
|
44
44
|
sowSalary: { type: String, default: "" },
|
|
45
45
|
statusLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", required: true },
|
|
46
46
|
submitReason: { type: String, default: "" },
|
|
47
|
-
submittedDate: { type:
|
|
47
|
+
submittedDate: { type: String },
|
|
48
48
|
underwriter: { type: String, default: "" },
|
|
49
49
|
isValuationFeePaid: { type: String, required: true },
|
|
50
50
|
withdrawalReason: { type: String, default: "" },
|
|
@@ -57,7 +57,7 @@ const applicationSchema = new mongoose.Schema(
|
|
|
57
57
|
{ type: mongoose.Schema.Types.ObjectId, ref: "Applicant" }
|
|
58
58
|
],
|
|
59
59
|
statusLid: { type: mongoose.Schema.Types.ObjectId, ref: "Lookup", required: true },
|
|
60
|
-
submittedDate: { type:
|
|
60
|
+
submittedDate: { type: String },
|
|
61
61
|
isValuationFeePaid: { type: String, required: true },
|
|
62
62
|
isActive: { type: String, default: false },
|
|
63
63
|
isUkResident: { type: String, default: true },
|
|
@@ -17,7 +17,7 @@ const documentSchema = new mongoose.Schema({
|
|
|
17
17
|
documentTypeId: { type: mongoose.Schema.Types.ObjectId, ref: "DocumentType", required: false },
|
|
18
18
|
fileName: { type: String, required: false },
|
|
19
19
|
contentType: { type: String, required: false },
|
|
20
|
-
created: { type:
|
|
20
|
+
created: { type: String, required: false },
|
|
21
21
|
createdBy: { type: String, required: false },
|
|
22
22
|
isGenerated: { type: String, required: false },
|
|
23
23
|
data: { type: String, required: false },
|
|
@@ -49,7 +49,7 @@ const productFeaturesSchema = new mongoose.Schema({
|
|
|
49
49
|
totalReversionRate: { type: String, default: null },
|
|
50
50
|
initialRate: { type: String, required: true },
|
|
51
51
|
fixedTerm: { type: String, required: true },
|
|
52
|
-
fixedTermEndDate: { type:
|
|
52
|
+
fixedTermEndDate: { type: String, default: null },
|
|
53
53
|
baseRate: { type: String, default: null },
|
|
54
54
|
productRate: { type: String, default: null },
|
|
55
55
|
apr: { type: String, default: null },
|
|
@@ -72,11 +72,11 @@ const productFeaturesSchema = new mongoose.Schema({
|
|
|
72
72
|
ercCode: { type: String, default: '' },
|
|
73
73
|
variableTerm: { type: String, default: null },
|
|
74
74
|
totalFeePayable: { type: String, default: null },
|
|
75
|
-
dipIssueDate: { type:
|
|
76
|
-
estimatedCompletionDate: { type:
|
|
77
|
-
dipExpiryDate: { type:
|
|
78
|
-
fixedRepaymentUntillDate: { type:
|
|
79
|
-
rentalReviewDate: { type:
|
|
75
|
+
dipIssueDate: { type: String, default: null },
|
|
76
|
+
estimatedCompletionDate: { type: String, default: null },
|
|
77
|
+
dipExpiryDate: { type: String, default: null },
|
|
78
|
+
fixedRepaymentUntillDate: { type: String, default: null },
|
|
79
|
+
rentalReviewDate: { type: String, default: null },
|
|
80
80
|
totalReimbursementWithFee: { type: String, default: null },
|
|
81
81
|
finalRentPayment: { type: String, default: null },
|
|
82
82
|
clientDeposit: { type: String, default: null },
|
package/package.json
CHANGED
|
@@ -5,9 +5,9 @@ const productCatalogueSchema = new mongoose.Schema({
|
|
|
5
5
|
productCatalogueId: { type: String, required: true },
|
|
6
6
|
name: { type: String, required: true },
|
|
7
7
|
description: { type: String },
|
|
8
|
-
applyFrom: { type:
|
|
9
|
-
applyUntil: { type:
|
|
10
|
-
submitUntil: { type:
|
|
8
|
+
applyFrom: { type: String, required: true },
|
|
9
|
+
applyUntil: { type: String, required: true },
|
|
10
|
+
submitUntil: { type: String, required: true },
|
|
11
11
|
status: { type: String, required: true },
|
|
12
12
|
lockedForEdit: { type: String, required: true },
|
|
13
13
|
baseRateName: { type: String },
|
|
@@ -12,8 +12,7 @@ const ApprivoSyncJourneySchema = new mongoose.Schema({
|
|
|
12
12
|
isFirstPull: { type: String, required: true },
|
|
13
13
|
jobRunId: { type: mongoose.Schema.Types.ObjectId, ref: "Job_Run"},
|
|
14
14
|
startTime: {type: Date, default: null},
|
|
15
|
-
endTime: {type: Date, default: null},
|
|
16
|
-
timestamp: { type: Date, default: Date.now }
|
|
15
|
+
endTime: { type: Date, default: null},
|
|
17
16
|
}, {timestamps: true});
|
|
18
17
|
|
|
19
18
|
const ApprivoSyncJourneyModel = mongoose.model('ApprivoSyncJourney', ApprivoSyncJourneySchema);
|
|
@@ -4,10 +4,10 @@ const errorSchema = new mongoose.Schema({
|
|
|
4
4
|
error_message: { type: String, required: true },
|
|
5
5
|
status_code: { type: Number, required: true },
|
|
6
6
|
route: { type: String, required: true },
|
|
7
|
-
timestamp: { type: Date, default: Date.now },
|
|
8
7
|
user_agent: { type: String, required: true },
|
|
9
8
|
stack_trace: [{ type: String }]
|
|
10
|
-
}
|
|
9
|
+
},
|
|
10
|
+
{ timestamps: true });
|
|
11
11
|
|
|
12
12
|
const ErrorLogModel = mongoose.model("Error_Log", errorSchema);
|
|
13
13
|
export default ErrorLogModel;
|
package/users/user.model.js
CHANGED
|
@@ -19,11 +19,11 @@ const userSchema = new mongoose.Schema({
|
|
|
19
19
|
}],
|
|
20
20
|
claims: [ClaimSchema],
|
|
21
21
|
externalData: { type: mongoose.Schema.Types.Mixed },
|
|
22
|
-
modifiedOn: { type:
|
|
22
|
+
modifiedOn: { type: String },
|
|
23
23
|
modifiedById: { type: String },
|
|
24
|
-
createdOnInApprivo: { type:
|
|
24
|
+
createdOnInApprivo: { type: String},
|
|
25
25
|
createdById: { type: String },
|
|
26
|
-
deletedOn: { type:
|
|
26
|
+
deletedOn: { type: String },
|
|
27
27
|
deletedById: { type: String },
|
|
28
28
|
token: { type: String }
|
|
29
29
|
}, {
|
package/utils/encryption.js
CHANGED
|
@@ -8,77 +8,75 @@ import { fileURLToPath } from 'url';
|
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = path.dirname(__filename);
|
|
10
10
|
|
|
11
|
-
//
|
|
12
|
-
dotenv.config({
|
|
13
|
-
|
|
11
|
+
// Load environment variables
|
|
12
|
+
dotenv.config({
|
|
13
|
+
path: path.resolve(__dirname, '../../../../.env'),
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Encryption settings
|
|
17
17
|
const SECRET_KEY = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); // 32 bytes for AES-256
|
|
18
18
|
const IV_LENGTH = 16; // AES-GCM IV length
|
|
19
|
-
const EXCLUDED_COLLECTIONS = process.env.EXCLUDED_COLLECTIONS?.split(
|
|
19
|
+
const EXCLUDED_COLLECTIONS = process.env.EXCLUDED_COLLECTIONS?.split(',') || []; // Collections excluded from encryption
|
|
20
|
+
|
|
21
|
+
// Function to check if a value is an ObjectId or array of ObjectIds
|
|
22
|
+
const isObjectIdOrArray = (value) => {
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
return value.every((item) => mongoose.isValidObjectId(item));
|
|
25
|
+
}
|
|
26
|
+
return mongoose.isValidObjectId(value);
|
|
27
|
+
};
|
|
20
28
|
|
|
21
|
-
// Encrypt an object (
|
|
29
|
+
// Encrypt an object (excluding _id and ObjectId references)
|
|
22
30
|
export const encryptObject = (obj, collectionName) => {
|
|
23
|
-
|
|
24
|
-
if (EXCLUDED_COLLECTIONS.includes(collectionName)) {
|
|
31
|
+
if (EXCLUDED_COLLECTIONS.includes(collectionName) || !obj || typeof obj !== 'object') {
|
|
25
32
|
return obj;
|
|
26
33
|
}
|
|
27
34
|
|
|
28
|
-
if (!obj || typeof obj !== "object") return obj;
|
|
29
35
|
let encryptedObj = {};
|
|
30
|
-
|
|
31
36
|
for (const key in obj) {
|
|
32
|
-
if (
|
|
33
|
-
key
|
|
34
|
-
(Array.isArray(obj[key]) && obj[key].every(item => mongoose.isValidObjectId(item))) ||
|
|
35
|
-
mongoose.isValidObjectId(obj[key])
|
|
36
|
-
) {
|
|
37
|
-
encryptedObj[key] = obj[key]; // Don't encrypt ObjectId references
|
|
37
|
+
if (key === '_id' || isObjectIdOrArray(obj[key])) {
|
|
38
|
+
encryptedObj[key] = obj[key]; // Skip _id and ObjectIds
|
|
38
39
|
} else {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
try {
|
|
41
|
+
const iv = crypto.randomBytes(IV_LENGTH);
|
|
42
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', SECRET_KEY, iv);
|
|
43
|
+
let encrypted = cipher.update(JSON.stringify(obj[key]), 'utf8', 'hex');
|
|
44
|
+
encrypted += cipher.final('hex');
|
|
45
|
+
const authTag = cipher.getAuthTag().toString('hex');
|
|
46
|
+
encryptedObj[key] = `${iv.toString('hex')}:${authTag}:${encrypted}`;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(`Encryption error for key ${key}:`, error);
|
|
49
|
+
encryptedObj[key] = obj[key]; // Store original value if encryption fails
|
|
50
|
+
}
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
return encryptedObj;
|
|
52
55
|
};
|
|
53
56
|
|
|
54
|
-
// Decrypt an object (
|
|
57
|
+
// Decrypt an object (excluding _id and ObjectId references)
|
|
55
58
|
export const decryptObject = (obj, collectionName) => {
|
|
56
|
-
|
|
57
|
-
if (EXCLUDED_COLLECTIONS.includes(collectionName)) {
|
|
59
|
+
if (EXCLUDED_COLLECTIONS.includes(collectionName) || !obj || typeof obj !== 'object') {
|
|
58
60
|
return obj;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
if (!obj || typeof obj !== "object") return obj;
|
|
62
63
|
let decryptedObj = {};
|
|
63
|
-
|
|
64
64
|
for (const key in obj) {
|
|
65
|
-
if (key ===
|
|
66
|
-
decryptedObj[key] = obj[key]; //
|
|
65
|
+
if (key === '_id' || isObjectIdOrArray(obj[key])) {
|
|
66
|
+
decryptedObj[key] = obj[key]; // Skip _id and ObjectIds
|
|
67
67
|
} else {
|
|
68
68
|
try {
|
|
69
69
|
const [ivHex, authTagHex, encryptedData] = obj[key].split(':');
|
|
70
70
|
const iv = Buffer.from(ivHex, 'hex');
|
|
71
71
|
const authTag = Buffer.from(authTagHex, 'hex');
|
|
72
|
-
|
|
73
|
-
const decipher = crypto.createDecipheriv("aes-256-gcm", SECRET_KEY, iv);
|
|
72
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', SECRET_KEY, iv);
|
|
74
73
|
decipher.setAuthTag(authTag);
|
|
75
|
-
|
|
76
74
|
let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
|
|
77
75
|
decrypted += decipher.final('utf8');
|
|
78
|
-
|
|
79
76
|
decryptedObj[key] = JSON.parse(decrypted);
|
|
80
77
|
} catch (error) {
|
|
81
|
-
|
|
78
|
+
console.error(`Decryption error for key ${key}:`, error);
|
|
79
|
+
decryptedObj[key] = obj[key]; // Store original value if decryption fails
|
|
82
80
|
}
|
|
83
81
|
}
|
|
84
82
|
}
|
|
@@ -7,7 +7,7 @@ dotenv.config();
|
|
|
7
7
|
const EXCLUDED_COLLECTIONS = process.env.EXCLUDED_COLLECTIONS?.split(",") || [];
|
|
8
8
|
|
|
9
9
|
export default function mongooseEncryption(schema, options) {
|
|
10
|
-
console.log("========MONGOOSE ENCRYPTION IS IN PROGRESS");
|
|
10
|
+
console.log("========MONGOOSE ENCRYPTION IS IN PROGRESS========");
|
|
11
11
|
|
|
12
12
|
const collectionName = options?.collection || schema.options.collection;
|
|
13
13
|
|
|
@@ -16,132 +16,74 @@ export default function mongooseEncryption(schema, options) {
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// Encrypt
|
|
20
|
-
schema.pre(
|
|
21
|
-
|
|
22
|
-
this.
|
|
19
|
+
// ** Encrypt query parameters before execution **
|
|
20
|
+
schema.pre(['find', 'findOne', 'findById'], function (next) {
|
|
21
|
+
const query = this.getQuery();
|
|
22
|
+
this.setQuery(encryptObject(query, collectionName));
|
|
23
23
|
next();
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
//
|
|
27
|
-
schema.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
operation.updateOne.update = encryptObject(operation.updateOne.update, collectionName);
|
|
33
|
-
} else if (operation.updateMany && operation.updateMany.update) {
|
|
34
|
-
operation.updateMany.update = encryptObject(operation.updateMany.update, collectionName);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
next();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// Encrypt before creating a document
|
|
41
|
-
schema.pre("create", function (next) {
|
|
42
|
-
// Encrypt only the fields before saving to the database
|
|
43
|
-
this.set(encryptObject(this.toObject(), collectionName)); // Encrypt the document
|
|
44
|
-
next();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Decrypt after creating a document
|
|
48
|
-
schema.post("create", function (docs) {
|
|
49
|
-
for (let doc of docs) {
|
|
50
|
-
doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt document fields
|
|
26
|
+
// ** Decrypt result after querying **
|
|
27
|
+
schema.post(['find', 'findOne', 'findById'], function (docs) {
|
|
28
|
+
if (Array.isArray(docs)) {
|
|
29
|
+
docs.forEach((doc) => doc && Object.assign(doc, decryptObject(doc.toObject(), collectionName)));
|
|
30
|
+
} else if (docs) {
|
|
31
|
+
Object.assign(docs, decryptObject(docs.toObject(), collectionName));
|
|
51
32
|
}
|
|
52
33
|
});
|
|
53
34
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
result.forEach(doc => doc.set(decryptObject(doc.toObject(), collectionName)));
|
|
59
|
-
} else {
|
|
60
|
-
result.set(encryptObject(result.toObject(), collectionName)); // Decrypt single document
|
|
61
|
-
}
|
|
35
|
+
// ** Encrypt before saving (insert, update) **
|
|
36
|
+
schema.pre(['save', 'create'], function (next) {
|
|
37
|
+
this.set(encryptObject(this.toObject(), collectionName));
|
|
38
|
+
next();
|
|
62
39
|
});
|
|
63
40
|
|
|
64
|
-
//
|
|
65
|
-
schema.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
result.set(decryptObject(result.toObject(), collectionName)); // Decrypt single document
|
|
41
|
+
// ** Encrypt update operations **
|
|
42
|
+
schema.pre(['updateOne', 'findOneAndUpdate'], function (next) {
|
|
43
|
+
const update = this.getUpdate();
|
|
44
|
+
if (update) {
|
|
45
|
+
this.setUpdate(encryptObject(update, collectionName));
|
|
70
46
|
}
|
|
47
|
+
next();
|
|
71
48
|
});
|
|
72
49
|
|
|
73
|
-
// Encrypt
|
|
74
|
-
schema.pre("
|
|
75
|
-
|
|
76
|
-
|
|
50
|
+
// ** Encrypt before bulkWrite operations **
|
|
51
|
+
schema.pre("bulkWrite", function (next) {
|
|
52
|
+
const operations = this.getUpdate();
|
|
53
|
+
if (operations) {
|
|
54
|
+
operations.forEach((operation) => {
|
|
55
|
+
if (operation.insertOne?.document) {
|
|
56
|
+
operation.insertOne.document = encryptObject(operation.insertOne.document, collectionName);
|
|
57
|
+
} else if (operation.updateOne?.update) {
|
|
58
|
+
operation.updateOne.update = encryptObject(operation.updateOne.update, collectionName);
|
|
59
|
+
} else if (operation.updateMany?.update) {
|
|
60
|
+
operation.updateMany.update = encryptObject(operation.updateMany.update, collectionName);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
77
63
|
}
|
|
64
|
+
next();
|
|
78
65
|
});
|
|
79
66
|
|
|
80
|
-
// Decrypt after
|
|
81
|
-
schema.post("
|
|
82
|
-
if (
|
|
83
|
-
|
|
67
|
+
// ** Decrypt after creating a document **
|
|
68
|
+
schema.post("create", function (docs) {
|
|
69
|
+
if (Array.isArray(docs)) {
|
|
70
|
+
docs.forEach((doc) => Object.assign(doc, decryptObject(doc.toObject(), collectionName)));
|
|
71
|
+
} else {
|
|
72
|
+
Object.assign(docs, decryptObject(docs.toObject(), collectionName));
|
|
84
73
|
}
|
|
85
74
|
});
|
|
86
75
|
|
|
87
|
-
|
|
76
|
+
// ** Decrypt after update operations **
|
|
77
|
+
schema.post(["updateOne", "findOneAndUpdate"], function (result) {
|
|
88
78
|
if (result && result.toObject) {
|
|
89
|
-
|
|
79
|
+
Object.assign(result, decryptObject(result.toObject(), collectionName));
|
|
90
80
|
}
|
|
91
81
|
});
|
|
92
82
|
|
|
93
|
-
// Decrypt after
|
|
94
|
-
schema.post("
|
|
95
|
-
console.log("find", docs);
|
|
96
|
-
docs.forEach(doc => {
|
|
97
|
-
doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt document fields
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Decrypt after findById operations
|
|
102
|
-
schema.post("findById", function (doc) {
|
|
103
|
-
console.log("findById", doc);
|
|
104
|
-
if (doc) doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt single document
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Decrypt after findOne operations
|
|
108
|
-
schema.post("findOne", function (doc) {
|
|
109
|
-
console.log("findOne", doc);
|
|
110
|
-
if (doc) doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt single document
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// Decrypt after findOneAndUpdate operations
|
|
115
|
-
schema.post("findOneAndUpdate", function (doc) {
|
|
116
|
-
console.log("findOneAndUpdate", doc);
|
|
83
|
+
// ** Decrypt after findOneAndUpdate, findOneAndDelete, deleteOne, remove **
|
|
84
|
+
schema.post(["findOneAndUpdate", "findOneAndDelete", "deleteOne"], function (doc) {
|
|
117
85
|
if (doc) {
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Decrypt after findOneAndDelete operations
|
|
123
|
-
schema.post("findOneAndDelete", function (doc) {
|
|
124
|
-
console.log("findOneAndDelete", doc);
|
|
125
|
-
if (doc) doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt single document
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// Decrypt after deleteMany operations
|
|
129
|
-
schema.post("deleteMany", function (result) {
|
|
130
|
-
console.log("deleteMany", result);
|
|
131
|
-
if (Array.isArray(result)) {
|
|
132
|
-
result.forEach(doc => doc.set(decryptObject(doc.toObject(), collectionName))); // Decrypt document fields
|
|
86
|
+
Object.assign(doc, decryptObject(doc.toObject(), collectionName));
|
|
133
87
|
}
|
|
134
88
|
});
|
|
135
|
-
|
|
136
|
-
// Decrypt after deleteOne operations
|
|
137
|
-
schema.post("deleteOne", function (doc) {
|
|
138
|
-
console.log("deleteOne", doc);
|
|
139
|
-
if (doc) doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt single document
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Decrypt after remove operations
|
|
143
|
-
schema.post("remove", function (doc) {
|
|
144
|
-
console.log("remove", doc);
|
|
145
|
-
if (doc) doc.set(decryptObject(doc.toObject(), collectionName)); // Decrypt single document
|
|
146
|
-
});
|
|
147
89
|
}
|