From 6d54ba4f7c078617b27e1c3f5e79973dde61c9e3 Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Mon, 25 Oct 2021 10:04:24 +0200 Subject: [PATCH 1/3] Return work from http-to-fetch branch --- packages/github-oauth/github_server.js | 64 +++++++++++++++----------- packages/github-oauth/package.js | 2 +- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/packages/github-oauth/github_server.js b/packages/github-oauth/github_server.js index e86940eb8d..3f11796a96 100644 --- a/packages/github-oauth/github_server.js +++ b/packages/github-oauth/github_server.js @@ -2,9 +2,12 @@ Github = {}; OAuth.registerService('github', 2, null, query => { - const accessToken = getAccessToken(query); - const identity = getIdentity(accessToken); - const emails = getEmails(accessToken); + const accessTokenCall = Meteor.wrapAsync(getAccessToken); + const accessToken = accessTokenCall(query); + const identityCall = Meteor.wrapAsync(getIdentity); + const identity = identityCall(accessToken); + const emailsCall = Meteor.wrapAsync(getEmails); + const emails = emailsCall(accessToken); const primaryEmail = emails.find(email => email.primary); return { @@ -13,7 +16,7 @@ OAuth.registerService('github', 2, null, query => { accessToken: OAuth.sealSecret(accessToken), email: identity.email || (primaryEmail && primaryEmail.email) || '', username: identity.login, - emails, + emails }, options: {profile: {name: identity.name}} }; @@ -24,60 +27,67 @@ let userAgent = "Meteor"; if (Meteor.release) userAgent += `/${Meteor.release}`; -const getAccessToken = query => { +const getAccessToken = async (query) => { const config = ServiceConfiguration.configurations.findOne({service: 'github'}); if (!config) throw new ServiceConfiguration.ConfigError(); let response; try { - response = HTTP.post( - "https://github.com/login/oauth/access_token", { + const content = new URLSearchParams({ + code: query.code, + redirect_uri: OAuth._redirectUri('github', config), + state: query.state + }); + const request = await fetch( + `https://github.com/login/oauth/access_token?${content.toString()}`, { + method: 'POST', headers: { Accept: 'application/json', - "User-Agent": userAgent - }, - params: { - code: query.code, - client_id: config.clientId, - client_secret: OAuth.openSecret(config.secret), - redirect_uri: OAuth._redirectUri('github', config), - state: query.state + "User-Agent": userAgent, + Authorization: `Basic ${config.clientId}:${OAuth.openSecret(config.secret)}` } }); + response = await request.json(); } catch (err) { throw Object.assign( new Error(`Failed to complete OAuth handshake with Github. ${err.message}`), { response: err.response }, ); } - if (response.data.error) { // if the http response was a json object with an error attribute - throw new Error(`Failed to complete OAuth handshake with GitHub. ${response.data.error}`); + if (response.error) { // if the http response was a json object with an error attribute + throw new Error(`Failed to complete OAuth handshake with GitHub. ${response.error}`); } else { - return response.data.access_token; + return response.access_token; } }; -const getIdentity = accessToken => { +const getIdentity = async (accessToken) => { try { - return HTTP.get( + const request = await fetch( "https://api.github.com/user", { - headers: {"User-Agent": userAgent, "Authorization": `token ${accessToken}`}, // http://developer.github.com/v3/#user-agent-required - }).data; + method: 'GET', + headers: { Accept: 'application/json', "User-Agent": userAgent, "Authorization": `token ${accessToken}`}, // http://developer.github.com/v3/#user-agent-required + }); + const response = await request.json(); + return response; } catch (err) { throw Object.assign( new Error(`Failed to fetch identity from Github. ${err.message}`), - { response: err.response }, + { response: err.response } ); } }; -const getEmails = accessToken => { +const getEmails = async (accessToken) => { try { - return HTTP.get( + const request = await fetch( "https://api.github.com/user/emails", { - headers: {"User-Agent": userAgent, "Authorization": `token ${accessToken}`}, // http://developer.github.com/v3/#user-agent-required - }).data; + method: 'GET', + headers: {"User-Agent": userAgent, Accept: 'application/json', "Authorization": `token ${accessToken}`}, // http://developer.github.com/v3/#user-agent-required + }); + const response = await request.json(); + return response; } catch (err) { return []; } diff --git a/packages/github-oauth/package.js b/packages/github-oauth/package.js index c9ca612e01..de78f9a598 100644 --- a/packages/github-oauth/package.js +++ b/packages/github-oauth/package.js @@ -7,7 +7,7 @@ Package.onUse(api => { api.use('ecmascript', ['client', 'server']); api.use('oauth2', ['client', 'server']); api.use('oauth', ['client', 'server']); - api.use('http@1.4.4 || 2.0.0', 'server'); + api.use('fetch', 'server'); api.use('random', 'client'); api.use('service-configuration', ['client', 'server']); From b234720d8da048f3b9ae7db05e47c2eb2b6baefb Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Wed, 27 Oct 2021 17:43:04 +0200 Subject: [PATCH 2/3] Fix GitHub OAuth --- History.md | 14 +++++ packages/github-oauth/github_server.js | 87 ++++++++++++++++---------- packages/github-oauth/package.js | 2 +- packages/oauth/oauth_server.js | 33 +++++----- 4 files changed, 86 insertions(+), 50 deletions(-) diff --git a/History.md b/History.md index 81771d0cb9..b63e454505 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,17 @@ +## v2.6, 2021-11- + +#### Highlights + +#### Breaking Changes + +#### Meteor Version Release + +#### Independent Releases + +* `github-oauth@1.3.2` + - Migrate from `http` to `fetch` + - Fix GitHub login params to adhere to changes in GitHub API + ## v2.5, 2021-10-21 #### Highlights diff --git a/packages/github-oauth/github_server.js b/packages/github-oauth/github_server.js index 3f11796a96..2991fdb0c9 100644 --- a/packages/github-oauth/github_server.js +++ b/packages/github-oauth/github_server.js @@ -1,14 +1,13 @@ Github = {}; -OAuth.registerService('github', 2, null, query => { - +OAuth.registerService('github', 2, null, (query) => { const accessTokenCall = Meteor.wrapAsync(getAccessToken); const accessToken = accessTokenCall(query); const identityCall = Meteor.wrapAsync(getIdentity); const identity = identityCall(accessToken); const emailsCall = Meteor.wrapAsync(getEmails); const emails = emailsCall(accessToken); - const primaryEmail = emails.find(email => email.primary); + const primaryEmail = emails.find((email) => email.primary); return { serviceData: { @@ -18,60 +17,77 @@ OAuth.registerService('github', 2, null, query => { username: identity.login, emails }, - options: {profile: {name: identity.name}} + options: { profile: { name: identity.name } } }; }); // http://developer.github.com/v3/#user-agent-required -let userAgent = "Meteor"; -if (Meteor.release) - userAgent += `/${Meteor.release}`; +let userAgent = 'Meteor'; +if (Meteor.release) userAgent += `/${Meteor.release}`; -const getAccessToken = async (query) => { - const config = ServiceConfiguration.configurations.findOne({service: 'github'}); - if (!config) - throw new ServiceConfiguration.ConfigError(); +const getAccessToken = async (query, callback) => { + const config = ServiceConfiguration.configurations.findOne({ + service: 'github' + }); + if (!config) throw new ServiceConfiguration.ConfigError(); let response; try { const content = new URLSearchParams({ + client_id: config.clientId, + client_secret: config.secret, code: query.code, - redirect_uri: OAuth._redirectUri('github', config), - state: query.state + redirect_uri: OAuth._redirectUri( + 'github', + config + ) }); const request = await fetch( - `https://github.com/login/oauth/access_token?${content.toString()}`, { + `https://github.com/login/oauth/access_token?${content.toString()}`, + { method: 'POST', headers: { Accept: 'application/json', - "User-Agent": userAgent, - Authorization: `Basic ${config.clientId}:${OAuth.openSecret(config.secret)}` + 'User-Agent': userAgent } - }); + } + ); response = await request.json(); } catch (err) { throw Object.assign( - new Error(`Failed to complete OAuth handshake with Github. ${err.message}`), - { response: err.response }, + new Error( + `Failed to complete OAuth handshake with Github. ${err.message}` + ), + { response: err.response } ); } - if (response.error) { // if the http response was a json object with an error attribute - throw new Error(`Failed to complete OAuth handshake with GitHub. ${response.error}`); + if (response.error) { + callback(response.error); + // if the http response was a json object with an error attribute + throw new Error( + `Failed to complete OAuth handshake with GitHub. ${response.error}` + ); } else { + callback(null, response.access_token); return response.access_token; } }; -const getIdentity = async (accessToken) => { +const getIdentity = async (accessToken, callback) => { try { - const request = await fetch( - "https://api.github.com/user", { - method: 'GET', - headers: { Accept: 'application/json', "User-Agent": userAgent, "Authorization": `token ${accessToken}`}, // http://developer.github.com/v3/#user-agent-required - }); + const request = await fetch('https://api.github.com/user', { + method: 'GET', + headers: { + Accept: 'application/json', + 'User-Agent': userAgent, + Authorization: `token ${accessToken}` + } // http://developer.github.com/v3/#user-agent-required + }); const response = await request.json(); + callback(null, response); return response; } catch (err) { + callback(err.message); throw Object.assign( new Error(`Failed to fetch identity from Github. ${err.message}`), { response: err.response } @@ -79,16 +95,21 @@ const getIdentity = async (accessToken) => { } }; -const getEmails = async (accessToken) => { +const getEmails = async (accessToken, callback) => { try { - const request = await fetch( - "https://api.github.com/user/emails", { - method: 'GET', - headers: {"User-Agent": userAgent, Accept: 'application/json', "Authorization": `token ${accessToken}`}, // http://developer.github.com/v3/#user-agent-required - }); + const request = await fetch('https://api.github.com/user/emails', { + method: 'GET', + headers: { + 'User-Agent': userAgent, + Accept: 'application/json', + Authorization: `token ${accessToken}` + } // http://developer.github.com/v3/#user-agent-required + }); const response = await request.json(); + callback(null, response); return response; } catch (err) { + callback(err.message, []); return []; } }; diff --git a/packages/github-oauth/package.js b/packages/github-oauth/package.js index de78f9a598..959a69a86b 100644 --- a/packages/github-oauth/package.js +++ b/packages/github-oauth/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'GitHub OAuth flow', - version: '1.3.1' + version: '1.3.2' }); Package.onUse(api => { diff --git a/packages/oauth/oauth_server.js b/packages/oauth/oauth_server.js index 9f650a102c..6d7b0cb578 100644 --- a/packages/oauth/oauth_server.js +++ b/packages/oauth/oauth_server.js @@ -13,22 +13,23 @@ const registeredServices = {}; OAuth._requestHandlers = {}; -// Register a handler for an OAuth service. The handler will be called -// when we get an incoming http request on /_oauth/{serviceName}. This -// handler should use that information to fetch data about the user -// logging in. -// -// @param name {String} e.g. "google", "facebook" -// @param version {Number} OAuth version (1 or 2) -// @param urls For OAuth1 only, specify the service's urls -// @param handleOauthRequest {Function(oauthBinding|query)} -// - (For OAuth1 only) oauthBinding {OAuth1Binding} bound to the appropriate provider -// - (For OAuth2 only) query {Object} parameters passed in query string -// - return value is: -// - {serviceData:, (optional options:)} where serviceData should end -// up in the user's services[name] field -// - `null` if the user declined to give permissions -// +/** +/* Register a handler for an OAuth service. The handler will be called +/* when we get an incoming http request on /_oauth/{serviceName}. This +/* handler should use that information to fetch data about the user +/* logging in. +/* +/* @param name {String} e.g. "google", "facebook" +/* @param version {Number} OAuth version (1 or 2) +/* @param urls For OAuth1 only, specify the service's urls +/* @param handleOauthRequest {Function(oauthBinding|query)} +/* - (For OAuth1 only) oauthBinding {OAuth1Binding} bound to the appropriate provider +/* - (For OAuth2 only) query {Object} parameters passed in query string +/* - return value is: +/* - {serviceData:, (optional options:)} where serviceData should end +/* up in the user's services[name] field +/* - `null` if the user declined to give permissions +*/ OAuth.registerService = (name, version, urls, handleOauthRequest) => { if (registeredServices[name]) throw new Error(`Already registered the ${name} OAuth service`); From e516cd9805e3f154f0a945c4f9cd98cb7d141243 Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Wed, 27 Oct 2021 17:58:20 +0200 Subject: [PATCH 3/3] Removed submodule docs/themes/meteor --- docs/themes/meteor | 1 - 1 file changed, 1 deletion(-) delete mode 160000 docs/themes/meteor diff --git a/docs/themes/meteor b/docs/themes/meteor deleted file mode 160000 index aab2ba93e9..0000000000 --- a/docs/themes/meteor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aab2ba93e905ff21300559ee7ff694319fd1015d