From fd0cc57895df131b2c02b348ed39b656107eafa1 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:25:25 -0300 Subject: [PATCH 01/14] updated collection.js in server --- packages/mongo/collection.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/mongo/collection.js b/packages/mongo/collection.js index 73d8590563..9554858544 100644 --- a/packages/mongo/collection.js +++ b/packages/mongo/collection.js @@ -1259,17 +1259,15 @@ function popCallbackFromArgs(args) { } -// XXX: IN Meteor 3.x this code was not working.... -// It throws an error when trying to call a method on the collection. -// the error normally is: -// TypeError: this[methodName] is not a function -// ASYNC_COLLECTION_METHODS.forEach(methodName => { -// const methodNameAsync = getAsyncMethodName(methodName); -// Mongo.Collection.prototype[methodNameAsync] = function(...args) { -// try { -// return Promise.resolve(this[methodName](...args)); -// } catch (error) { -// return Promise.reject(error); -// } -// }; -// }); +// this methods should not be available in the server +if (Meteor.isServer) { + for (const method of ASYNC_COLLECTION_METHODS) { + Mongo.Collection.prototype[method] = function () { + throw new Error( + `${method} is not avaible on the server. Please use ${getAsyncMethodName( + method + )}() instead.` + ); + }; + } +} From 5e081a0a220413c31ea436e84a8176482ce75bc5 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:25:33 -0300 Subject: [PATCH 02/14] Updated cursor in driver --- packages/mongo/mongo_driver.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index 0c2e021036..a1f629b71f 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -868,6 +868,12 @@ Cursor.prototype.countAsync = async function () { ); }; +Cursor.prototype.count = function () { + throw new Error( + "count() is not avaible on the server. Please use countAsync() instead." + ); +}; + [...ASYNC_CURSOR_METHODS, Symbol.iterator, Symbol.asyncIterator].forEach(methodName => { // count is handled specially since we don't want to create a cursor. // it is still included in ASYNC_CURSOR_METHODS because we still want an async version of it to exist. From a9decc9a0df283156a2d014cfe0203cae0b06e47 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:27:04 -0300 Subject: [PATCH 03/14] chore: added CLIENT_ONLY_METHODS constant --- packages/minimongo/constants.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/minimongo/constants.js b/packages/minimongo/constants.js index fc4c5b9225..3795a8dc68 100644 --- a/packages/minimongo/constants.js +++ b/packages/minimongo/constants.js @@ -18,3 +18,5 @@ export const ASYNC_COLLECTION_METHODS = [ ]; export const ASYNC_CURSOR_METHODS = ['count', 'fetch', 'forEach', 'map']; + +export const CLIENT_ONLY_METHODS = ["findOne", "insert", "remove", "update", "upsert"]; From c47899b72b7068955b80630edf7dea2d06a08743 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:27:14 -0300 Subject: [PATCH 04/14] fix: removed update from server --- packages/mongo/collection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mongo/collection.js b/packages/mongo/collection.js index 9554858544..9f6757872c 100644 --- a/packages/mongo/collection.js +++ b/packages/mongo/collection.js @@ -959,7 +959,7 @@ Object.assign(Mongo.Collection.prototype, { // If the user provided a callback and the collection implements this // operation asynchronously, then queryRet will be undefined, and the // result will be returned through the callback instead. - return this._collection.updateAsync( + return this._collection.update( selector, modifier, options, From 6d629d3932bba710734564d235b25f2661cc2768 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:27:30 -0300 Subject: [PATCH 05/14] chore: added CLIENT_ONLY_METHODS constant in driver --- packages/mongo/mongo_driver.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index a1f629b71f..8fc3644b86 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -17,6 +17,7 @@ var MongoDB = NpmModuleMongodb; import { DocFetcher } from "./doc_fetcher.js"; import { ASYNC_CURSOR_METHODS, + CLIENT_ONLY_METHODS, getAsyncMethodName } from "meteor/minimongo/constants"; import { Meteor } from "meteor/meteor"; @@ -359,6 +360,7 @@ MongoConnection.prototype.insertAsync = async function (collection_name, documen }); }; + // Cause queries that may be affected by the selector to poll in this write // fence. MongoConnection.prototype._refresh = async function (collectionName, selector) { @@ -791,6 +793,17 @@ MongoConnection.prototype.dropIndexAsync = async function (collectionName, index var indexName = await collection.dropIndex(index); }; + +CLIENT_ONLY_METHODS.forEach(function (m) { + MongoConnection.prototype[m] = function () { + throw new Error( + `${m} + is not available on the server. Please use ${getAsyncMethodName( + m + )}() instead.` + ); + }; +}); + // CURSORS // There are several classes which relate to cursors: From e4602e15474240c5400624f4752647f178e16bb0 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:27:39 -0300 Subject: [PATCH 06/14] chore: added CLIENT_ONLY_METHODS constant in remote collection --- packages/mongo/remote_collection_driver.js | 36 +++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/mongo/remote_collection_driver.js b/packages/mongo/remote_collection_driver.js index c3954a9cf9..7a58b3841c 100644 --- a/packages/mongo/remote_collection_driver.js +++ b/packages/mongo/remote_collection_driver.js @@ -1,6 +1,7 @@ import { ASYNC_COLLECTION_METHODS, - getAsyncMethodName + getAsyncMethodName, + CLIENT_ONLY_METHODS } from "meteor/minimongo/constants"; MongoInternals.RemoteCollectionDriver = function ( @@ -30,22 +31,29 @@ Object.assign(MongoInternals.RemoteCollectionDriver.prototype, { open: function (name) { var self = this; var ret = {}; - REMOTE_COLLECTION_METHODS.forEach( - function (m) { - ret[m] = _.bind(self.mongo[m], self.mongo, name); + REMOTE_COLLECTION_METHODS.forEach(function (m) { + ret[m] = _.bind(self.mongo[m], self.mongo, name); - if (!ASYNC_COLLECTION_METHODS.includes(m)) return; - const asyncMethodName = getAsyncMethodName(m); - ret[asyncMethodName] = function (...args) { - try { - return Promise.resolve(ret[m](...args)); - } catch (error) { - return Promise.reject(error); - } + if (!ASYNC_COLLECTION_METHODS.includes(m)) return; + const asyncMethodName = getAsyncMethodName(m); + ret[asyncMethodName] = function (...args) { + try { + return Promise.resolve(ret[m](...args)); + } catch (error) { + return Promise.reject(error); } - }); + }; + }); + + CLIENT_ONLY_METHODS.forEach(function (m) { + ret[m] = _.bind(self.mongo[m], self.mongo, name); + + ret[m] = function (...args) { + throw new Error(`${m} is not available on the server-side. please use ${getAsyncMethodName(m)}()`); + }; + }); return ret; - } + }, }); // Create the singleton RemoteCollectionDriver only on demand, so we From 5967735679524ddffa8cb23b9b1ade5a18642849 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:28:31 -0300 Subject: [PATCH 07/14] added more clear messages in mongo methods [sc-2948] From 237528af89668cea7014e939db03fa275d5fccb8 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:18:18 -0300 Subject: [PATCH 08/14] chore: removed unsed code in collection --- packages/mongo/collection.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/packages/mongo/collection.js b/packages/mongo/collection.js index 9f6757872c..6d2199965c 100644 --- a/packages/mongo/collection.js +++ b/packages/mongo/collection.js @@ -1258,16 +1258,3 @@ function popCallbackFromArgs(args) { } } - -// this methods should not be available in the server -if (Meteor.isServer) { - for (const method of ASYNC_COLLECTION_METHODS) { - Mongo.Collection.prototype[method] = function () { - throw new Error( - `${method} is not avaible on the server. Please use ${getAsyncMethodName( - method - )}() instead.` - ); - }; - } -} From df3138043232cb6d059dc5e2e6421a4e9b207173 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:18:28 -0300 Subject: [PATCH 09/14] updated error in collection driver --- packages/mongo/remote_collection_driver.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/mongo/remote_collection_driver.js b/packages/mongo/remote_collection_driver.js index 7a58b3841c..36a8a30910 100644 --- a/packages/mongo/remote_collection_driver.js +++ b/packages/mongo/remote_collection_driver.js @@ -49,7 +49,11 @@ Object.assign(MongoInternals.RemoteCollectionDriver.prototype, { ret[m] = _.bind(self.mongo[m], self.mongo, name); ret[m] = function (...args) { - throw new Error(`${m} is not available on the server-side. please use ${getAsyncMethodName(m)}()`); + throw new Error( + `${m} + is not available on the server. Please use ${getAsyncMethodName( + m + )}() instead.` + ); }; }); return ret; From 2e7f6a611e3f8deb84e33f68e363c7079caa4997 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:18:23 -0300 Subject: [PATCH 10/14] tests: solved 2fa tests --- packages/accounts-2fa/2fa-server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/accounts-2fa/2fa-server.js b/packages/accounts-2fa/2fa-server.js index 45f701a2ee..188d829489 100644 --- a/packages/accounts-2fa/2fa-server.js +++ b/packages/accounts-2fa/2fa-server.js @@ -59,7 +59,7 @@ Meteor.methods({ }); const svg = new QRCode(uri).svg(); - await Meteor.users.update( + await Meteor.users.updateAsync( { _id: user._id }, { $set: { @@ -94,7 +94,7 @@ Meteor.methods({ Accounts._handleError('Invalid 2FA code', true, 'invalid-2fa-code'); } - await Meteor.users.update( + await Meteor.users.updateAsync( { _id: user._id }, { $set: { @@ -113,7 +113,7 @@ Meteor.methods({ throw new Meteor.Error(400, 'No user logged in.'); } - await Meteor.users.update( + await Meteor.users.updateAsync( { _id: userId }, { $unset: { From 7aba69763d58f0f80181865e9172a102c81d3036 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:18:41 -0300 Subject: [PATCH 11/14] tests: solved email tests --- packages/accounts-password/email_tests.js | 72 +++++++++++++---------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/packages/accounts-password/email_tests.js b/packages/accounts-password/email_tests.js index afcdef3905..6c78320c58 100644 --- a/packages/accounts-password/email_tests.js +++ b/packages/accounts-password/email_tests.js @@ -49,9 +49,9 @@ testAsyncMulti("accounts emails - reset password flow", [ })); }, function (test, expect) { - Meteor.logout(expect((error) => { + Meteor.logout(expect(async (error) => { test.equal(error, undefined); - test.equal(Meteor.user(), null); + test.equal(await Meteor.user(), null); })); }, function (test, expect) { @@ -62,9 +62,9 @@ testAsyncMulti("accounts emails - reset password flow", [ })); }, function (test, expect) { - Meteor.logout(expect((error) => { + Meteor.logout(expect(async (error) => { test.equal(error, undefined); - test.equal(Meteor.user(), null); + test.equal(await Meteor.user(), null); })); } ]); @@ -168,40 +168,45 @@ testAsyncMulti("accounts emails - verify email flow", [ {email: this.email, password: 'foobar'}, loggedIn(test, expect)); }, - function (test, expect) { - test.equal(Meteor.user().emails.length, 1); - test.equal(Meteor.user().emails[0].address, this.email); - test.isFalse(Meteor.user().emails[0].verified); + async function (test, expect) { + const u = await Meteor.user(); + test.equal(u.emails.length, 1); + test.equal(u.emails[0].address, this.email); + test.isFalse(u.emails[0].verified); // We should NOT be publishing things like verification tokens! - test.isFalse(Object.prototype.hasOwnProperty.call(Meteor.user(), 'services')); + test.isFalse(Object.prototype.hasOwnProperty.call(u, 'services')); }, function (test, expect) { getVerifyEmailToken(this.email, test, expect); }, function (test, expect) { // Log out, to test that verifyEmail logs us back in. - Meteor.logout(expect((error) => { + Meteor.logout(expect(async (error) => { test.equal(error, undefined); - test.equal(Meteor.user(), null); + test.equal(await Meteor.user(), null); })); }, function (test, expect) { Accounts.verifyEmail(verifyEmailToken, loggedIn(test, expect)); }, - function (test, expect) { - test.equal(Meteor.user().emails.length, 1); - test.equal(Meteor.user().emails[0].address, this.email); - test.isTrue(Meteor.user().emails[0].verified); + async function (test, expect) { + const u = await Meteor.user(); + + test.equal(u.emails.length, 1); + test.equal(u.emails[0].address, this.email); + test.isTrue(u.emails[0].verified); }, function (test, expect) { Accounts.connection.call( "addEmailForTestAndVerify", this.anotherEmail, - expect((error, result) => { + expect(async (error, result) => { + const u = await Meteor.user(); + test.isFalse(error); - test.equal(Meteor.user().emails.length, 2); - test.equal(Meteor.user().emails[1].address, this.anotherEmail); - test.isFalse(Meteor.user().emails[1].verified); + test.equal(u.emails.length, 2); + test.equal(u.emails[1].address, this.anotherEmail); + test.isFalse(u.emails[1].verified); })); }, function (test, expect) { @@ -210,9 +215,9 @@ testAsyncMulti("accounts emails - verify email flow", [ function (test, expect) { // Log out, to test that verifyEmail logs us back in. (And if we don't // do that, waitUntilLoggedIn won't be able to prevent race conditions.) - Meteor.logout(expect((error) => { + Meteor.logout(expect(async (error) => { test.equal(error, undefined); - test.equal(Meteor.user(), null); + test.equal(await Meteor.user(), null); })); }, function (test, expect) { @@ -226,11 +231,12 @@ testAsyncMulti("accounts emails - verify email flow", [ function (test, expect) { Accounts.connection.call( "addEmailForTestAndVerify", this.anotherEmailCaps, - expect((error, result) => { + expect(async (error, result) => { + const u = await Meteor.user(); test.isFalse(error); - test.equal(Meteor.user().emails.length, 3); - test.equal(Meteor.user().emails[2].address, this.anotherEmailCaps); - test.isFalse(Meteor.user().emails[2].verified); + test.equal(u.emails.length, 3); + test.equal(u.emails[2].address, this.anotherEmailCaps); + test.isFalse(u.emails[2].verified); })); }, function (test, expect) { @@ -239,23 +245,25 @@ testAsyncMulti("accounts emails - verify email flow", [ function (test, expect) { // Log out, to test that verifyEmail logs us back in. (And if we don't // do that, waitUntilLoggedIn won't be able to prevent race conditions.) - Meteor.logout(expect((error) => { + Meteor.logout(expect(async (error) => { test.equal(error, undefined); - test.equal(Meteor.user(), null); + test.equal(await Meteor.user(), null); })); }, function (test, expect) { Accounts.verifyEmail(verifyEmailToken, loggedIn(test, expect)); }, - function (test, expect) { - test.equal(Meteor.user().emails[2].address, this.anotherEmailCaps); - test.isTrue(Meteor.user().emails[2].verified); + async function (test, expect) { + const u = await Meteor.user(); + + test.equal(u.emails[2].address, this.anotherEmailCaps); + test.isTrue(u.emails[2].verified); }, function (test, expect) { - Meteor.logout(expect((error) => { + Meteor.logout(expect(async (error) => { test.equal(error, undefined); - test.equal(Meteor.user(), null); + test.equal(await Meteor.user(), null); })); } ]); From 855f48ea28ef242da53a794614aabb3d5d102451 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:18:49 -0300 Subject: [PATCH 12/14] tests: solved email tests_setup --- packages/accounts-password/email_tests_setup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/accounts-password/email_tests_setup.js b/packages/accounts-password/email_tests_setup.js index e06fbfa789..fe393fb663 100644 --- a/packages/accounts-password/email_tests_setup.js +++ b/packages/accounts-password/email_tests_setup.js @@ -44,7 +44,7 @@ Meteor.methods( addEmailForTestAndVerify: async email => { check(email, String); - await Meteor.users.update( + await Meteor.users.updateAsync( { _id: Accounts.userId() }, { $push: { emails: { address: email, verified: false } } }); await Accounts.sendVerificationEmail(Accounts.userId(), email); From 1a7ee29785b6352cf9f36e5acb8fb3e0236da359 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:18:56 -0300 Subject: [PATCH 13/14] tests: solved password tests --- packages/accounts-password/password_tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/accounts-password/password_tests.js b/packages/accounts-password/password_tests.js index 5cf096a9da..6d80c80552 100644 --- a/packages/accounts-password/password_tests.js +++ b/packages/accounts-password/password_tests.js @@ -700,8 +700,8 @@ if (Meteor.isClient) (() => { // test Meteor.user(). This test properly belongs in // accounts-base/accounts_tests.js, but this is where the tests that // actually log in are. - function (test, expect) { - const clientUser = Meteor.user(); + async function (test, expect) { + const clientUser = await Meteor.user(); Accounts.connection.call('testMeteorUser', expect((err, result) => { test.equal(result._id, clientUser._id); test.equal(result.username, clientUser.username); From 35eea18311866fe9359786365572cd451e06bc12 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:24:13 -0300 Subject: [PATCH 14/14] tests: updated rpassword_test_setup --- packages/accounts-password/password_tests_setup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/accounts-password/password_tests_setup.js b/packages/accounts-password/password_tests_setup.js index 80964c72fd..48a34c8766 100644 --- a/packages/accounts-password/password_tests_setup.js +++ b/packages/accounts-password/password_tests_setup.js @@ -128,7 +128,7 @@ Meteor.methods( if (!this.userId) throw new Error("Not logged in!"); await Meteor .users - .update(this.userId, { $unset: { profile: 1, username: 1 } }); + .updateAsync(this.userId, { $unset: { profile: 1, username: 1 } }); }, expireTokens: @@ -137,6 +137,6 @@ Meteor.methods( }, removeUser: - async username => await Meteor.users.remove({ "username": username }), + async username => await Meteor.users.removeAsync({ "username": username }), } );