From 2823b97cee0082aae7bc1e9bce1d1fd40474f4dc Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 15:59:25 -0300 Subject: [PATCH 1/9] chore: ensureConfigured is now async --- packages/oauth/oauth_server.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/oauth/oauth_server.js b/packages/oauth/oauth_server.js index 7c705d07fd..ebf9873fcc 100644 --- a/packages/oauth/oauth_server.js +++ b/packages/oauth/oauth_server.js @@ -156,7 +156,7 @@ const middleware = async (req, res, next) => { throw new Error(`Unexpected OAuth service ${serviceName}`); // Make sure we're configured - ensureConfigured(serviceName); + await ensureConfigured(serviceName); const handler = OAuth._requestHandlers[service.version]; if (!handler) @@ -167,7 +167,6 @@ const middleware = async (req, res, next) => { } else { requestData = req.body; } - await handler(service, requestData, res); } catch (err) { // if we got thrown an error, save it off, it will get passed to @@ -179,7 +178,7 @@ const middleware = async (req, res, next) => { // style the error or react to it in any way. if (requestData?.state && err instanceof Error) { try { // catch any exceptions to avoid crashing runner - OAuth._storePendingCredential(OAuth._credentialTokenFromQuery(requestData), err); + await OAuth._storePendingCredential(OAuth._credentialTokenFromQuery(requestData), err); } catch (err) { // Ignore the error and just give up. If we failed to store the // error, then the login will just fail with a generic error. @@ -193,7 +192,7 @@ const middleware = async (req, res, next) => { // think to check server logs (we hope?) // Catch errors because any exception here will crash the runner. try { - OAuth._endOfLoginResponse(res, { + await OAuth._endOfLoginResponse(res, { query: requestData, loginStyle: OAuth._loginStyleFromQuery(requestData), error: err @@ -237,11 +236,14 @@ const oauthServiceName = req => { }; // Make sure we're configured -const ensureConfigured = serviceName => { - if (!ServiceConfiguration.configurations.findOne({service: serviceName})) { - throw new ServiceConfiguration.ConfigError(); - } -}; +const ensureConfigured = + async serviceName => { + const config = + await ServiceConfiguration.configurations.findOne({ service: serviceName }) + if (!config) { + throw new ServiceConfiguration.ConfigError(); + } + }; const isSafe = value => { // This matches strings generated by `Random.secret` and From 37e0fe55f423776ab37de7085383d1683c009f31 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 15:59:48 -0300 Subject: [PATCH 2/9] chore: _cleanStaleResults is now async --- packages/oauth/pending_credentials.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/oauth/pending_credentials.js b/packages/oauth/pending_credentials.js index 71623acc31..bb68cb0931 100644 --- a/packages/oauth/pending_credentials.js +++ b/packages/oauth/pending_credentials.js @@ -16,18 +16,22 @@ OAuth._pendingCredentials = new Mongo.Collection( _preventAutopublish: true }); -OAuth._pendingCredentials.createIndex('key', { unique: true }); -OAuth._pendingCredentials.createIndex('credentialSecret'); -OAuth._pendingCredentials.createIndex('createdAt'); +// TODO[FIBERS]: I Need TLA +async function init() { + await OAuth._pendingCredentials.createIndex('key', { unique: true }); + await OAuth._pendingCredentials.createIndex('credentialSecret'); + await OAuth._pendingCredentials.createIndex('createdAt'); +} +init() // Periodically clear old entries that were never retrieved -const _cleanStaleResults = () => { +const _cleanStaleResults = async () => { // Remove credentials older than 1 minute const timeCutoff = new Date(); timeCutoff.setMinutes(timeCutoff.getMinutes() - 1); - OAuth._pendingCredentials.remove({ createdAt: { $lt: timeCutoff } }); + await OAuth._pendingCredentials.remove({ createdAt: { $lt: timeCutoff } }); }; const _cleanupHandle = Meteor.setInterval(_cleanStaleResults, 60 * 1000); @@ -78,7 +82,6 @@ OAuth._retrievePendingCredential = key, credentialSecret, }); - if (pendingCredential) { await OAuth._pendingCredentials.remove({ _id: pendingCredential._id }); if (pendingCredential.credential.error) From 8bee8ea850096c636c377395229647c09af5f7c3 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:00:22 -0300 Subject: [PATCH 3/9] chore: _storeRequestToken and _retrieveRequestToken are now async --- packages/oauth1/oauth1_pending_request_tokens.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/oauth1/oauth1_pending_request_tokens.js b/packages/oauth1/oauth1_pending_request_tokens.js index db23f400fa..06b11feb52 100644 --- a/packages/oauth1/oauth1_pending_request_tokens.js +++ b/packages/oauth1/oauth1_pending_request_tokens.js @@ -47,13 +47,13 @@ const _cleanupHandle = Meteor.setInterval(_cleanStaleResults, 60 * 1000); // @param requestToken {string} // @param requestTokenSecret {string} // -OAuth._storeRequestToken = (key, requestToken, requestTokenSecret) => { +OAuth._storeRequestToken = async (key, requestToken, requestTokenSecret) => { check(key, String); // We do an upsert here instead of an insert in case the user happens // to somehow send the same `state` parameter twice during an OAuth // login; we don't want a duplicate key error. - OAuth._pendingRequestTokens.upsert({ + await OAuth._pendingRequestTokens.upsert({ key, }, { key, @@ -69,12 +69,12 @@ OAuth._storeRequestToken = (key, requestToken, requestTokenSecret) => { // // @param key {string} // -OAuth._retrieveRequestToken = key => { +OAuth._retrieveRequestToken = async key => { check(key, String); - const pendingRequestToken = OAuth._pendingRequestTokens.findOne({ key: key }); + const pendingRequestToken = await OAuth._pendingRequestTokens.findOne({ key: key }); if (pendingRequestToken) { - OAuth._pendingRequestTokens.remove({ _id: pendingRequestToken._id }); + await OAuth._pendingRequestTokens.remove({ _id: pendingRequestToken._id }); return { requestToken: OAuth.openSecret(pendingRequestToken.requestToken), requestTokenSecret: OAuth.openSecret( From 8f58e55c91f4560aa3997761c8b294ce878d7e8f Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:00:46 -0300 Subject: [PATCH 4/9] chore: added missing awaits in oauth1_server.js --- packages/oauth1/oauth1_server.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/oauth1/oauth1_server.js b/packages/oauth1/oauth1_server.js index d0c8e3732a..a8ffb501ef 100644 --- a/packages/oauth1/oauth1_server.js +++ b/packages/oauth1/oauth1_server.js @@ -26,7 +26,7 @@ OAuth._queryParamsWithAuthTokenUrl = (authUrl, oauthBinding, params = {}, whitel // connect middleware OAuth._requestHandlers['1'] = async (service, query, res) => { - const config = ServiceConfiguration.configurations.findOne({service: service.serviceName}); + const config = await ServiceConfiguration.configurations.findOne({service: service.serviceName}); if (! config) { throw new ServiceConfiguration.ConfigError(service.serviceName); } @@ -48,7 +48,7 @@ OAuth._requestHandlers['1'] = async (service, query, res) => { await oauthBinding.prepareRequestToken(callbackUrl); // Keep track of request token so we can verify it on the next step - OAuth._storeRequestToken( + await OAuth._storeRequestToken( OAuth._credentialTokenFromQuery(query), oauthBinding.requestToken, oauthBinding.requestTokenSecret); @@ -76,7 +76,7 @@ OAuth._requestHandlers['1'] = async (service, query, res) => { // and close the window to allow the login handler to proceed // Get the user's request token so we can verify it and clear it - const requestTokenInfo = OAuth._retrieveRequestToken( + const requestTokenInfo = await OAuth._retrieveRequestToken( OAuth._credentialTokenFromQuery(query)); if (! requestTokenInfo) { @@ -102,7 +102,7 @@ OAuth._requestHandlers['1'] = async (service, query, res) => { // Store the login result so it can be retrieved in another // browser tab by the result handler - OAuth._storePendingCredential(credentialToken, { + await OAuth._storePendingCredential(credentialToken, { serviceName: service.serviceName, serviceData: oauthResult.serviceData, options: oauthResult.options @@ -111,6 +111,6 @@ OAuth._requestHandlers['1'] = async (service, query, res) => { // Either close the window, redirect, or render nothing // if all else fails - OAuth._renderOauthResults(res, query, credentialSecret); + await OAuth._renderOauthResults(res, query, credentialSecret); } }; From a1bc475cb70ac1959dea5e702dc7d72173c532e0 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:01:03 -0300 Subject: [PATCH 5/9] tests: solved pending credentials --- packages/oauth1/oauth1_tests.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/oauth1/oauth1_tests.js b/packages/oauth1/oauth1_tests.js index d4b283a97a..7b72cc4471 100644 --- a/packages/oauth1/oauth1_tests.js +++ b/packages/oauth1/oauth1_tests.js @@ -23,7 +23,7 @@ const testPendingCredential = async (test, method) => { this.accessTokenSecret = twitterfooAccessTokenSecret; }; - ServiceConfiguration.configurations.insert({service: serviceName}); + await ServiceConfiguration.configurations.insert({service: serviceName}); try { // register a fake login service @@ -40,7 +40,7 @@ const testPendingCredential = async (test, method) => { })); // simulate logging in using twitterfoo - OAuth._storeRequestToken(credentialToken, twitterfooAccessToken); + await OAuth._storeRequestToken(credentialToken, twitterfooAccessToken); const req = { method, @@ -73,9 +73,8 @@ const testPendingCredential = async (test, method) => { }; await OAuthTest.middleware(req, res); const credentialSecret = respData; - // Test that the result for the token is available - let result = OAuth._retrievePendingCredential(credentialToken, + let result = await OAuth._retrievePendingCredential(credentialToken, credentialSecret); const serviceData = OAuth.openSecrets(result.serviceData); test.equal(result.serviceName, serviceName); @@ -86,7 +85,7 @@ const testPendingCredential = async (test, method) => { test.equal(result.options.option1, twitterOption1); // Test that pending credential is removed after being retrieved - result = OAuth._retrievePendingCredential(credentialToken); + result = await OAuth._retrievePendingCredential(credentialToken); test.isUndefined(result); } finally { From f9fe5a4debdb9b131503cea3f0d8a6b27a33a7a9 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:07:37 -0300 Subject: [PATCH 6/9] tests: solved duplicate key for request token --- packages/oauth1/oauth1_tests.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/oauth1/oauth1_tests.js b/packages/oauth1/oauth1_tests.js index 7b72cc4471..081155f568 100644 --- a/packages/oauth1/oauth1_tests.js +++ b/packages/oauth1/oauth1_tests.js @@ -109,15 +109,15 @@ Tinytest.addAsync("oauth1 - pendingCredential is stored and can be retrieved (wi } }); -Tinytest.add("oauth1 - duplicate key for request token", test => { +Tinytest.addAsync("oauth1 - duplicate key for request token", async test => { const key = Random.id(); const token = Random.id(); const secret = Random.id(); - OAuth._storeRequestToken(key, token, secret); + await OAuth._storeRequestToken(key, token, secret); const newToken = Random.id(); const newSecret = Random.id(); - OAuth._storeRequestToken(key, newToken, newSecret); - const result = OAuth._retrieveRequestToken(key); + await OAuth._storeRequestToken(key, newToken, newSecret); + const result = await OAuth._retrieveRequestToken(key); test.equal(result.requestToken, newToken); test.equal(result.requestTokenSecret, newSecret); }); From 2708571624925cb666c59128e2b7a53591322df4 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:08:36 -0300 Subject: [PATCH 7/9] tests: solved undefined key for request token --- packages/oauth1/oauth1_tests.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/oauth1/oauth1_tests.js b/packages/oauth1/oauth1_tests.js index 081155f568..bc87f6a2af 100644 --- a/packages/oauth1/oauth1_tests.js +++ b/packages/oauth1/oauth1_tests.js @@ -122,11 +122,11 @@ Tinytest.addAsync("oauth1 - duplicate key for request token", async test => { test.equal(result.requestTokenSecret, newSecret); }); -Tinytest.add("oauth1 - null, undefined key for request token", test => { +Tinytest.addAsync("oauth1 - null, undefined key for request token", async test => { const token = Random.id(); const secret = Random.id(); - test.throws(() => OAuth._storeRequestToken(null, token, secret)); - test.throws(() => OAuth._storeRequestToken(undefined, token, secret)); + await test.throwsAsync(() => OAuth._storeRequestToken(null, token, secret)); + await test.throwsAsync(() => OAuth._storeRequestToken(undefined, token, secret)); }); Tinytest.add("oauth1 - signature is built correctly", test => { From 0a77a3788fa810c2a367fee3170b937b7c9d0336 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:34:18 -0300 Subject: [PATCH 8/9] docs: updated oauth async methods --- docs/history.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/history.md b/docs/history.md index 1664baa212..b6c094f952 100644 --- a/docs/history.md +++ b/docs/history.md @@ -34,6 +34,10 @@ - `OAuth.renderEndOfLoginResponse` - `OAuth._storePendingCredential` - `OAuth._retrievePendingCredential` + - `ensureConfigured` + - `_cleanStaleResults` + + #### Internal API changes From bd5c1af9ccf3ec60f4e50457aecdcadf58a28331 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Wed, 28 Dec 2022 16:37:03 -0300 Subject: [PATCH 9/9] docs: added oauth1 in changelog --- docs/history.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/history.md b/docs/history.md index b6c094f952..4a14171e9d 100644 --- a/docs/history.md +++ b/docs/history.md @@ -28,7 +28,7 @@ * `oauth`: - `_endOfPopupResponseTemplate` and `_endOfRedirectResponseTemplate` are no longer a property but now a function that returns a promise of the same value as before - - the following methods are now async: + - the following server methods are now async: - `OAuth._renderOauthResults` - `OAuth._endOfLoginResponse` - `OAuth.renderEndOfLoginResponse` @@ -37,6 +37,10 @@ - `ensureConfigured` - `_cleanStaleResults` +* `oauth1`: + - the following server methods are now async: + - `OAuth._storeRequestToken` + - `OAuth._retrieveRequestToken` #### Internal API changes