Remove underscore dependency from google-oauth package.

This commit is contained in:
Ben Newman
2017-04-12 14:20:06 -04:00
committed by Jesse Rosenberger
parent db093ff316
commit 6b44ded1e4
4 changed files with 63 additions and 37 deletions

View File

@@ -1,5 +1,13 @@
var Google = require("./namespace.js");
var ILLEGAL_PARAMETERS = {
'response_type': 1,
'client_id': 1,
'scope': 1,
'redirect_uri': 1,
'state': 1
};
// Request Google credentials for the user
// @param options {optional}
// @param credentialRequestCompleteCallback {Function} Callback function to call on
@@ -24,24 +32,26 @@ Google.requestCredential = function (options, credentialRequestCompleteCallback)
var credentialToken = Random.secret();
// we need the email scope to get user id from google.
var requiredScope = ['email'];
var scope = ['profile'];
if (options.requestPermissions)
scope = options.requestPermissions;
scope = _.union(scope, requiredScope);
var requiredScopes = { 'email': 1 };
var scopes = options.requestPermissions || ['profile'];
scopes.forEach(function (scope) {
requiredScopes[scope] = 1;
});
scopes = Object.keys(requiredScopes);
var loginUrlParameters = {};
if (config.loginUrlParameters){
_.extend(loginUrlParameters, config.loginUrlParameters)
Object.assign(loginUrlParameters, config.loginUrlParameters);
}
if (options.loginUrlParameters){
_.extend(loginUrlParameters, options.loginUrlParameters)
Object.assign(loginUrlParameters, options.loginUrlParameters);
}
var ILLEGAL_PARAMETERS = ['response_type', 'client_id', 'scope', 'redirect_uri', 'state'];
// validate options keys
_.each(_.keys(loginUrlParameters), function (key) {
if (_.contains(ILLEGAL_PARAMETERS, key))
// validate options keys
Object.keys(loginUrlParameters).forEach(function (key) {
if (ILLEGAL_PARAMETERS.hasOwnProperty(key)) {
throw new Error("Google.requestCredential: Invalid loginUrlParameter: " + key);
}
});
// backwards compatible options
@@ -60,16 +70,17 @@ Google.requestCredential = function (options, credentialRequestCompleteCallback)
var loginStyle = OAuth._loginStyle('google', config, options);
// https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl
_.extend(loginUrlParameters, {
Object.assign(loginUrlParameters, {
"response_type": "code",
"client_id": config.clientId,
"scope": scope.join(' '), // space delimited
"scope": scopes.join(' '), // space delimited
"redirect_uri": OAuth._redirectUri('google', config),
"state": OAuth._stateParam(loginStyle, credentialToken, options.redirectUrl)
});
var loginUrl = 'https://accounts.google.com/o/oauth2/auth?' +
_.map(loginUrlParameters, function(value, param){
return encodeURIComponent(param) + '=' + encodeURIComponent(value);
Object.keys(loginUrlParameters).map(function (param) {
return encodeURIComponent(param) + '=' +
encodeURIComponent(loginUrlParameters[param]);
}).join("&");
OAuth.launchLogin({

View File

@@ -1,5 +1,6 @@
var Google = require("./namespace.js");
var Accounts = require("meteor/accounts-base").Accounts;
var hasOwn = Object.prototype.hasOwnProperty;
// https://developers.google.com/accounts/docs/OAuth2Login#userinfocall
Google.whitelistedFields = ['id', 'email', 'verified_email', 'name', 'given_name',
@@ -20,8 +21,14 @@ function getServiceData(query) {
scope: scopes
};
var fields = _.pick(identity, Google.whitelistedFields);
_.extend(serviceData, fields);
var fields = Object.create(null);
Google.whitelistedFields.forEach(function (name) {
if (hasOwn.call(identity, name)) {
fields[name] = identity[name];
}
});
Object.assign(serviceData, fields);
// only set the token in serviceData if it's there. this ensures
// that we don't lose old ones (since we only get this on the first
@@ -40,15 +47,16 @@ Accounts.registerLoginHandler(function (request) {
return;
}
const res = getServiceData({code: request.serverAuthCode});
return Accounts.updateOrCreateUserFromExternalService("google", _.extend({
return Accounts.updateOrCreateUserFromExternalService("google", {
id: request.userId,
idToken: request.idToken,
accessToken: request.accessToken,
email: request.email,
picture: request.imageUrl
}, res.serviceData));
picture: request.imageUrl,
...getServiceData({
code: request.serverAuthCode
}).serviceData,
});
});
OAuth.registerService('google', 2, null, getServiceData);
@@ -73,8 +81,10 @@ var getTokens = function (query) {
grant_type: 'authorization_code'
}});
} catch (err) {
throw _.extend(new Error("Failed to complete OAuth handshake with Google. " + err.message),
{response: err.response});
throw Object.assign(
new Error("Failed to complete OAuth handshake with Google. " + err.message),
{ response: err.response }
);
}
if (response.data.error) { // if the http response was a json object with an error attribute
@@ -95,8 +105,10 @@ var getIdentity = function (accessToken) {
"https://www.googleapis.com/oauth2/v1/userinfo",
{params: {access_token: accessToken}}).data;
} catch (err) {
throw _.extend(new Error("Failed to fetch identity from Google. " + err.message),
{response: err.response});
throw Object.assign(
new Error("Failed to fetch identity from Google. " + err.message),
{ response: err.response }
);
}
};
@@ -106,8 +118,10 @@ var getScopes = function (accessToken) {
"https://www.googleapis.com/oauth2/v1/tokeninfo",
{params: {access_token: accessToken}}).data.scope.split(' ');
} catch (err) {
throw _.extend(new Error("Failed to fetch tokeninfo from Google. " + err.message),
{response: err.response});
throw Object.assign(
new Error("Failed to fetch tokeninfo from Google. " + err.message),
{ response: err.response }
);
}
};

View File

@@ -59,12 +59,14 @@ exports.signIn = Google.signIn = function (options, 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);
var requiredScopes = { 'email': 1 };
var scopes = options.requestPermissions || ['profile'];
scopes.forEach(function (scope) {
requiredScopes[scope] = 1;
});
return Object.keys(requiredScopes);
}
exports.signOut = Google.signOut = function () {

View File

@@ -14,12 +14,11 @@ Cordova.depends({
});
Package.onUse(function(api) {
api.use("modules");
api.use("promise");
api.use("ecmascript");
api.use('oauth2', ['client', 'server']);
api.use('oauth', ['client', 'server']);
api.use('http', ['server']);
api.use(['underscore', 'service-configuration'], ['client', 'server']);
api.use('service-configuration');
api.use('random', 'client');
api.addFiles('google_server.js', 'server');