Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mongoose-sort-encrypted-field

Package Overview
Dependencies
Maintainers
1
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mongoose-sort-encrypted-field - npm Package Compare versions

Comparing version 0.0.8-a to 0.0.9

11

lib/index.d.ts

@@ -5,2 +5,6 @@ declare const Base2N: any;

add: Function;
options: {
sortFields: {};
decrypters: {};
};
paths: {

@@ -14,3 +18,6 @@ [fieldName: string]: {

};
}, options: any): void;
declare function evaluateMissedSortFields(model: any): Promise<void>;
}, options?: {
noOfDividePartsForSearching?: number;
noOfCharsToIncreaseOnSaturation?: number;
}): void;
declare function evaluateMissedSortFields(model: any): void;

417

lib/index.js

@@ -10,43 +10,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
const Base2N = require('@navpreetdevpuri/base-2-n');
function sortEncryptedFields(schema, options = { noOfDividePartsForSearching: 100, noOfCharsToIncreaseOnSaturation: 2 }) {
const { noOfDividePartsForSearching = 100, noOfCharsToIncreaseOnSaturation = 2, } = options;
const sortFields = {};
const decrypters = {};
for (const [fieldName, field] of Object.entries(schema.paths)) {
if (!field.options.sortFieldName)
continue;
if (!sortFields[fieldName])
sortFields[fieldName] = field.options.sortFieldName;
if (!decrypters[fieldName])
decrypters[fieldName] = field.options.get;
schema.add({
[field.options.sortFieldName]: {
type: String,
default: null,
},
});
}
};
var Base2N = require('@navpreetdevpuri/base-2-n');
function sortEncryptedFields(schema, options) {
var _a;
var _b = options.noOfDividePartsForSearching, noOfDividePartsForSearching = _b === void 0 ? 100 : _b, _c = options.noOfCharsToIncreaseOnSaturation, noOfCharsToIncreaseOnSaturation = _c === void 0 ? 2 : _c;
options.noOfDividePartsForSearching = noOfDividePartsForSearching;
options.noOfCharsToIncreaseOnSaturation = noOfCharsToIncreaseOnSaturation;
var sortFields = {};
var decrypters = {};
schema.options.sortFields = sortFields;
schema.options.decrypters = decrypters;
function documentsBinarySearch(documents, fieldName, value) {
var start = 0;
var end = documents.length - 1;
let start = 0;
let end = documents.length - 1;
while (start <= end) {
var mid = Math.floor((start + end) / 2);
var decryptedMidValue = decrypters[fieldName](documents[mid][fieldName]).toLowerCase();
const mid = Math.floor((start + end) / 2);
const decryptedMidValue = decrypters[fieldName](documents[mid][fieldName]).toLowerCase();
if (value < decryptedMidValue) {

@@ -68,8 +54,8 @@ end = mid - 1;

}
var predecessorNumber;
var successorNumber;
let predecessorNumber;
let successorNumber;
if (predecessorSortId.length == predecessorSortId.length) {
predecessorNumber = new Base2N(predecessorSortId);
successorNumber = new Base2N(successorSortId);
var averageNumber = predecessorNumber.average(successorNumber);
const averageNumber = predecessorNumber.average(successorNumber);
if (averageNumber.toString() != predecessorNumber.toString()) {

@@ -82,202 +68,127 @@ return averageNumber.toString();

}
var bigger = predecessorSortId.length > successorSortId.length
const bigger = predecessorSortId.length > successorSortId.length
? predecessorSortId
: successorSortId;
var smaller = successorSortId.length > predecessorSortId.length
const smaller = successorSortId.length > predecessorSortId.length
? predecessorSortId
: successorSortId;
var biggerNumber = new Base2N(bigger);
var smallerNumber = new Base2N(smaller.padEnd(bigger.length, '\0'));
const biggerNumber = new Base2N(bigger);
const smallerNumber = new Base2N(smaller.padEnd(bigger.length, '\0'));
return biggerNumber.average(smallerNumber).toString();
}
function getMatchForAggregate(documents, fieldName, fieldValue, sortFieldName) {
return __awaiter(this, void 0, void 0, function () {
var index, gteIndex, lteIndex, match;
var _a, _b;
return __generator(this, function (_c) {
index = documentsBinarySearch(documents, fieldName, fieldValue);
gteIndex = index - 1;
lteIndex = index;
match = {
$and: [
(_a = {}, _a[sortFieldName] = { $ne: null }, _a),
(_b = {},
_b[sortFieldName] = {
$gte: gteIndex == -1 ? undefined : documents[gteIndex][sortFieldName],
$lte: lteIndex == documents.length
? undefined
: documents[lteIndex][sortFieldName],
},
_b),
],
};
return [2 /*return*/, match];
});
function getMatchForAggregate(documents, fieldName, fieldValue, sortFieldName, ignoreSortFieldValue) {
return __awaiter(this, void 0, void 0, function* () {
const index = documentsBinarySearch(documents, fieldName, fieldValue);
const gteIndex = index - 1;
const lteIndex = index;
const match = {
$and: [{ [sortFieldName]: { $ne: ignoreSortFieldValue } }],
};
if (gteIndex === -1 && lteIndex === documents.length) {
return match;
}
match.$and.push({ [sortFieldName]: {} });
if (gteIndex !== -1) {
match.$and[1][sortFieldName].$gte = documents[gteIndex][sortFieldName];
}
if (lteIndex !== documents.length) {
match.$and[1][sortFieldName].$lte = documents[lteIndex][sortFieldName];
}
return match;
});
}
function updateSortFieldsForDocument(objectId, model, fieldName, fieldValue, sortFieldName) {
return __awaiter(this, void 0, void 0, function () {
var pipeline, currN, _a, _b, match, documents, index, gteIndex, lteIndex, predecessorSortId, successorSortId, newSortId, documentsCountWithSameSortId, documentsWithSameSortId, _i, documentsWithSameSortId_1, document_1;
var _c, _d, _e, _f, _g, _h, _j, _k;
return __generator(this, function (_l) {
switch (_l.label) {
case 0:
console.time("Total time took to update orderId: ".concat(objectId));
pipeline = [];
_b = (_a = Math).round;
return [4 /*yield*/, model.find({}).count().exec()];
case 1:
currN = _b.apply(_a, [(_l.sent()) / noOfDividePartsForSearching]);
match = { $and: (_c = {}, _c[sortFieldName] = { $ne: null }, _c) };
_l.label = 2;
case 2:
if (!true) return [3 /*break*/, 5];
return [4 /*yield*/, model.aggregate([
{ $match: match },
{
$setWindowFields: {
sortBy: (_d = {}, _d[sortFieldName] = 1, _d),
output: {
index: { $rank: {} },
},
},
},
{
$match: {
$expr: {
$eq: [{ $mod: ['$index', currN] }, 0],
},
},
},
{ $project: (_e = {}, _e[fieldName] = 1, _e[sortFieldName] = 1, _e) },
])];
case 3:
documents = _l.sent();
if (currN < noOfDividePartsForSearching) {
return [3 /*break*/, 5];
}
return [4 /*yield*/, getMatchForAggregate(documents, fieldName, fieldValue, sortFieldName)];
case 4:
match = _l.sent();
currN = Math.round(currN / noOfDividePartsForSearching);
return [3 /*break*/, 2];
case 5:
index = documentsBinarySearch(documents, fieldName, fieldValue);
gteIndex = index - 1;
lteIndex = index;
predecessorSortId = documents[gteIndex][sortFieldName];
successorSortId = documents[lteIndex][sortFieldName];
newSortId = getAverageSortId(predecessorSortId, successorSortId);
return [4 /*yield*/, model.updateOne({ _id: objectId }, { $set: (_f = {}, _f[sortFieldName] = newSortId.toString(), _f) })];
case 6:
_l.sent();
return [4 /*yield*/, model
.find((_g = {}, _g[sortFieldName] = newSortId.toString(), _g))
.count()
.exec()];
case 7:
documentsCountWithSameSortId = _l.sent();
if (!(documentsCountWithSameSortId > 1)) return [3 /*break*/, 12];
return [4 /*yield*/, model
.find((_h = {}, _h[sortFieldName] = newSortId.toString(), _h), (_j = { _id: 1 }, _j[fieldName] = 1, _j))
.exec()];
case 8:
documentsWithSameSortId = _l.sent();
console.log("mongoose-sort-encrypted-field -> Got collions, retrying... ".concat(documentsWithSameSortId));
_i = 0, documentsWithSameSortId_1 = documentsWithSameSortId;
_l.label = 9;
case 9:
if (!(_i < documentsWithSameSortId_1.length)) return [3 /*break*/, 12];
document_1 = documentsWithSameSortId_1[_i];
// Retrigering sortId generation due to collion
return [4 /*yield*/, model.updateOne({ _id: document_1._id }, { $set: (_k = {}, _k[fieldName] = document_1[fieldName], _k) })];
case 10:
// Retrigering sortId generation due to collion
_l.sent();
_l.label = 11;
case 11:
_i++;
return [3 /*break*/, 9];
case 12:
console.timeEnd("Total time took to update orderId: ".concat(objectId));
return [2 /*return*/];
}
});
function updateSortFieldsForDocument(objectId, model, fieldName, fieldValue, sortFieldName, ignoreSortFieldValue = null) {
return __awaiter(this, void 0, void 0, function* () {
console.time(`Total time took to update orderId: ${objectId}`);
const pipeline = [];
let currN = Math.round((yield model.find({}).count().exec()) / noOfDividePartsForSearching);
let match = {
$and: [{ [sortFieldName]: { $ne: ignoreSortFieldValue } }],
};
let documents = [];
while (currN > 0) {
documents = yield model.aggregate([
{ $match: match },
{
$setWindowFields: {
sortBy: { [sortFieldName]: 1 },
output: {
index: { $rank: {} },
},
},
},
{
$match: {
$expr: {
$eq: [{ $mod: ['$index', currN] }, 0],
},
},
},
{ $project: { [fieldName]: 1, [sortFieldName]: 1 } },
]);
match = yield getMatchForAggregate(documents, fieldName, fieldValue, sortFieldName, ignoreSortFieldValue);
currN = Math.round(currN / noOfDividePartsForSearching);
}
match = yield getMatchForAggregate(documents, fieldName, fieldValue, sortFieldName, ignoreSortFieldValue);
documents = yield model
.aggregate([
{ $match: match },
{ $project: { [fieldName]: 1, [sortFieldName]: 1 } },
{ $sort: { [sortFieldName]: 1 } },
])
.exec();
const index = documentsBinarySearch(documents, fieldName, fieldValue);
let gteIndex = index - 1;
let lteIndex = index;
const predecessorSortId = documents[gteIndex] && documents[gteIndex][sortFieldName];
const successorSortId = documents[lteIndex] && documents[lteIndex][sortFieldName];
const newSortId = getAverageSortId(predecessorSortId, successorSortId);
yield model.updateOne({ _id: objectId }, { $set: { [sortFieldName]: newSortId.toString() } });
const documentsCountWithSameSortId = yield model
.find({ [sortFieldName]: newSortId.toString() })
.count()
.exec();
if (documentsCountWithSameSortId > 1) {
console.log(`mongoose-sort-encrypted-field -> Got collions, retrying... ${objectId}`);
// Retrigering sortId generation due to collion
console.timeEnd(`Total time took to update orderId: ${objectId}`);
yield model.updateOne({ _id: objectId }, { $set: { [fieldName]: decrypters[fieldName][document[fieldName]] } });
}
console.timeEnd(`Total time took to update orderId: ${objectId}`);
});
}
function updateSortFieldsForUpdateOne(filter, model, fieldName, fieldValue, sortFieldName) {
return __awaiter(this, void 0, void 0, function () {
var document;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, model.findOne(filter, { _id: 1 }).exec()];
case 1:
document = _a.sent();
if (!document) return [3 /*break*/, 3];
return [4 /*yield*/, updateSortFieldsForDocument(document._id, model, fieldName, fieldValue, sortFieldName)];
case 2:
_a.sent();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
return __awaiter(this, void 0, void 0, function* () {
const document = yield model
.findOne(filter, { _id: 1, [sortFieldName]: 1 })
.exec();
if (document) {
yield updateSortFieldsForDocument(document._id, model, fieldName, fieldValue, sortFieldName, document[sortFieldName]);
}
});
}
function updateSortFieldsForUpdateMany(filter, model, fieldName, fieldValue, sortFieldName) {
return __awaiter(this, void 0, void 0, function () {
var documents, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, model.find(filter, { _id: 1 }).exec()];
case 1:
documents = _a.sent();
if (!(documents && documents.length > 0)) return [3 /*break*/, 5];
i = 0;
_a.label = 2;
case 2:
if (!(i < documents.length)) return [3 /*break*/, 5];
return [4 /*yield*/, updateSortFieldsForDocument(documents[i]._id, model, fieldName, fieldValue, sortFieldName)];
case 3:
_a.sent();
_a.label = 4;
case 4:
i += 1;
return [3 /*break*/, 2];
case 5: return [2 /*return*/];
return __awaiter(this, void 0, void 0, function* () {
const documents = yield model
.find(filter, { _id: 1, [sortFieldName]: 1 })
.exec();
if (documents && documents.length > 0) {
for (let i = 0; i < documents.length; i += 1) {
yield updateSortFieldsForDocument(documents[i]._id, model, fieldName, decrypters[fieldName](fieldValue), sortFieldName, documents[i][sortFieldName]);
}
});
}
});
}
for (var _i = 0, _d = Object.entries(schema.paths); _i < _d.length; _i++) {
var _e = _d[_i], fieldName = _e[0], field = _e[1];
if (field.options.sortFieldName) {
sortFields[fieldName] = field.options.sortFieldName;
decrypters[fieldName] = field.options.get;
schema.add((_a = {},
_a[field.options.sortFieldName] = {
type: String,
default: null,
},
_a));
}
}
options.sortFields = sortFields;
options.decrypters = decrypters;
schema.post('save', function (doc, next) {
return __awaiter(this, void 0, void 0, function () {
var _i, _a, _b, fieldName, sortFieldName;
return __generator(this, function (_c) {
for (_i = 0, _a = Object.entries(sortFields); _i < _a.length; _i++) {
_b = _a[_i], fieldName = _b[0], sortFieldName = _b[1];
updateSortFieldsForDocument(doc._id, this.constructor, fieldName, doc[fieldName], sortFieldName);
}
next();
return [2 /*return*/];
});
return __awaiter(this, void 0, void 0, function* () {
for (const [fieldName, sortFieldName] of Object.entries(sortFields)) {
updateSortFieldsForDocument(doc._id, this.constructor, fieldName, doc[fieldName], sortFieldName);
}
next();
});
});
schema.post('updateOne', function (res, next) {
var update = this.getUpdate();
for (var _i = 0, _a = Object.entries(sortFields); _i < _a.length; _i++) {
var _b = _a[_i], fieldName = _b[0], sortFieldName = _b[1];
const update = this.getUpdate();
for (const fieldName of Object.keys(sortFields)) {
const sortFieldName = sortFields[fieldName];
if (update.$set && update.$set[sortFieldName]) {

@@ -288,3 +199,3 @@ // Bypass middleware internal call for updating any sortFieldName field

if (update.$set && update.$set[fieldName]) {
updateSortFieldsForUpdateOne(this.getFilter(), this.constructor, fieldName, update.$set[fieldName], sortFieldName);
updateSortFieldsForUpdateOne(this.getFilter(), this.model, fieldName, decrypters[fieldName](update.$set[fieldName]), sortFieldName);
}

@@ -295,6 +206,5 @@ }

schema.post('updateMany', function (res, next) {
var update = this.getUpdate();
for (var _i = 0, _a = Object.keys(sortFields); _i < _a.length; _i++) {
var fieldName = _a[_i];
var sortFieldName = sortFields[fieldName];
const update = this.getUpdate();
for (const fieldName of Object.keys(sortFields)) {
const sortFieldName = sortFields[fieldName];
if (update.$set && update.$set[sortFieldName]) {

@@ -305,3 +215,3 @@ // Bypass middleware internal call for updating any sortFieldName field

if (update.$set && update.$set[fieldName]) {
updateSortFieldsForUpdateMany(this.getFilter(), this.constructor, fieldName, update.$set[fieldName], sortFieldName);
updateSortFieldsForUpdateMany(this.getFilter(), this.model, fieldName, decrypters[fieldName](update.$set[fieldName]), sortFieldName);
}

@@ -313,43 +223,18 @@ }

function evaluateMissedSortFields(model) {
return __awaiter(this, void 0, void 0, function () {
var pluginOptions, _i, _a, fieldName, sortFieldName, documents, _b, documents_1, document_2;
var _c, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
pluginOptions = model.schema.plugins.find(function (plugin) { return plugin.fn.name == 'sortEncryptedFields'; });
if (!pluginOptions) {
throw 'Plugin is not enabled on this model, Try ModelSchema.plugin(sortEncryptedFields), brefore creating Model.';
}
_i = 0, _a = Object.keys(pluginOptions.sortFields);
_e.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 7];
fieldName = _a[_i];
sortFieldName = pluginOptions.sortFields[fieldName];
return [4 /*yield*/, model.find((_c = {}, _c[sortFieldName] = { $eq: null }, _c))];
case 2:
documents = _e.sent();
_b = 0, documents_1 = documents;
_e.label = 3;
case 3:
if (!(_b < documents_1.length)) return [3 /*break*/, 6];
document_2 = documents_1[_b];
// Retrigering sortId generation
return [4 /*yield*/, model.updateOne({ _id: document_2._id }, { $set: (_d = {}, _d[fieldName] = document_2[fieldName], _d) })];
case 4:
// Retrigering sortId generation
_e.sent();
_e.label = 5;
case 5:
_b++;
return [3 /*break*/, 3];
case 6:
_i++;
return [3 /*break*/, 1];
case 7: return [2 /*return*/];
const plugin = model.schema.plugins.find((plugin) => plugin.fn.name == 'sortEncryptedFields');
if (!plugin) {
throw 'Plugin is not enabled on this model, Try ModelSchema.plugin(sortEncryptedFields), brefore creating Model.';
}
model.schema.options.model = model;
const { sortFields, decrypters } = model.schema.options;
for (const fieldName of Object.keys(sortFields)) {
const sortFieldName = sortFields[fieldName];
model.find({ [sortFieldName]: { $eq: null } }).then((documents) => __awaiter(this, void 0, void 0, function* () {
for (const document of documents) {
// Retrigering sortId generation
yield model.updateOne({ _id: document._id }, { $set: { [fieldName]: decrypters[fieldName](document[fieldName]) } });
}
});
});
}));
}
}
module.exports = { sortEncryptedFields: sortEncryptedFields, evaluateMissedSortFields: evaluateMissedSortFields };
module.exports = { sortEncryptedFields, evaluateMissedSortFields };
{
"name": "mongoose-sort-encrypted-field",
"version": "0.0.8a",
"version": "0.0.9",
"description": "Mongoose plugin to enable sorting on encrypted fields",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -47,3 +47,3 @@ # mongoose-sort-encrypted-field

```javascript
const await sortedUsers = await User.find({}).sort({ emailSort: 1 }).exec();
const sortedUsers = await User.find({}).sort({ emailSort: 1 }).exec();
```

@@ -50,0 +50,0 @@

@@ -7,2 +7,3 @@ const Base2N = require('@navpreetdevpuri/base-2-n');

add: Function;
options: { sortFields: {}; decrypters: {} };
paths: {

@@ -14,3 +15,6 @@ [fieldName: string]: {

},
options
options: {
noOfDividePartsForSearching?: number;
noOfCharsToIncreaseOnSaturation?: number;
} = { noOfDividePartsForSearching: 100, noOfCharsToIncreaseOnSaturation: 2 }
) {

@@ -21,8 +25,22 @@ const {

} = options;
options.noOfDividePartsForSearching = noOfDividePartsForSearching;
options.noOfCharsToIncreaseOnSaturation = noOfCharsToIncreaseOnSaturation;
const sortFields: { [key: string]: string } = {};
const sortFields = {};
const decrypters = {};
for (const [fieldName, field] of Object.entries(schema.paths)) {
if (!field.options.sortFieldName) continue;
if (!sortFields[fieldName])
sortFields[fieldName] = field.options.sortFieldName;
if (!decrypters[fieldName]) decrypters[fieldName] = field.options.get;
schema.add({
[field.options.sortFieldName]: {
type: String,
default: null,
},
});
}
schema.options.sortFields = sortFields;
schema.options.decrypters = decrypters;
function documentsBinarySearch(documents, fieldName, value) {

@@ -100,3 +118,4 @@ let start = 0;

fieldValue,
sortFieldName
sortFieldName,
ignoreSortFieldValue
) {

@@ -106,18 +125,19 @@ const index = documentsBinarySearch(documents, fieldName, fieldValue);

const lteIndex = index;
const match = {
$and: [
{ [sortFieldName]: { $ne: null } },
{
[sortFieldName]: {
$gte:
gteIndex == -1 ? undefined : documents[gteIndex][sortFieldName],
$lte:
lteIndex == documents.length
? undefined
: documents[lteIndex][sortFieldName],
},
},
],
const match: any = {
$and: [{ [sortFieldName]: { $ne: ignoreSortFieldValue } }],
};
if (gteIndex === -1 && lteIndex === documents.length) {
return match;
}
match.$and.push({ [sortFieldName]: {} });
if (gteIndex !== -1) {
match.$and[1][sortFieldName].$gte = documents[gteIndex][sortFieldName];
}
if (lteIndex !== documents.length) {
match.$and[1][sortFieldName].$lte = documents[lteIndex][sortFieldName];
}
return match;

@@ -131,3 +151,4 @@ }

fieldValue,
sortFieldName
sortFieldName,
ignoreSortFieldValue = null
) {

@@ -139,5 +160,8 @@ console.time(`Total time took to update orderId: ${objectId}`);

);
let match: {} = { $and: { [sortFieldName]: { $ne: null } } };
let documents;
while (true) {
let match: {} = {
$and: [{ [sortFieldName]: { $ne: ignoreSortFieldValue } }],
};
let documents = [];
while (currN > 0) {
documents = await model.aggregate([

@@ -163,5 +187,2 @@ { $match: match },

if (currN < noOfDividePartsForSearching) {
break;
}
match = await getMatchForAggregate(

@@ -171,6 +192,21 @@ documents,

fieldValue,
sortFieldName
sortFieldName,
ignoreSortFieldValue
);
currN = Math.round(currN / noOfDividePartsForSearching);
}
match = await getMatchForAggregate(
documents,
fieldName,
fieldValue,
sortFieldName,
ignoreSortFieldValue
);
documents = await model
.aggregate([
{ $match: match },
{ $project: { [fieldName]: 1, [sortFieldName]: 1 } },
{ $sort: { [sortFieldName]: 1 } },
])
.exec();

@@ -180,4 +216,6 @@ const index = documentsBinarySearch(documents, fieldName, fieldValue);

let lteIndex = index;
const predecessorSortId = documents[gteIndex][sortFieldName];
const successorSortId = documents[lteIndex][sortFieldName];
const predecessorSortId =
documents[gteIndex] && documents[gteIndex][sortFieldName];
const successorSortId =
documents[lteIndex] && documents[lteIndex][sortFieldName];
const newSortId = getAverageSortId(predecessorSortId, successorSortId);

@@ -193,18 +231,12 @@ await model.updateOne(

if (documentsCountWithSameSortId > 1) {
const documentsWithSameSortId = await model
.find(
{ [sortFieldName]: newSortId.toString() },
{ _id: 1, [fieldName]: 1 }
)
.exec();
console.log(
`mongoose-sort-encrypted-field -> Got collions, retrying... ${documentsWithSameSortId}`
`mongoose-sort-encrypted-field -> Got collions, retrying... ${objectId}`
);
for (const document of documentsWithSameSortId) {
// Retrigering sortId generation due to collion
await model.updateOne(
{ _id: document._id },
{ $set: { [fieldName]: document[fieldName] } }
);
}
// Retrigering sortId generation due to collion
console.timeEnd(`Total time took to update orderId: ${objectId}`);
await model.updateOne(
{ _id: objectId },
{ $set: { [fieldName]: decrypters[fieldName][document[fieldName]] } }
);
}

@@ -221,3 +253,5 @@ console.timeEnd(`Total time took to update orderId: ${objectId}`);

) {
const document = await model.findOne(filter, { _id: 1 }).exec();
const document = await model
.findOne(filter, { _id: 1, [sortFieldName]: 1 })
.exec();
if (document) {

@@ -229,3 +263,4 @@ await updateSortFieldsForDocument(

fieldValue,
sortFieldName
sortFieldName,
document[sortFieldName]
);

@@ -242,3 +277,5 @@ }

) {
const documents = await model.find(filter, { _id: 1 }).exec();
const documents = await model
.find(filter, { _id: 1, [sortFieldName]: 1 })
.exec();
if (documents && documents.length > 0) {

@@ -250,4 +287,5 @@ for (let i = 0; i < documents.length; i += 1) {

fieldName,
fieldValue,
sortFieldName
decrypters[fieldName](fieldValue),
sortFieldName,
documents[i][sortFieldName]
);

@@ -258,18 +296,2 @@ }

for (const [fieldName, field] of Object.entries(schema.paths)) {
if (field.options.sortFieldName) {
sortFields[fieldName] = field.options.sortFieldName;
decrypters[fieldName] = field.options.get;
schema.add({
[field.options.sortFieldName]: {
type: String,
default: null,
},
});
}
}
options.sortFields = sortFields;
options.decrypters = decrypters;
schema.post('save', async function (doc, next) {

@@ -290,3 +312,4 @@ for (const [fieldName, sortFieldName] of Object.entries(sortFields)) {

const update: { $set: { [key: string]: string } } = this.getUpdate();
for (const [fieldName, sortFieldName] of Object.entries(sortFields)) {
for (const fieldName of Object.keys(sortFields)) {
const sortFieldName = sortFields[fieldName];
if (update.$set && update.$set[sortFieldName]) {

@@ -299,5 +322,5 @@ // Bypass middleware internal call for updating any sortFieldName field

this.getFilter(),
this.constructor,
this.model,
fieldName,
update.$set[fieldName],
decrypters[fieldName](update.$set[fieldName]),
sortFieldName

@@ -321,5 +344,5 @@ );

this.getFilter(),
this.constructor,
this.model,
fieldName,
update.$set[fieldName],
decrypters[fieldName](update.$set[fieldName]),
sortFieldName

@@ -333,21 +356,24 @@ );

async function evaluateMissedSortFields(model) {
const pluginOptions = model.schema.plugins.find(
function evaluateMissedSortFields(model) {
const plugin = model.schema.plugins.find(
(plugin) => plugin.fn.name == 'sortEncryptedFields'
);
if (!pluginOptions) {
if (!plugin) {
throw 'Plugin is not enabled on this model, Try ModelSchema.plugin(sortEncryptedFields), brefore creating Model.';
}
for (const fieldName of Object.keys(pluginOptions.sortFields)) {
const sortFieldName = pluginOptions.sortFields[fieldName];
const documents = await model.find({ [sortFieldName]: { $eq: null } });
for (const document of documents) {
// Retrigering sortId generation
await model.updateOne(
{ _id: document._id },
{ $set: { [fieldName]: document[fieldName] } }
);
}
model.schema.options.model = model;
const { sortFields, decrypters } = model.schema.options;
for (const fieldName of Object.keys(sortFields)) {
const sortFieldName = sortFields[fieldName];
model.find({ [sortFieldName]: { $eq: null } }).then(async (documents) => {
for (const document of documents) {
// Retrigering sortId generation
await model.updateOne(
{ _id: document._id },
{ $set: { [fieldName]: decrypters[fieldName](document[fieldName]) } }
);
}
});
}
}
module.exports = { sortEncryptedFields, evaluateMissedSortFields };
{
"compilerOptions": {
"incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: */
"target": "es6", /* Specify ECMAScript target version: */
"module": "commonjs", /* 'none', 'commonjs', 'amd', 'system', etc */

@@ -6,0 +6,0 @@ "declaration": true, /* Concatenate & emit output to single file.*/

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc