mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Support Google Sign-In in google-oauth package. (#8549)
* Support Google Sign-In in google-oauth package. Addresses #8253. * Use Meteor.startup instead of listening for deviceready event. * Fix mobile-config.js typo. * Bump accounts-google and google-oauth package versions. I'm only bumping the patch versions, even though the recent changes to these packages may seem significant, for two reasons: 1. Bumping the minor versions would force Meteor 1.4.3 developers to upgrade to Meteor 1.4.4 if they wanted to use these changes. 2. The accounts-google and google-oauth packages without these changes will stop working completely in two weeks, which is much worse than the risks of upgrading.
This commit is contained in:
@@ -8,6 +8,15 @@ if (Meteor.isClient) {
|
||||
options = null;
|
||||
}
|
||||
|
||||
if (Meteor.isCordova &&
|
||||
Google.signIn) {
|
||||
// After 20 April 2017, Google OAuth login will no longer work from
|
||||
// a WebView, so Cordova apps must use Google Sign-In instead.
|
||||
// https://github.com/meteor/meteor/issues/8253
|
||||
Google.signIn(options, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use Google's domain-specific login page if we want to restrict creation to
|
||||
// a particular email domain. (Don't use it if restrictCreationByEmailDomain
|
||||
// is a function.) Note that all this does is change Google's UI ---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: "Login service for Google accounts",
|
||||
version: "1.1.1"
|
||||
version: "1.1.2"
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Google = {};
|
||||
var Google = require("./namespace.js");
|
||||
|
||||
// Request Google credentials for the user
|
||||
// @param options {optional}
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
Google = {};
|
||||
var Google = require("./namespace.js");
|
||||
var Accounts = require("meteor/accounts-base").Accounts;
|
||||
|
||||
// https://developers.google.com/accounts/docs/OAuth2Login#userinfocall
|
||||
Google.whitelistedFields = ['id', 'email', 'verified_email', 'name', 'given_name',
|
||||
'family_name', 'picture', 'locale', 'timezone', 'gender'];
|
||||
|
||||
Accounts.registerLoginHandler(function (request) {
|
||||
if (request.googleSignIn !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
var res = HTTP.get(
|
||||
"https://www.googleapis.com/oauth2/v3/tokeninfo",
|
||||
{ headers: { "User-Agent": "Meteor/1.0" },
|
||||
params: { id_token: request.idToken }}
|
||||
);
|
||||
|
||||
if (res.error) {
|
||||
throw res.error;
|
||||
}
|
||||
|
||||
if (res.statusCode === 200 &&
|
||||
res.data.sub === request.userId) {
|
||||
return Accounts.updateOrCreateUserFromExternalService("google", {
|
||||
id: request.userId,
|
||||
idToken: request.idToken,
|
||||
accessToken: request.accessToken,
|
||||
email: request.email,
|
||||
picture: request.imageUrl
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
OAuth.registerService('google', 2, null, function(query) {
|
||||
|
||||
var response = getTokens(query);
|
||||
var expiresAt = (+new Date) + (1000 * parseInt(response.expiresIn, 10));
|
||||
var accessToken = response.accessToken;
|
||||
|
||||
84
packages/google-oauth/google_sign-in.js
Normal file
84
packages/google-oauth/google_sign-in.js
Normal file
@@ -0,0 +1,84 @@
|
||||
var Google = require("./namespace.js");
|
||||
|
||||
var gplusPromise = new Promise(function (resolve, reject) {
|
||||
if (! Meteor.isCordova) {
|
||||
reject(new Error("plugins.googleplus requires Cordova"));
|
||||
return;
|
||||
}
|
||||
|
||||
Meteor.startup(function () {
|
||||
var plugins = global.plugins;
|
||||
var gplus = plugins && plugins.googleplus;
|
||||
if (gplus) {
|
||||
resolve(gplus);
|
||||
} else {
|
||||
reject(new Error("plugins.googleplus not defined"));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function tolerateUnhandledRejection() {}
|
||||
gplusPromise.catch(tolerateUnhandledRejection);
|
||||
|
||||
// After 20 April 2017, Google OAuth login will no longer work from a
|
||||
// WebView, so Cordova apps must use Google Sign-In instead.
|
||||
// https://github.com/meteor/meteor/issues/8253
|
||||
exports.signIn = Google.signIn = function (options, callback) {
|
||||
// support a callback without options
|
||||
if (! callback && typeof options === "function") {
|
||||
callback = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
gplusPromise.then(function (gplus) {
|
||||
var config = ServiceConfiguration.configurations.findOne({
|
||||
service: "google"
|
||||
});
|
||||
|
||||
if (! config) {
|
||||
throw new ServiceConfiguration.ConfigError();
|
||||
}
|
||||
|
||||
options = Object.assign(Object.create(null), options);
|
||||
|
||||
gplus.login({
|
||||
scopes: getScopes(options).join(" "),
|
||||
webClientId: config.clientId,
|
||||
offline: true
|
||||
}, function (response) {
|
||||
Accounts.callLoginMethod({
|
||||
methodArguments: [Object.assign({
|
||||
googleSignIn: true
|
||||
}, response)],
|
||||
userCallback: callback
|
||||
});
|
||||
}, callback);
|
||||
|
||||
}).catch(callback);
|
||||
};
|
||||
|
||||
function getScopes(options) {
|
||||
// we need the email scope to get user id from google.
|
||||
var requiredScopes = ['email'];
|
||||
var scopes = ['profile'];
|
||||
if (options && options.requestPermissions) {
|
||||
scopes = options.requestPermissions;
|
||||
}
|
||||
return _.union(scopes, requiredScopes);
|
||||
}
|
||||
|
||||
exports.signOut = Google.signOut = function () {
|
||||
return gplusPromise.then(function (gplus) {
|
||||
return new Promise(function (resolve) {
|
||||
gplus.logout(resolve);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Make sure we don't stay logged in with Google Sign-In after the client
|
||||
// calls Meteor.logout().
|
||||
Meteor.startup(function () {
|
||||
Accounts.onLogout(function () {
|
||||
Google.signOut().catch(tolerateUnhandledRejection);
|
||||
});
|
||||
});
|
||||
6
packages/google-oauth/namespace.js
Normal file
6
packages/google-oauth/namespace.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// The module.exports object of this module becomes the Google namespace
|
||||
// for other modules in this package.
|
||||
Google = module.exports;
|
||||
|
||||
// So that api.export finds the "Google" property.
|
||||
Google.Google = Google;
|
||||
@@ -1,9 +1,15 @@
|
||||
Package.describe({
|
||||
summary: "Google OAuth flow",
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
});
|
||||
|
||||
Cordova.depends({
|
||||
"cordova-plugin-googleplus": "5.1.1"
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
api.use("modules");
|
||||
api.use("promise");
|
||||
api.use('oauth2', ['client', 'server']);
|
||||
api.use('oauth', ['client', 'server']);
|
||||
api.use('http', ['server']);
|
||||
@@ -12,6 +18,9 @@ Package.onUse(function(api) {
|
||||
|
||||
api.addFiles('google_server.js', 'server');
|
||||
api.addFiles('google_client.js', 'client');
|
||||
api.addFiles('google_sign-in.js', 'web.cordova');
|
||||
|
||||
api.mainModule('namespace.js');
|
||||
|
||||
api.export('Google');
|
||||
});
|
||||
|
||||
@@ -111,7 +111,7 @@ app bundle (`pluginVersionsFromStarManifest`, a combination of
|
||||
`.meteor/cordova-plugins` for stand-alone plugin installs and the plugins added
|
||||
as dependencies of packages through `Cordova.depends`).
|
||||
The `pluginsConfiguration` comes from `App.configurePlugin` calls in
|
||||
`meteor-config.js`.
|
||||
`mobile-config.js`.
|
||||
|
||||
Uses methods `CordovaProject#listInstalledPluginVersions()`,
|
||||
`CordovaProject#addPlugin(name, version, config)`,
|
||||
|
||||
Reference in New Issue
Block a user