@flowerforce/flowerbase 1.7.3-beta.2 → 1.7.3-beta.4
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/auth/controller.d.ts.map +1 -1
- package/dist/auth/controller.js +1 -1
- package/dist/auth/plugins/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/jwt.js +8 -5
- package/dist/auth/providers/custom-function/controller.d.ts.map +1 -1
- package/dist/auth/providers/custom-function/controller.js +8 -4
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
- package/dist/auth/providers/local-userpass/controller.js +1 -1
- package/dist/monitoring/utils.d.ts.map +1 -1
- package/dist/monitoring/utils.js +3 -2
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.js +36 -14
- package/dist/services/mongodb-atlas/model.d.ts +4 -1
- package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/controller.ts +3 -0
- package/src/auth/plugins/jwt.test.ts +35 -2
- package/src/auth/plugins/jwt.ts +15 -9
- package/src/auth/providers/custom-function/controller.ts +14 -2
- package/src/auth/providers/local-userpass/controller.ts +6 -1
- package/src/monitoring/utils.ts +3 -2
- package/src/services/mongodb-atlas/__tests__/findOneAndUpdate.test.ts +34 -0
- package/src/services/mongodb-atlas/__tests__/realmCompatibility.test.ts +43 -0
- package/src/services/mongodb-atlas/index.ts +42 -17
- package/src/services/mongodb-atlas/model.ts +9 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAQzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAQzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,iBA2KxD"}
|
package/dist/auth/controller.js
CHANGED
|
@@ -111,7 +111,7 @@ function authController(app) {
|
|
|
111
111
|
: {};
|
|
112
112
|
res.status(201);
|
|
113
113
|
return {
|
|
114
|
-
access_token: this.createAccessToken(Object.assign(Object.assign({}, auth_user), { user_data: Object.assign(Object.assign({}, user), { id: req.user.sub }) }))
|
|
114
|
+
access_token: this.createAccessToken(Object.assign(Object.assign({}, auth_user), { user_data: Object.assign(Object.assign({}, user), { id: req.user.sub }), custom_data: Object.assign({}, user) }))
|
|
115
115
|
};
|
|
116
116
|
});
|
|
117
117
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/jwt.ts"],"names":[],"mappings":"AAKA,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/jwt.ts"],"names":[],"mappings":"AAKA,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAkBD;;;;;;;GAOG;iUAC8C,OAAO;AAAxD,wBA+GE"}
|
package/dist/auth/plugins/jwt.js
CHANGED
|
@@ -16,6 +16,7 @@ const jwt_1 = __importDefault(require("@fastify/jwt"));
|
|
|
16
16
|
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
|
|
17
17
|
const mongodb_1 = require("mongodb");
|
|
18
18
|
const constants_1 = require("../../constants");
|
|
19
|
+
const isRecord = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
19
20
|
const unauthorizedSessionError = {
|
|
20
21
|
message: 'Unauthorized',
|
|
21
22
|
error: 'unauthorized',
|
|
@@ -94,14 +95,16 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
94
95
|
});
|
|
95
96
|
fastify.decorate('createAccessToken', function (user) {
|
|
96
97
|
const id = user._id.toString();
|
|
97
|
-
|
|
98
|
-
const
|
|
98
|
+
const userData = isRecord(user.user_data) ? Object.assign({}, user.user_data) : {};
|
|
99
|
+
const customData = isRecord(user.custom_data)
|
|
100
|
+
? Object.assign({}, user.custom_data) : Object.assign({}, userData);
|
|
101
|
+
const mergedUserData = Object.assign(Object.assign(Object.assign({}, customData), userData), { _id: id, id, email: typeof user.email === 'string' ? user.email : userData.email });
|
|
99
102
|
return this.jwt.sign({
|
|
100
103
|
typ: 'access',
|
|
101
104
|
id,
|
|
102
|
-
data:
|
|
103
|
-
user_data:
|
|
104
|
-
custom_data:
|
|
105
|
+
data: mergedUserData,
|
|
106
|
+
user_data: mergedUserData,
|
|
107
|
+
custom_data: customData
|
|
105
108
|
}, {
|
|
106
109
|
iss: BAAS_ID,
|
|
107
110
|
jti: BAAS_ID,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AASzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AASzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBAiHlE"}
|
|
@@ -26,7 +26,7 @@ function customFunctionController(app) {
|
|
|
26
26
|
const functionsList = state_1.StateManager.select('functions');
|
|
27
27
|
const services = state_1.StateManager.select('services');
|
|
28
28
|
const db = app.mongo.client.db(constants_1.DB_NAME);
|
|
29
|
-
const { authCollection, refreshTokensCollection } = constants_1.AUTH_CONFIG;
|
|
29
|
+
const { authCollection, refreshTokensCollection, userCollection, user_id_field } = constants_1.AUTH_CONFIG;
|
|
30
30
|
const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
|
|
31
31
|
/**
|
|
32
32
|
* Endpoint for user login.
|
|
@@ -80,11 +80,15 @@ function customFunctionController(app) {
|
|
|
80
80
|
reply.code(401).send({ message: 'Unauthorized' });
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
|
+
const user = user_id_field && userCollection
|
|
84
|
+
? yield db
|
|
85
|
+
.collection(userCollection)
|
|
86
|
+
.findOne({ [user_id_field]: authUser._id.toString() })
|
|
87
|
+
: {};
|
|
83
88
|
const currentUserData = {
|
|
84
89
|
_id: authUser._id,
|
|
85
|
-
user_data: {
|
|
86
|
-
|
|
87
|
-
}
|
|
90
|
+
user_data: Object.assign(Object.assign({}, (user || {})), { id: authUser._id.toString(), email: authUser.email }),
|
|
91
|
+
custom_data: Object.assign({}, (user || {}))
|
|
88
92
|
};
|
|
89
93
|
const refreshToken = this.createRefreshToken(currentUserData);
|
|
90
94
|
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAoXjE"}
|
|
@@ -209,7 +209,7 @@ function localUserPassController(app) {
|
|
|
209
209
|
.findOne({ [user_id_field]: authUser._id.toString() })
|
|
210
210
|
: {};
|
|
211
211
|
authUser === null || authUser === void 0 ? true : delete authUser.password;
|
|
212
|
-
const userWithCustomData = Object.assign(Object.assign({}, authUser), { user_data: Object.assign(Object.assign({}, (user || {})), {
|
|
212
|
+
const userWithCustomData = Object.assign(Object.assign({}, authUser), { user_data: Object.assign(Object.assign({}, (user || {})), { id: authUser._id.toString(), email: authUser.email }), custom_data: Object.assign({}, (user || {})), data: { email: authUser.email }, id: authUser._id.toString() });
|
|
213
213
|
if (authUser && authUser.status !== 'confirmed') {
|
|
214
214
|
throw new Error(utils_1.AUTH_ERRORS.USER_NOT_CONFIRMED);
|
|
215
215
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/monitoring/utils.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/monitoring/utils.ts"],"names":[],"mappings":"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"}
|
package/dist/monitoring/utils.js
CHANGED
|
@@ -354,14 +354,15 @@ const resolveUserContext = (app, userId, userPayload) => __awaiter(void 0, void
|
|
|
354
354
|
: (customUser && typeof customUser[userIdField] !== 'undefined'
|
|
355
355
|
? String(customUser[userIdField])
|
|
356
356
|
: normalizedUserId);
|
|
357
|
-
const
|
|
357
|
+
const custom_data = customUser ? (0, exports.stripSensitiveFields)(customUser) : {};
|
|
358
|
+
const user_data = Object.assign(Object.assign({}, custom_data), { id, _id: id, email: authUser && typeof authUser.email === 'string'
|
|
358
359
|
? authUser.email
|
|
359
360
|
: undefined });
|
|
360
361
|
const user = {
|
|
361
362
|
id,
|
|
362
363
|
user_data,
|
|
363
364
|
data: user_data,
|
|
364
|
-
custom_data
|
|
365
|
+
custom_data
|
|
365
366
|
};
|
|
366
367
|
if (isObjectId) {
|
|
367
368
|
user._id = new mongodb_1.ObjectId(id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAuBA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAuBA,OAAO,EAGL,oBAAoB,EAErB,MAAM,SAAS,CAAA;AA6tChB,QAAA,MAAM,YAAY,EAAE,oBA6BlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
|
|
@@ -8,15 +8,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
11
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
24
|
};
|
|
14
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
15
27
|
const get_1 = __importDefault(require("lodash/get"));
|
|
16
28
|
const isEqual_1 = __importDefault(require("lodash/isEqual"));
|
|
17
29
|
const set_1 = __importDefault(require("lodash/set"));
|
|
18
30
|
const unset_1 = __importDefault(require("lodash/unset"));
|
|
19
|
-
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
20
31
|
const utils_1 = require("../../monitoring/utils");
|
|
21
32
|
const machines_1 = require("../../utils/roles/machines");
|
|
22
33
|
const utils_2 = require("../../utils/roles/machines/utils");
|
|
@@ -92,6 +103,16 @@ const normalizeInsertManyResult = (result) => {
|
|
|
92
103
|
return result;
|
|
93
104
|
return Object.assign(Object.assign({}, result), { insertedIds: Object.values(result.insertedIds) });
|
|
94
105
|
};
|
|
106
|
+
const normalizeFindOneAndUpdateOptions = (options) => {
|
|
107
|
+
if (!options)
|
|
108
|
+
return undefined;
|
|
109
|
+
const { returnNewDocument } = options, rest = __rest(options, ["returnNewDocument"]);
|
|
110
|
+
if (typeof returnNewDocument !== 'boolean' || typeof rest.returnDocument !== 'undefined') {
|
|
111
|
+
return rest;
|
|
112
|
+
}
|
|
113
|
+
return Object.assign(Object.assign({}, rest), { returnDocument: returnNewDocument ? 'after' : 'before' });
|
|
114
|
+
};
|
|
115
|
+
const buildAndQuery = (clauses) => clauses.length ? { $and: clauses } : {};
|
|
95
116
|
const hasAtomicOperators = (data) => Object.keys(data).some((key) => key.startsWith('$'));
|
|
96
117
|
const normalizeUpdatePayload = (data) => hasAtomicOperators(data) ? data : { $set: data };
|
|
97
118
|
const hasOperatorExpressions = (value) => isPlainObject(value) && Object.keys(value).some((key) => key.startsWith('$'));
|
|
@@ -336,7 +357,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
336
357
|
logService('findOne query', { collName, formattedQuery });
|
|
337
358
|
const safeQuery = (0, utils_3.normalizeQuery)(formattedQuery);
|
|
338
359
|
logService('findOne normalizedQuery', { collName, safeQuery });
|
|
339
|
-
const result = yield collection.findOne(
|
|
360
|
+
const result = yield collection.findOne(buildAndQuery(safeQuery), resolvedOptions);
|
|
340
361
|
logDebug('findOne result', {
|
|
341
362
|
collection: collName,
|
|
342
363
|
result
|
|
@@ -397,7 +418,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
397
418
|
// Apply access control filters
|
|
398
419
|
const formattedQuery = (0, utils_3.getFormattedQuery)(filters, query, user);
|
|
399
420
|
// Retrieve the document to check permissions before deleting
|
|
400
|
-
const result = yield collection.findOne(
|
|
421
|
+
const result = yield collection.findOne(buildAndQuery(formattedQuery));
|
|
401
422
|
const winningRole = (0, utils_2.getWinningRole)(result, user, roles);
|
|
402
423
|
logDebug('delete winningRole', {
|
|
403
424
|
collection: collName,
|
|
@@ -415,7 +436,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
415
436
|
if (!status) {
|
|
416
437
|
throw new Error('Delete not permitted');
|
|
417
438
|
}
|
|
418
|
-
const res = yield collection.deleteOne(
|
|
439
|
+
const res = yield collection.deleteOne(buildAndQuery(formattedQuery), options);
|
|
419
440
|
emitMongoEvent('deleteOne');
|
|
420
441
|
return res;
|
|
421
442
|
}
|
|
@@ -516,10 +537,10 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
516
537
|
const safeQuery = Array.isArray(formattedQuery)
|
|
517
538
|
? (0, utils_3.normalizeQuery)(formattedQuery)
|
|
518
539
|
: formattedQuery;
|
|
519
|
-
const result = yield collection.findOne(
|
|
540
|
+
const result = yield collection.findOne(buildAndQuery(safeQuery));
|
|
520
541
|
if (!result) {
|
|
521
542
|
if (options === null || options === void 0 ? void 0 : options.upsert) {
|
|
522
|
-
const upsertResult = yield collection.updateOne(
|
|
543
|
+
const upsertResult = yield collection.updateOne(buildAndQuery(safeQuery), normalizedData, options);
|
|
523
544
|
emitMongoEvent('updateOne');
|
|
524
545
|
return upsertResult;
|
|
525
546
|
}
|
|
@@ -543,7 +564,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
543
564
|
if (!status || !areDocumentsEqual) {
|
|
544
565
|
throw new Error('Update not permitted');
|
|
545
566
|
}
|
|
546
|
-
const res = yield collection.updateOne(
|
|
567
|
+
const res = yield collection.updateOne(buildAndQuery(safeQuery), normalizedData, options);
|
|
547
568
|
emitMongoEvent('updateOne');
|
|
548
569
|
return res;
|
|
549
570
|
}
|
|
@@ -569,13 +590,14 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
569
590
|
findOneAndUpdate: (query, data, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
570
591
|
var _a;
|
|
571
592
|
try {
|
|
593
|
+
const normalizedOptions = normalizeFindOneAndUpdateOptions(options);
|
|
572
594
|
if (!run_as_system) {
|
|
573
595
|
(0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.UPDATE);
|
|
574
596
|
const formattedQuery = (0, utils_3.getFormattedQuery)(filters, query, user);
|
|
575
597
|
const safeQuery = Array.isArray(formattedQuery)
|
|
576
598
|
? (0, utils_3.normalizeQuery)(formattedQuery)
|
|
577
599
|
: formattedQuery;
|
|
578
|
-
const result = yield collection.findOne(
|
|
600
|
+
const result = yield collection.findOne(buildAndQuery(safeQuery));
|
|
579
601
|
if (!result) {
|
|
580
602
|
throw new Error('Update not permitted');
|
|
581
603
|
}
|
|
@@ -588,7 +610,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
588
610
|
: getUpdatedPaths(normalizedData);
|
|
589
611
|
const [docToCheck] = Array.isArray(normalizedData)
|
|
590
612
|
? yield collection.aggregate([
|
|
591
|
-
{ $match:
|
|
613
|
+
{ $match: buildAndQuery(safeQuery) },
|
|
592
614
|
{ $limit: 1 },
|
|
593
615
|
...normalizedData
|
|
594
616
|
]).toArray()
|
|
@@ -605,9 +627,9 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
605
627
|
if (!status || !areDocumentsEqual) {
|
|
606
628
|
throw new Error('Update not permitted');
|
|
607
629
|
}
|
|
608
|
-
const updateResult =
|
|
609
|
-
? yield collection.findOneAndUpdate(
|
|
610
|
-
: yield collection.findOneAndUpdate(
|
|
630
|
+
const updateResult = normalizedOptions
|
|
631
|
+
? yield collection.findOneAndUpdate(buildAndQuery(safeQuery), normalizedData, normalizedOptions)
|
|
632
|
+
: yield collection.findOneAndUpdate(buildAndQuery(safeQuery), normalizedData);
|
|
611
633
|
if (!updateResult) {
|
|
612
634
|
emitMongoEvent('findOneAndUpdate');
|
|
613
635
|
return updateResult;
|
|
@@ -625,8 +647,8 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
|
|
|
625
647
|
emitMongoEvent('findOneAndUpdate');
|
|
626
648
|
return sanitizedDoc;
|
|
627
649
|
}
|
|
628
|
-
const updateResult =
|
|
629
|
-
? yield collection.findOneAndUpdate(query, data,
|
|
650
|
+
const updateResult = normalizedOptions
|
|
651
|
+
? yield collection.findOneAndUpdate(query, data, normalizedOptions)
|
|
630
652
|
: yield collection.findOneAndUpdate(query, data);
|
|
631
653
|
emitMongoEvent('findOneAndUpdate');
|
|
632
654
|
return updateResult;
|
|
@@ -29,11 +29,11 @@ export type GetOperatorsFunction = (collection: Collection<Document>, { rules, c
|
|
|
29
29
|
collName: string;
|
|
30
30
|
monitoringOrigin?: string;
|
|
31
31
|
}) => {
|
|
32
|
+
findOneAndUpdate: (filter: MongoFilter<Document>, update: UpdateFilter<Document> | Document[], options?: RealmCompatibleFindOneAndUpdateOptions) => Promise<Document | null>;
|
|
32
33
|
findOne: (filter?: MongoFilter<Document>, projection?: Document, options?: FindOneOptions) => ReturnType<Method<'findOne'>>;
|
|
33
34
|
deleteOne: (...params: Parameters<Method<'deleteOne'>>) => ReturnType<Method<'deleteOne'>>;
|
|
34
35
|
insertOne: (...params: Parameters<Method<'insertOne'>>) => ReturnType<Method<'insertOne'>>;
|
|
35
36
|
updateOne: (...params: Parameters<Method<'updateOne'>>) => ReturnType<Method<'updateOne'>>;
|
|
36
|
-
findOneAndUpdate: (filter: MongoFilter<Document>, update: UpdateFilter<Document> | Document[], options?: FindOneAndUpdateOptions) => Promise<Document | null>;
|
|
37
37
|
find: (filter?: MongoFilter<Document>, projection?: Document, options?: FindOptions) => FindCursor;
|
|
38
38
|
count: (...params: Parameters<Method<'countDocuments'>>) => ReturnType<Method<'countDocuments'>>;
|
|
39
39
|
countDocuments: (...params: Parameters<Method<'countDocuments'>>) => ReturnType<Method<'countDocuments'>>;
|
|
@@ -43,6 +43,9 @@ export type GetOperatorsFunction = (collection: Collection<Document>, { rules, c
|
|
|
43
43
|
updateMany: (...params: Parameters<Method<'updateMany'>>) => ReturnType<Method<'updateMany'>>;
|
|
44
44
|
deleteMany: (...params: Parameters<Method<'deleteMany'>>) => ReturnType<Method<'deleteMany'>>;
|
|
45
45
|
};
|
|
46
|
+
export type RealmCompatibleFindOneAndUpdateOptions = FindOneAndUpdateOptions & {
|
|
47
|
+
returnNewDocument?: boolean;
|
|
48
|
+
};
|
|
46
49
|
export declare enum CRUD_OPERATIONS {
|
|
47
50
|
CREATE = "CREATE",
|
|
48
51
|
READ = "READ",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,UAAU,EACV,QAAQ,EACR,UAAU,EACV,uBAAuB,EACvB,cAAc,EACd,WAAW,EACX,MAAM,IAAI,WAAW,EACrB,YAAY,EACZ,MAAM,EACP,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAElD,MAAM,MAAM,oBAAoB,GAAG,CACjC,GAAG,EAAE,eAAe,EACpB,EACE,KAAK,EACL,IAAI,EACJ,aAAa,EACb,UAAU,EACX,EAAE;IACD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACtC,KACE;IACH,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QACtB,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAAU,CAAC,oBAAoB,CAAC,CAAA;KACnE,CAAA;IACD,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,oBAAoB,KAAK,aAAa,CAAA;CAChE,CAAA;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,IAAI,GAAG,MAAM,IAAI;IACxD,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAA;CAC5C,CAAA;AACD,KAAK,MAAM,CAAC,CAAC,SAAS,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAE3E,MAAM,MAAM,oBAAoB,GAAG,CACjC,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,EAChC,EACE,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,aAAa,EACb,gBAAgB,EACjB,EAAE;IACD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,KACE;IACH,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/model.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/auth/controller.ts
CHANGED
|
@@ -13,9 +13,10 @@ jest.mock('node:diagnostics_channel', () => {
|
|
|
13
13
|
}
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
+
import { ObjectId } from 'bson'
|
|
16
17
|
import fastify, { FastifyInstance, FastifyReply } from 'fastify'
|
|
18
|
+
import * as jwt from 'jsonwebtoken'
|
|
17
19
|
import jwtAuthPlugin from './jwt'
|
|
18
|
-
import { ObjectId } from 'bson'
|
|
19
20
|
|
|
20
21
|
const SECRET = 'test-secret'
|
|
21
22
|
|
|
@@ -52,7 +53,7 @@ describe('jwtAuthentication', () => {
|
|
|
52
53
|
const collectionMock = { findOne: findOneMock }
|
|
53
54
|
const dbMock = { collection: jest.fn().mockReturnValue(collectionMock) }
|
|
54
55
|
const mongoMock = { client: { db: jest.fn().mockReturnValue(dbMock) } }
|
|
55
|
-
|
|
56
|
+
; (app as any).mongo = mongoMock
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
const createReply = () => {
|
|
@@ -111,4 +112,36 @@ describe('jwtAuthentication', () => {
|
|
|
111
112
|
expect(reply.code).toHaveBeenCalledWith(401)
|
|
112
113
|
expect(reply.send).toHaveBeenCalledWith(unauthorizedSessionError)
|
|
113
114
|
})
|
|
115
|
+
|
|
116
|
+
it('preserves linked custom_data _id in access token payload', async () => {
|
|
117
|
+
const authId = new ObjectId()
|
|
118
|
+
const linkedId = new ObjectId()
|
|
119
|
+
const token = (app as any).createAccessToken({
|
|
120
|
+
_id: authId,
|
|
121
|
+
email: 'owner@example.com',
|
|
122
|
+
user_data: {
|
|
123
|
+
_id: linkedId.toHexString(),
|
|
124
|
+
role: 'owner'
|
|
125
|
+
},
|
|
126
|
+
custom_data: {
|
|
127
|
+
_id: linkedId.toHexString(),
|
|
128
|
+
role: 'owner'
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const decoded = jwt.decode(token) as {
|
|
133
|
+
id: string
|
|
134
|
+
data: { _id: string; id: string }
|
|
135
|
+
user_data: { _id: string; id: string }
|
|
136
|
+
custom_data: { _id: string; role: string }
|
|
137
|
+
sub: string
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
expect(decoded.id).toBe(authId.toHexString())
|
|
141
|
+
expect(decoded.sub).toBe(authId.toHexString())
|
|
142
|
+
expect(decoded.data._id).toBe(authId.toHexString())
|
|
143
|
+
expect(decoded.user_data._id).toBe(authId.toHexString())
|
|
144
|
+
expect(decoded.custom_data._id).toBe(linkedId.toHexString())
|
|
145
|
+
expect(decoded.custom_data.role).toBe('owner')
|
|
146
|
+
})
|
|
114
147
|
})
|
package/src/auth/plugins/jwt.ts
CHANGED
|
@@ -13,6 +13,9 @@ type JwtAccessWithTimestamp = {
|
|
|
13
13
|
iat?: number
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
17
|
+
!!value && typeof value === 'object' && !Array.isArray(value)
|
|
18
|
+
|
|
16
19
|
const unauthorizedSessionError = {
|
|
17
20
|
message: 'Unauthorized',
|
|
18
21
|
error: 'unauthorized',
|
|
@@ -98,22 +101,25 @@ export default fp(async function (fastify, opts: Options) {
|
|
|
98
101
|
|
|
99
102
|
fastify.decorate('createAccessToken', function (user: WithId<Document>) {
|
|
100
103
|
const id = user._id.toString()
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
...
|
|
104
|
+
const userData = isRecord(user.user_data) ? { ...user.user_data } : {}
|
|
105
|
+
const customData = isRecord(user.custom_data)
|
|
106
|
+
? { ...user.custom_data }
|
|
107
|
+
: { ...userData }
|
|
108
|
+
const mergedUserData = {
|
|
109
|
+
...customData,
|
|
110
|
+
...userData,
|
|
105
111
|
_id: id,
|
|
106
|
-
id
|
|
107
|
-
email: user.email
|
|
112
|
+
id,
|
|
113
|
+
email: typeof user.email === 'string' ? user.email : userData.email
|
|
108
114
|
}
|
|
109
115
|
|
|
110
116
|
return this.jwt.sign(
|
|
111
117
|
{
|
|
112
118
|
typ: 'access',
|
|
113
119
|
id,
|
|
114
|
-
data:
|
|
115
|
-
user_data:
|
|
116
|
-
custom_data:
|
|
120
|
+
data: mergedUserData,
|
|
121
|
+
user_data: mergedUserData,
|
|
122
|
+
custom_data: customData
|
|
117
123
|
},
|
|
118
124
|
{
|
|
119
125
|
iss: BAAS_ID,
|
|
@@ -17,7 +17,7 @@ export async function customFunctionController(app: FastifyInstance) {
|
|
|
17
17
|
const functionsList = StateManager.select('functions')
|
|
18
18
|
const services = StateManager.select('services')
|
|
19
19
|
const db = app.mongo.client.db(DB_NAME)
|
|
20
|
-
const { authCollection, refreshTokensCollection } = AUTH_CONFIG
|
|
20
|
+
const { authCollection, refreshTokensCollection, userCollection, user_id_field } = AUTH_CONFIG
|
|
21
21
|
const refreshTokenTtlMs = DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -89,10 +89,22 @@ export async function customFunctionController(app: FastifyInstance) {
|
|
|
89
89
|
return
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
const user =
|
|
93
|
+
user_id_field && userCollection
|
|
94
|
+
? await db
|
|
95
|
+
.collection(userCollection)
|
|
96
|
+
.findOne({ [user_id_field]: authUser._id.toString() })
|
|
97
|
+
: {}
|
|
98
|
+
|
|
92
99
|
const currentUserData = {
|
|
93
100
|
_id: authUser._id,
|
|
94
101
|
user_data: {
|
|
95
|
-
|
|
102
|
+
...(user || {}),
|
|
103
|
+
id: authUser._id.toString(),
|
|
104
|
+
email: authUser.email
|
|
105
|
+
},
|
|
106
|
+
custom_data: {
|
|
107
|
+
...(user || {})
|
|
96
108
|
}
|
|
97
109
|
}
|
|
98
110
|
const refreshToken = this.createRefreshToken(currentUserData)
|
|
@@ -268,7 +268,12 @@ export async function localUserPassController(app: FastifyInstance) {
|
|
|
268
268
|
|
|
269
269
|
const userWithCustomData = {
|
|
270
270
|
...authUser,
|
|
271
|
-
user_data: {
|
|
271
|
+
user_data: {
|
|
272
|
+
...(user || {}),
|
|
273
|
+
id: authUser._id.toString(),
|
|
274
|
+
email: authUser.email
|
|
275
|
+
},
|
|
276
|
+
custom_data: { ...(user || {}) },
|
|
272
277
|
data: { email: authUser.email },
|
|
273
278
|
id: authUser._id.toString()
|
|
274
279
|
}
|
package/src/monitoring/utils.ts
CHANGED
|
@@ -404,8 +404,9 @@ export const resolveUserContext = async (
|
|
|
404
404
|
? String(customUser[userIdField])
|
|
405
405
|
: normalizedUserId)
|
|
406
406
|
|
|
407
|
+
const custom_data = customUser ? stripSensitiveFields(customUser) : {}
|
|
407
408
|
const user_data = {
|
|
408
|
-
...
|
|
409
|
+
...custom_data,
|
|
409
410
|
id,
|
|
410
411
|
_id: id,
|
|
411
412
|
email: authUser && typeof (authUser as { email?: unknown }).email === 'string'
|
|
@@ -417,7 +418,7 @@ export const resolveUserContext = async (
|
|
|
417
418
|
id,
|
|
418
419
|
user_data,
|
|
419
420
|
data: user_data,
|
|
420
|
-
custom_data
|
|
421
|
+
custom_data
|
|
421
422
|
}
|
|
422
423
|
|
|
423
424
|
if (isObjectId) {
|
|
@@ -91,4 +91,38 @@ describe('mongodb-atlas findOneAndUpdate', () => {
|
|
|
91
91
|
).rejects.toThrow('Update not permitted')
|
|
92
92
|
expect(findOneAndUpdate).not.toHaveBeenCalled()
|
|
93
93
|
})
|
|
94
|
+
|
|
95
|
+
it('maps returnNewDocument=true to returnDocument=after', async () => {
|
|
96
|
+
const id = new ObjectId()
|
|
97
|
+
const existingDoc = { _id: id, value: 100, userId: 'user-1' }
|
|
98
|
+
const updatedDoc = { _id: id, value: 101, userId: 'user-1' }
|
|
99
|
+
const findOne = jest.fn().mockResolvedValue(existingDoc)
|
|
100
|
+
const findOneAndUpdate = jest.fn().mockResolvedValue(updatedDoc)
|
|
101
|
+
const collection = {
|
|
102
|
+
collectionName: 'todos',
|
|
103
|
+
findOne,
|
|
104
|
+
findOneAndUpdate
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const app = createAppWithCollection(collection)
|
|
108
|
+
const operators = MongoDbAtlas(app as any, {
|
|
109
|
+
rules: createRules(),
|
|
110
|
+
user: { id: 'user-1' }
|
|
111
|
+
})
|
|
112
|
+
.db('db')
|
|
113
|
+
.collection('todos')
|
|
114
|
+
|
|
115
|
+
const result = await operators.findOneAndUpdate(
|
|
116
|
+
{ _id: id },
|
|
117
|
+
{ $inc: { value: 1 } },
|
|
118
|
+
{ returnNewDocument: true } as any
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
expect(result).toEqual(updatedDoc)
|
|
122
|
+
expect(findOneAndUpdate).toHaveBeenCalledWith(
|
|
123
|
+
{ $and: [{ _id: id }] },
|
|
124
|
+
{ $inc: { value: 1 } },
|
|
125
|
+
{ returnDocument: 'after' }
|
|
126
|
+
)
|
|
127
|
+
})
|
|
94
128
|
})
|
|
@@ -153,6 +153,31 @@ describe('mongodb-atlas Realm compatibility', () => {
|
|
|
153
153
|
expect(aggregate).not.toHaveBeenCalled()
|
|
154
154
|
})
|
|
155
155
|
|
|
156
|
+
it('supports Realm returnNewDocument option in findOneAndUpdate', async () => {
|
|
157
|
+
const id = new ObjectId()
|
|
158
|
+
const findOneAndUpdate = jest.fn().mockResolvedValue({ _id: id, value: 101 })
|
|
159
|
+
const collection = {
|
|
160
|
+
collectionName: 'todos',
|
|
161
|
+
findOneAndUpdate
|
|
162
|
+
}
|
|
163
|
+
const operators = MongoDbAtlas(createAppWithCollection(collection) as any, {
|
|
164
|
+
run_as_system: true
|
|
165
|
+
}).db('db').collection('todos')
|
|
166
|
+
|
|
167
|
+
const result = await operators.findOneAndUpdate(
|
|
168
|
+
{ _id: id },
|
|
169
|
+
{ $inc: { value: 1 } } as any,
|
|
170
|
+
{ returnNewDocument: true } as any
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
expect(result).toEqual({ _id: id, value: 101 })
|
|
174
|
+
expect(findOneAndUpdate).toHaveBeenCalledWith(
|
|
175
|
+
{ _id: id },
|
|
176
|
+
{ $inc: { value: 1 } },
|
|
177
|
+
{ returnDocument: 'after' }
|
|
178
|
+
)
|
|
179
|
+
})
|
|
180
|
+
|
|
156
181
|
it('supports operator updates in updateMany without using invalid aggregate stages', async () => {
|
|
157
182
|
const id = new ObjectId()
|
|
158
183
|
const find = jest.fn().mockReturnValue({
|
|
@@ -225,6 +250,24 @@ describe('mongodb-atlas Realm compatibility', () => {
|
|
|
225
250
|
expect(find).toHaveBeenCalledWith({ active: true }, { session })
|
|
226
251
|
})
|
|
227
252
|
|
|
253
|
+
it('allows findOne({}) without emitting an empty $and query', async () => {
|
|
254
|
+
const doc = { _id: new ObjectId(), label: 'first' }
|
|
255
|
+
const findOne = jest.fn().mockResolvedValue(doc)
|
|
256
|
+
const collection = {
|
|
257
|
+
collectionName: 'todos',
|
|
258
|
+
findOne
|
|
259
|
+
}
|
|
260
|
+
const operators = MongoDbAtlas(createAppWithCollection(collection) as any, {
|
|
261
|
+
rules: createRules(),
|
|
262
|
+
user: { id: 'user-1' }
|
|
263
|
+
}).db('db').collection('todos')
|
|
264
|
+
|
|
265
|
+
const result = await operators.findOne({})
|
|
266
|
+
|
|
267
|
+
expect(result).toEqual(doc)
|
|
268
|
+
expect(findOne).toHaveBeenCalledWith({}, undefined)
|
|
269
|
+
})
|
|
270
|
+
|
|
228
271
|
it('returns insertMany insertedIds as an array', async () => {
|
|
229
272
|
const id0 = new ObjectId()
|
|
230
273
|
const id1 = new ObjectId()
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
1
2
|
import get from 'lodash/get'
|
|
2
3
|
import isEqual from 'lodash/isEqual'
|
|
3
4
|
import set from 'lodash/set'
|
|
4
5
|
import unset from 'lodash/unset'
|
|
5
|
-
import cloneDeep from 'lodash/cloneDeep'
|
|
6
6
|
import {
|
|
7
7
|
ClientSession,
|
|
8
8
|
ClientSessionOptions,
|
|
9
9
|
Collection,
|
|
10
10
|
Document,
|
|
11
11
|
EventsDescription,
|
|
12
|
+
FindOneAndUpdateOptions,
|
|
12
13
|
FindOneOptions,
|
|
13
14
|
FindOptions,
|
|
14
|
-
FindOneAndUpdateOptions,
|
|
15
15
|
Filter as MongoFilter,
|
|
16
16
|
UpdateFilter,
|
|
17
17
|
WithId
|
|
@@ -21,7 +21,12 @@ import { buildRulesMeta } from '../../monitoring/utils'
|
|
|
21
21
|
import { checkValidation } from '../../utils/roles/machines'
|
|
22
22
|
import { getWinningRole } from '../../utils/roles/machines/utils'
|
|
23
23
|
import { emitServiceEvent } from '../monitoring'
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
CRUD_OPERATIONS,
|
|
26
|
+
GetOperatorsFunction,
|
|
27
|
+
MongodbAtlasFunction,
|
|
28
|
+
RealmCompatibleFindOneAndUpdateOptions
|
|
29
|
+
} from './model'
|
|
25
30
|
import {
|
|
26
31
|
applyAccessControlToPipeline,
|
|
27
32
|
checkDenyOperation,
|
|
@@ -115,6 +120,25 @@ const normalizeInsertManyResult = <T extends { insertedIds?: Record<string, unkn
|
|
|
115
120
|
}
|
|
116
121
|
}
|
|
117
122
|
|
|
123
|
+
const normalizeFindOneAndUpdateOptions = (
|
|
124
|
+
options?: RealmCompatibleFindOneAndUpdateOptions
|
|
125
|
+
): FindOneAndUpdateOptions | undefined => {
|
|
126
|
+
if (!options) return undefined
|
|
127
|
+
|
|
128
|
+
const { returnNewDocument, ...rest } = options
|
|
129
|
+
if (typeof returnNewDocument !== 'boolean' || typeof rest.returnDocument !== 'undefined') {
|
|
130
|
+
return rest
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
...rest,
|
|
135
|
+
returnDocument: returnNewDocument ? 'after' : 'before'
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const buildAndQuery = (clauses: MongoFilter<Document>[]): MongoFilter<Document> =>
|
|
140
|
+
clauses.length ? { $and: clauses } : {}
|
|
141
|
+
|
|
118
142
|
const hasAtomicOperators = (data: Document) => Object.keys(data).some((key) => key.startsWith('$'))
|
|
119
143
|
|
|
120
144
|
const normalizeUpdatePayload = (data: Document) =>
|
|
@@ -389,7 +413,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
389
413
|
logService('findOne query', { collName, formattedQuery })
|
|
390
414
|
const safeQuery = normalizeQuery(formattedQuery)
|
|
391
415
|
logService('findOne normalizedQuery', { collName, safeQuery })
|
|
392
|
-
const result = await collection.findOne(
|
|
416
|
+
const result = await collection.findOne(buildAndQuery(safeQuery), resolvedOptions)
|
|
393
417
|
logDebug('findOne result', {
|
|
394
418
|
collection: collName,
|
|
395
419
|
result
|
|
@@ -456,7 +480,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
456
480
|
const formattedQuery = getFormattedQuery(filters, query, user)
|
|
457
481
|
|
|
458
482
|
// Retrieve the document to check permissions before deleting
|
|
459
|
-
const result = await collection.findOne(
|
|
483
|
+
const result = await collection.findOne(buildAndQuery(formattedQuery))
|
|
460
484
|
const winningRole = getWinningRole(result, user, roles)
|
|
461
485
|
|
|
462
486
|
logDebug('delete winningRole', {
|
|
@@ -481,7 +505,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
481
505
|
throw new Error('Delete not permitted')
|
|
482
506
|
}
|
|
483
507
|
|
|
484
|
-
const res = await collection.deleteOne(
|
|
508
|
+
const res = await collection.deleteOne(buildAndQuery(formattedQuery), options)
|
|
485
509
|
emitMongoEvent('deleteOne')
|
|
486
510
|
return res
|
|
487
511
|
}
|
|
@@ -589,12 +613,12 @@ const getOperators: GetOperatorsFunction = (
|
|
|
589
613
|
? normalizeQuery(formattedQuery)
|
|
590
614
|
: formattedQuery
|
|
591
615
|
|
|
592
|
-
const result = await collection.findOne(
|
|
616
|
+
const result = await collection.findOne(buildAndQuery(safeQuery))
|
|
593
617
|
|
|
594
618
|
if (!result) {
|
|
595
619
|
if (options?.upsert) {
|
|
596
620
|
const upsertResult = await collection.updateOne(
|
|
597
|
-
|
|
621
|
+
buildAndQuery(safeQuery),
|
|
598
622
|
normalizedData,
|
|
599
623
|
options
|
|
600
624
|
)
|
|
@@ -628,7 +652,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
628
652
|
if (!status || !areDocumentsEqual) {
|
|
629
653
|
throw new Error('Update not permitted')
|
|
630
654
|
}
|
|
631
|
-
const res = await collection.updateOne(
|
|
655
|
+
const res = await collection.updateOne(buildAndQuery(safeQuery), normalizedData, options)
|
|
632
656
|
emitMongoEvent('updateOne')
|
|
633
657
|
return res
|
|
634
658
|
}
|
|
@@ -653,9 +677,10 @@ const getOperators: GetOperatorsFunction = (
|
|
|
653
677
|
findOneAndUpdate: async (
|
|
654
678
|
query: MongoFilter<Document>,
|
|
655
679
|
data: UpdateFilter<Document> | Document[],
|
|
656
|
-
options?:
|
|
680
|
+
options?: RealmCompatibleFindOneAndUpdateOptions
|
|
657
681
|
) => {
|
|
658
682
|
try {
|
|
683
|
+
const normalizedOptions = normalizeFindOneAndUpdateOptions(options)
|
|
659
684
|
if (!run_as_system) {
|
|
660
685
|
checkDenyOperation(normalizedRules, collection.collectionName, CRUD_OPERATIONS.UPDATE)
|
|
661
686
|
const formattedQuery = getFormattedQuery(filters, query, user)
|
|
@@ -663,7 +688,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
663
688
|
? normalizeQuery(formattedQuery)
|
|
664
689
|
: formattedQuery
|
|
665
690
|
|
|
666
|
-
const result = await collection.findOne(
|
|
691
|
+
const result = await collection.findOne(buildAndQuery(safeQuery))
|
|
667
692
|
|
|
668
693
|
if (!result) {
|
|
669
694
|
throw new Error('Update not permitted')
|
|
@@ -678,7 +703,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
678
703
|
: getUpdatedPaths(normalizedData as Document)
|
|
679
704
|
const [docToCheck] = Array.isArray(normalizedData)
|
|
680
705
|
? await collection.aggregate([
|
|
681
|
-
{ $match:
|
|
706
|
+
{ $match: buildAndQuery(safeQuery) },
|
|
682
707
|
{ $limit: 1 },
|
|
683
708
|
...normalizedData
|
|
684
709
|
]).toArray()
|
|
@@ -702,9 +727,9 @@ const getOperators: GetOperatorsFunction = (
|
|
|
702
727
|
throw new Error('Update not permitted')
|
|
703
728
|
}
|
|
704
729
|
|
|
705
|
-
const updateResult =
|
|
706
|
-
? await collection.findOneAndUpdate(
|
|
707
|
-
: await collection.findOneAndUpdate(
|
|
730
|
+
const updateResult = normalizedOptions
|
|
731
|
+
? await collection.findOneAndUpdate(buildAndQuery(safeQuery), normalizedData, normalizedOptions)
|
|
732
|
+
: await collection.findOneAndUpdate(buildAndQuery(safeQuery), normalizedData)
|
|
708
733
|
if (!updateResult) {
|
|
709
734
|
emitMongoEvent('findOneAndUpdate')
|
|
710
735
|
return updateResult
|
|
@@ -729,8 +754,8 @@ const getOperators: GetOperatorsFunction = (
|
|
|
729
754
|
return sanitizedDoc
|
|
730
755
|
}
|
|
731
756
|
|
|
732
|
-
const updateResult =
|
|
733
|
-
? await collection.findOneAndUpdate(query, data,
|
|
757
|
+
const updateResult = normalizedOptions
|
|
758
|
+
? await collection.findOneAndUpdate(query, data, normalizedOptions)
|
|
734
759
|
: await collection.findOneAndUpdate(query, data)
|
|
735
760
|
emitMongoEvent('findOneAndUpdate')
|
|
736
761
|
return updateResult
|
|
@@ -59,6 +59,11 @@ export type GetOperatorsFunction = (
|
|
|
59
59
|
monitoringOrigin?: string
|
|
60
60
|
}
|
|
61
61
|
) => {
|
|
62
|
+
findOneAndUpdate: (
|
|
63
|
+
filter: MongoFilter<Document>,
|
|
64
|
+
update: UpdateFilter<Document> | Document[],
|
|
65
|
+
options?: RealmCompatibleFindOneAndUpdateOptions
|
|
66
|
+
) => Promise<Document | null>
|
|
62
67
|
findOne: (
|
|
63
68
|
filter?: MongoFilter<Document>,
|
|
64
69
|
projection?: Document,
|
|
@@ -71,11 +76,6 @@ export type GetOperatorsFunction = (
|
|
|
71
76
|
updateOne: (
|
|
72
77
|
...params: Parameters<Method<'updateOne'>>
|
|
73
78
|
) => ReturnType<Method<'updateOne'>>
|
|
74
|
-
findOneAndUpdate: (
|
|
75
|
-
filter: MongoFilter<Document>,
|
|
76
|
-
update: UpdateFilter<Document> | Document[],
|
|
77
|
-
options?: FindOneAndUpdateOptions
|
|
78
|
-
) => Promise<Document | null>
|
|
79
79
|
find: (
|
|
80
80
|
filter?: MongoFilter<Document>,
|
|
81
81
|
projection?: Document,
|
|
@@ -102,6 +102,10 @@ export type GetOperatorsFunction = (
|
|
|
102
102
|
) => ReturnType<Method<'deleteMany'>>
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
export type RealmCompatibleFindOneAndUpdateOptions = FindOneAndUpdateOptions & {
|
|
106
|
+
returnNewDocument?: boolean
|
|
107
|
+
}
|
|
108
|
+
|
|
105
109
|
|
|
106
110
|
export enum CRUD_OPERATIONS {
|
|
107
111
|
CREATE = "CREATE",
|