mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Modernize oauth package
- Bumped patch version number 1.2.1 -> 1.2.2 - ES6 syntax and shorthand applied - Underscore removed as a dependency
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
(function () {
|
||||
(() => {
|
||||
|
||||
var config = JSON.parse(document.getElementById("config").innerHTML);
|
||||
const config = JSON.parse(document.getElementById("config").innerHTML);
|
||||
|
||||
if (config.setCredentialToken) {
|
||||
var credentialToken = config.credentialToken;
|
||||
var credentialSecret = config.credentialSecret;
|
||||
const { credentialToken, credentialSecret } = config;
|
||||
|
||||
if (config.isCordova) {
|
||||
var credentialString = JSON.stringify({
|
||||
credentialToken: credentialToken,
|
||||
credentialSecret: credentialSecret
|
||||
const credentialString = JSON.stringify({
|
||||
credentialToken,
|
||||
credentialSecret,
|
||||
});
|
||||
|
||||
window.location.hash = credentialString;
|
||||
@@ -31,7 +30,7 @@
|
||||
|
||||
if (! config.isCordova) {
|
||||
document.getElementById("completedText").style.display = "block";
|
||||
document.getElementById("loginCompleted").onclick = function(){ window.close(); };
|
||||
document.getElementById("loginCompleted").onclick = () => window.close();
|
||||
window.close();
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function () {
|
||||
(() => {
|
||||
|
||||
var config = JSON.parse(document.getElementById("config").innerHTML);
|
||||
const config = JSON.parse(document.getElementById("config").innerHTML);
|
||||
|
||||
if (config.setCredentialToken) {
|
||||
sessionStorage[config.storagePrefix + config.credentialToken] =
|
||||
|
||||
@@ -8,20 +8,21 @@
|
||||
// arguments.
|
||||
// @param dimensions {optional Object(width, height)} The dimensions of
|
||||
// the popup. If not passed defaults to something sane.
|
||||
OAuth.showPopup = function (url, callback, dimensions) {
|
||||
OAuth.showPopup = (url, callback, dimensions) => {
|
||||
// default dimensions that worked well for facebook and google
|
||||
var popup = openCenteredPopup(
|
||||
const popup = openCenteredPopup(
|
||||
url,
|
||||
(dimensions && dimensions.width) || 650,
|
||||
(dimensions && dimensions.height) || 331
|
||||
);
|
||||
|
||||
var checkPopupOpen = setInterval(function() {
|
||||
const checkPopupOpen = setInterval(() => {
|
||||
let popupClosed;
|
||||
try {
|
||||
// Fix for #328 - added a second test criteria (popup.closed === undefined)
|
||||
// to humour this Android quirk:
|
||||
// http://code.google.com/p/android/issues/detail?id=21061
|
||||
var popupClosed = popup.closed || popup.closed === undefined;
|
||||
popupClosed = popup.closed || popup.closed === undefined;
|
||||
} catch (e) {
|
||||
// For some unknown reason, IE9 (and others?) sometimes (when
|
||||
// the popup closes too quickly?) throws "SCRIPT16386: No such
|
||||
@@ -37,29 +38,29 @@ OAuth.showPopup = function (url, callback, dimensions) {
|
||||
}, 100);
|
||||
};
|
||||
|
||||
var openCenteredPopup = function(url, width, height) {
|
||||
var screenX = typeof window.screenX !== 'undefined'
|
||||
const openCenteredPopup = function(url, width, height) {
|
||||
const screenX = typeof window.screenX !== 'undefined'
|
||||
? window.screenX : window.screenLeft;
|
||||
var screenY = typeof window.screenY !== 'undefined'
|
||||
const screenY = typeof window.screenY !== 'undefined'
|
||||
? window.screenY : window.screenTop;
|
||||
var outerWidth = typeof window.outerWidth !== 'undefined'
|
||||
const outerWidth = typeof window.outerWidth !== 'undefined'
|
||||
? window.outerWidth : document.body.clientWidth;
|
||||
var outerHeight = typeof window.outerHeight !== 'undefined'
|
||||
const outerHeight = typeof window.outerHeight !== 'undefined'
|
||||
? window.outerHeight : (document.body.clientHeight - 22);
|
||||
// XXX what is the 22?
|
||||
|
||||
// Use `outerWidth - width` and `outerHeight - height` for help in
|
||||
// positioning the popup centered relative to the current window
|
||||
var left = screenX + (outerWidth - width) / 2;
|
||||
var top = screenY + (outerHeight - height) / 2;
|
||||
var features = ('width=' + width + ',height=' + height +
|
||||
',left=' + left + ',top=' + top + ',scrollbars=yes');
|
||||
const left = screenX + (outerWidth - width) / 2;
|
||||
const top = screenY + (outerHeight - height) / 2;
|
||||
const features = (`width=${width},height=${height}` +
|
||||
`,left=${left},top=${top},scrollbars=yes'`);
|
||||
|
||||
var newwindow = window.open(url, 'Login', features);
|
||||
const newwindow = window.open(url, 'Login', features);
|
||||
|
||||
if (typeof newwindow === 'undefined') {
|
||||
// blocked by a popup blocker maybe?
|
||||
var err = new Error("The login popup was blocked by the browser");
|
||||
const err = new Error("The login popup was blocked by the browser");
|
||||
err.attemptedUrl = url;
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// credentialToken -> credentialSecret. You must provide both the
|
||||
// credentialToken and the credentialSecret to retrieve an access token from
|
||||
// the _pendingCredentials collection.
|
||||
var credentialSecrets = {};
|
||||
const credentialSecrets = {};
|
||||
|
||||
OAuth = {};
|
||||
|
||||
OAuth.showPopup = function (url, callback, dimensions) {
|
||||
OAuth.showPopup = (url, callback, dimensions) => {
|
||||
throw new Error("OAuth.showPopup must be implemented on this arch.");
|
||||
};
|
||||
|
||||
// Determine the login style (popup or redirect) for this login flow.
|
||||
//
|
||||
//
|
||||
OAuth._loginStyle = function (service, config, options) {
|
||||
OAuth._loginStyle = (service, config, options) => {
|
||||
|
||||
if (Meteor.isCordova) {
|
||||
return "popup";
|
||||
}
|
||||
|
||||
var loginStyle = (options && options.loginStyle) || config.loginStyle || 'popup';
|
||||
let loginStyle = (options && options.loginStyle) || config.loginStyle || 'popup';
|
||||
|
||||
if (! _.contains(["popup", "redirect"], loginStyle))
|
||||
throw new Error("Invalid login style: " + loginStyle);
|
||||
if (! ["popup", "redirect"].includes(loginStyle))
|
||||
throw new Error(`Invalid login style: ${loginStyle}`);
|
||||
|
||||
// If we don't have session storage (for example, Safari in private
|
||||
// mode), the redirect login flow won't work, so fallback to the
|
||||
@@ -38,10 +38,10 @@ OAuth._loginStyle = function (service, config, options) {
|
||||
return loginStyle;
|
||||
};
|
||||
|
||||
OAuth._stateParam = function (loginStyle, credentialToken, redirectUrl) {
|
||||
var state = {
|
||||
loginStyle: loginStyle,
|
||||
credentialToken: credentialToken,
|
||||
OAuth._stateParam = (loginStyle, credentialToken, redirectUrl) => {
|
||||
const state = {
|
||||
loginStyle,
|
||||
credentialToken,
|
||||
isCordova: Meteor.isCordova
|
||||
};
|
||||
|
||||
@@ -59,10 +59,8 @@ OAuth._stateParam = function (loginStyle, credentialToken, redirectUrl) {
|
||||
// the login service, save the credential token for this login attempt
|
||||
// in the reload migration data.
|
||||
//
|
||||
OAuth.saveDataForRedirect = function (loginService, credentialToken) {
|
||||
Reload._onMigrate('oauth', function () {
|
||||
return [true, {loginService: loginService, credentialToken: credentialToken}];
|
||||
});
|
||||
OAuth.saveDataForRedirect = (loginService, credentialToken) => {
|
||||
Reload._onMigrate('oauth', () => [true, { loginService, credentialToken }]);
|
||||
Reload._migrate(null, {immediateMigration: true});
|
||||
};
|
||||
|
||||
@@ -74,15 +72,15 @@ OAuth.saveDataForRedirect = function (loginService, credentialToken) {
|
||||
// application startup and we weren't just redirected at the end of
|
||||
// the login flow.
|
||||
//
|
||||
OAuth.getDataAfterRedirect = function () {
|
||||
var migrationData = Reload._migrationData('oauth');
|
||||
OAuth.getDataAfterRedirect = () => {
|
||||
const migrationData = Reload._migrationData('oauth');
|
||||
|
||||
if (! (migrationData && migrationData.credentialToken))
|
||||
return null;
|
||||
|
||||
var credentialToken = migrationData.credentialToken;
|
||||
var key = OAuth._storageTokenPrefix + credentialToken;
|
||||
var credentialSecret;
|
||||
const { credentialToken } = migrationData;
|
||||
const key = OAuth._storageTokenPrefix + credentialToken;
|
||||
let credentialSecret;
|
||||
try {
|
||||
credentialSecret = sessionStorage.getItem(key);
|
||||
sessionStorage.removeItem(key);
|
||||
@@ -91,8 +89,8 @@ OAuth.getDataAfterRedirect = function () {
|
||||
}
|
||||
return {
|
||||
loginService: migrationData.loginService,
|
||||
credentialToken: credentialToken,
|
||||
credentialSecret: credentialSecret
|
||||
credentialToken,
|
||||
credentialSecret,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -109,13 +107,13 @@ OAuth.getDataAfterRedirect = function () {
|
||||
// is closed and we have the credential from the login service.
|
||||
// credentialToken: our identifier for this login flow.
|
||||
//
|
||||
OAuth.launchLogin = function (options) {
|
||||
OAuth.launchLogin = options => {
|
||||
if (! options.loginService)
|
||||
throw new Error('loginService required');
|
||||
if (options.loginStyle === 'popup') {
|
||||
OAuth.showPopup(
|
||||
options.loginUrl,
|
||||
_.bind(options.credentialRequestCompleteCallback, null, options.credentialToken),
|
||||
options.credentialRequestCompleteCallback.bind(null, options.credentialToken),
|
||||
options.popupOptions);
|
||||
} else if (options.loginStyle === 'redirect') {
|
||||
OAuth.saveDataForRedirect(options.loginService, options.credentialToken);
|
||||
@@ -127,20 +125,20 @@ OAuth.launchLogin = function (options) {
|
||||
|
||||
// XXX COMPAT WITH 0.7.0.1
|
||||
// Private interface but probably used by many oauth clients in atmosphere.
|
||||
OAuth.initiateLogin = function (credentialToken, url, callback, dimensions) {
|
||||
OAuth.initiateLogin = (credentialToken, url, callback, dimensions) => {
|
||||
OAuth.showPopup(
|
||||
url,
|
||||
_.bind(callback, null, credentialToken),
|
||||
callback.bind(null, credentialToken),
|
||||
dimensions
|
||||
);
|
||||
};
|
||||
|
||||
// Called by the popup when the OAuth flow is completed, right before
|
||||
// the popup closes.
|
||||
OAuth._handleCredentialSecret = function (credentialToken, secret) {
|
||||
OAuth._handleCredentialSecret = (credentialToken, secret) => {
|
||||
check(credentialToken, String);
|
||||
check(secret, String);
|
||||
if (! _.has(credentialSecrets,credentialToken)) {
|
||||
if (! Object.prototype.hasOwnProperty.call(credentialSecrets, credentialToken)) {
|
||||
credentialSecrets[credentialToken] = secret;
|
||||
} else {
|
||||
throw new Error("Duplicate credential token from OAuth login");
|
||||
@@ -149,13 +147,13 @@ OAuth._handleCredentialSecret = function (credentialToken, secret) {
|
||||
|
||||
// Used by accounts-oauth, which needs both a credentialToken and the
|
||||
// corresponding to credential secret to call the `login` method over DDP.
|
||||
OAuth._retrieveCredentialSecret = function (credentialToken) {
|
||||
OAuth._retrieveCredentialSecret = credentialToken => {
|
||||
// First check the secrets collected by OAuth._handleCredentialSecret,
|
||||
// then check localStorage. This matches what we do in
|
||||
// end_of_login_response.html.
|
||||
var secret = credentialSecrets[credentialToken];
|
||||
let secret = credentialSecrets[credentialToken];
|
||||
if (! secret) {
|
||||
var localStorageKey = OAuth._storageTokenPrefix + credentialToken;
|
||||
const localStorageKey = OAuth._storageTokenPrefix + credentialToken;
|
||||
secret = Meteor._localStorage.getItem(localStorageKey);
|
||||
Meteor._localStorage.removeItem(localStorageKey);
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import url from 'url';
|
||||
|
||||
OAuth._storageTokenPrefix = "Meteor.oauth.credentialSecret-";
|
||||
|
||||
OAuth._redirectUri = function (serviceName, config, params, absoluteUrlOptions) {
|
||||
OAuth._redirectUri = (serviceName, config, params, absoluteUrlOptions) => {
|
||||
// XXX COMPAT WITH 0.9.0
|
||||
// The redirect URI used to have a "?close" query argument. We
|
||||
// detect whether we need to be backwards compatible by checking for
|
||||
@@ -8,26 +10,26 @@ OAuth._redirectUri = function (serviceName, config, params, absoluteUrlOptions)
|
||||
// code which had the "?close" argument.
|
||||
// This logic is duplicated in the tool so that the tool can do OAuth
|
||||
// flow with <= 0.9.0 servers (tools/auth.js).
|
||||
var query = config.loginStyle ? null : "close";
|
||||
const query = config.loginStyle ? null : "close";
|
||||
|
||||
// Clone because we're going to mutate 'params'. The 'cordova' and
|
||||
// 'android' parameters are only used for picking the host of the
|
||||
// redirect URL, and not actually included in the redirect URL itself.
|
||||
var isCordova = false;
|
||||
var isAndroid = false;
|
||||
let isCordova = false;
|
||||
let isAndroid = false;
|
||||
if (params) {
|
||||
params = _.clone(params);
|
||||
params = { ...params };
|
||||
isCordova = params.cordova;
|
||||
isAndroid = params.android;
|
||||
delete params.cordova;
|
||||
delete params.android;
|
||||
if (_.isEmpty(params)) {
|
||||
if (Object.keys(params).length === 0) {
|
||||
params = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (Meteor.isServer && isCordova) {
|
||||
var rootUrl = process.env.MOBILE_ROOT_URL ||
|
||||
let rootUrl = process.env.MOBILE_ROOT_URL ||
|
||||
__meteor_runtime_config__.ROOT_URL;
|
||||
|
||||
if (isAndroid) {
|
||||
@@ -36,8 +38,7 @@ OAuth._redirectUri = function (serviceName, config, params, absoluteUrlOptions)
|
||||
// XXX Maybe we should put this in a separate package or something
|
||||
// that is used here and by boilerplate-generator? Or maybe
|
||||
// `Meteor.absoluteUrl` should know how to do this?
|
||||
var url = Npm.require("url");
|
||||
var parsedRootUrl = url.parse(rootUrl);
|
||||
const parsedRootUrl = url.parse(rootUrl);
|
||||
if (parsedRootUrl.hostname === "localhost") {
|
||||
parsedRootUrl.hostname = "10.0.2.2";
|
||||
delete parsedRootUrl.host;
|
||||
@@ -45,15 +46,16 @@ OAuth._redirectUri = function (serviceName, config, params, absoluteUrlOptions)
|
||||
rootUrl = url.format(parsedRootUrl);
|
||||
}
|
||||
|
||||
absoluteUrlOptions = _.extend({}, absoluteUrlOptions, {
|
||||
absoluteUrlOptions = {
|
||||
...absoluteUrlOptions,
|
||||
// For Cordova clients, redirect to the special Cordova root url
|
||||
// (likely a local IP in development mode).
|
||||
rootUrl: rootUrl
|
||||
});
|
||||
rootUrl,
|
||||
};
|
||||
}
|
||||
|
||||
return URL._constructUrl(
|
||||
Meteor.absoluteUrl('_oauth/' + serviceName, absoluteUrlOptions),
|
||||
Meteor.absoluteUrl(`_oauth/${serviceName}`, absoluteUrlOptions),
|
||||
query,
|
||||
params);
|
||||
};
|
||||
|
||||
@@ -8,32 +8,31 @@
|
||||
// arguments.
|
||||
// @param dimensions {optional Object(width, height)} The dimensions of
|
||||
// the popup. If not passed defaults to something sane.
|
||||
OAuth.showPopup = function (url, callback, dimensions) {
|
||||
var fail = function (err) {
|
||||
Meteor._debug("Error from OAuth popup: " + JSON.stringify(err));
|
||||
};
|
||||
OAuth.showPopup = (url, callback, dimensions) => {
|
||||
const fail = err =>
|
||||
Meteor._debug(`Error from OAuth popup: ${JSON.stringify(err)}`);
|
||||
|
||||
// When running on an android device, we sometimes see the
|
||||
// `pageLoaded` callback fire twice for the final page in the OAuth
|
||||
// popup, even though the page only loads once. This is maybe an
|
||||
// Android bug or maybe something intentional about how onPageFinished
|
||||
// works that we don't understand and isn't well-documented.
|
||||
var oauthFinished = false;
|
||||
let oauthFinished = false;
|
||||
|
||||
var pageLoaded = function (event) {
|
||||
const pageLoaded = event => {
|
||||
if (oauthFinished) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.url.indexOf(Meteor.absoluteUrl('_oauth')) === 0) {
|
||||
var splitUrl = event.url.split("#");
|
||||
var hashFragment = splitUrl[1];
|
||||
const splitUrl = event.url.split("#");
|
||||
const hashFragment = splitUrl[1];
|
||||
|
||||
if (! hashFragment) {
|
||||
throw new Error("No hash fragment in OAuth popup?");
|
||||
}
|
||||
|
||||
var credentials = JSON.parse(decodeURIComponent(hashFragment));
|
||||
const credentials = JSON.parse(decodeURIComponent(hashFragment));
|
||||
OAuth._handleCredentialSecret(credentials.credentialToken,
|
||||
credentials.credentialSecret);
|
||||
|
||||
@@ -47,20 +46,20 @@ OAuth.showPopup = function (url, callback, dimensions) {
|
||||
// https://issues.apache.org/jira/browse/CB-2285.
|
||||
//
|
||||
// XXX Can we make this timeout smaller?
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
popup.close();
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
var onExit = function () {
|
||||
const onExit = () => {
|
||||
popup.removeEventListener('loadstop', pageLoaded);
|
||||
popup.removeEventListener('loaderror', fail);
|
||||
popup.removeEventListener('exit', onExit);
|
||||
};
|
||||
|
||||
var popup = window.open(url, '_blank', 'location=yes,hidden=yes');
|
||||
const popup = window.open(url, '_blank', 'location=yes,hidden=yes');
|
||||
popup.addEventListener('loadstop', pageLoaded);
|
||||
popup.addEventListener('loaderror', fail);
|
||||
popup.addEventListener('exit', onExit);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
var Fiber = Npm.require('fibers');
|
||||
var url = Npm.require('url');
|
||||
import Fiber from 'fibers';
|
||||
import url from 'url';
|
||||
|
||||
OAuth = {};
|
||||
OAuthTest = {};
|
||||
|
||||
RoutePolicy.declare('/_oauth/', 'network');
|
||||
|
||||
var registeredServices = {};
|
||||
const registeredServices = {};
|
||||
|
||||
// Internal: Maps from service version to handler function. The
|
||||
// 'oauth1' and 'oauth2' packages manipulate this directly to register
|
||||
@@ -30,58 +30,57 @@ OAuth._requestHandlers = {};
|
||||
// up in the user's services[name] field
|
||||
// - `null` if the user declined to give permissions
|
||||
//
|
||||
OAuth.registerService = function (name, version, urls, handleOauthRequest) {
|
||||
OAuth.registerService = (name, version, urls, handleOauthRequest) => {
|
||||
if (registeredServices[name])
|
||||
throw new Error("Already registered the " + name + " OAuth service");
|
||||
throw new Error(`Already registered the ${name} OAuth service`);
|
||||
|
||||
registeredServices[name] = {
|
||||
serviceName: name,
|
||||
version: version,
|
||||
urls: urls,
|
||||
handleOauthRequest: handleOauthRequest
|
||||
version,
|
||||
urls,
|
||||
handleOauthRequest,
|
||||
};
|
||||
};
|
||||
|
||||
// For test cleanup.
|
||||
OAuthTest.unregisterService = function (name) {
|
||||
OAuthTest.unregisterService = name => {
|
||||
delete registeredServices[name];
|
||||
};
|
||||
|
||||
|
||||
OAuth.retrieveCredential = function(credentialToken, credentialSecret) {
|
||||
return OAuth._retrievePendingCredential(credentialToken, credentialSecret);
|
||||
};
|
||||
OAuth.retrieveCredential = (credentialToken, credentialSecret) =>
|
||||
OAuth._retrievePendingCredential(credentialToken, credentialSecret);
|
||||
|
||||
|
||||
// The state parameter is normally generated on the client using
|
||||
// `btoa`, but for tests we need a version that runs on the server.
|
||||
//
|
||||
OAuth._generateState = function (loginStyle, credentialToken, redirectUrl) {
|
||||
OAuth._generateState = (loginStyle, credentialToken, redirectUrl) => {
|
||||
return Buffer.from(JSON.stringify({
|
||||
loginStyle: loginStyle,
|
||||
credentialToken: credentialToken,
|
||||
redirectUrl: redirectUrl})).toString('base64');
|
||||
};
|
||||
|
||||
OAuth._stateFromQuery = function (query) {
|
||||
var string;
|
||||
OAuth._stateFromQuery = query => {
|
||||
let string;
|
||||
try {
|
||||
string = Buffer.from(query.state, 'base64').toString('binary');
|
||||
} catch (e) {
|
||||
Log.warn('Unable to base64 decode state from OAuth query: ' + query.state);
|
||||
Log.warn(`Unable to base64 decode state from OAuth query: ${query.state}`);
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(string);
|
||||
} catch (e) {
|
||||
Log.warn('Unable to parse state from OAuth query: ' + string);
|
||||
Log.warn(`Unable to parse state from OAuth query: ${string}`);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
OAuth._loginStyleFromQuery = function (query) {
|
||||
var style;
|
||||
OAuth._loginStyleFromQuery = quer => {
|
||||
let style;
|
||||
// For backwards-compatibility for older clients, catch any errors
|
||||
// that result from parsing the state parameter. If we can't parse it,
|
||||
// set login style to popup by default.
|
||||
@@ -91,13 +90,13 @@ OAuth._loginStyleFromQuery = function (query) {
|
||||
style = "popup";
|
||||
}
|
||||
if (style !== "popup" && style !== "redirect") {
|
||||
throw new Error("Unrecognized login style: " + style);
|
||||
throw new Error(`Unrecognized login style: ${style}`);
|
||||
}
|
||||
return style;
|
||||
};
|
||||
|
||||
OAuth._credentialTokenFromQuery = function (query) {
|
||||
var state;
|
||||
OAuth._credentialTokenFromQuery = query => {
|
||||
let state;
|
||||
// For backwards-compatibility for older clients, catch any errors
|
||||
// that result from parsing the state parameter. If we can't parse it,
|
||||
// assume that the state parameter's value is the credential token, as
|
||||
@@ -110,7 +109,7 @@ OAuth._credentialTokenFromQuery = function (query) {
|
||||
return state.credentialToken;
|
||||
};
|
||||
|
||||
OAuth._isCordovaFromQuery = function (query) {
|
||||
OAuth._isCordovaFromQuery = query => {
|
||||
try {
|
||||
return !! OAuth._stateFromQuery(query).isCordova;
|
||||
} catch (err) {
|
||||
@@ -126,9 +125,9 @@ OAuth._isCordovaFromQuery = function (query) {
|
||||
// We export this function so that developers can override this
|
||||
// behavior to allow apps from external domains to login using the
|
||||
// redirect OAuth flow.
|
||||
OAuth._checkRedirectUrlOrigin = function (redirectUrl) {
|
||||
var appHost = Meteor.absoluteUrl();
|
||||
var appHostReplacedLocalhost = Meteor.absoluteUrl(undefined, {
|
||||
OAuth._checkRedirectUrlOrigin = redirectUrl => {
|
||||
const appHost = Meteor.absoluteUrl();
|
||||
const appHostReplacedLocalhost = Meteor.absoluteUrl(undefined, {
|
||||
replaceLocalhost: true
|
||||
});
|
||||
return (
|
||||
@@ -139,37 +138,35 @@ OAuth._checkRedirectUrlOrigin = function (redirectUrl) {
|
||||
|
||||
|
||||
// Listen to incoming OAuth http requests
|
||||
WebApp.connectHandlers.use(function(req, res, next) {
|
||||
WebApp.connectHandlers.use((req, res, next) => {
|
||||
// Need to create a Fiber since we're using synchronous http calls and nothing
|
||||
// else is wrapping this in a fiber automatically
|
||||
Fiber(function () {
|
||||
middleware(req, res, next);
|
||||
}).run();
|
||||
Fiber(() => middleware(req, res, next)).run();
|
||||
});
|
||||
|
||||
var middleware = function (req, res, next) {
|
||||
const middleware = (req, res, next) => {
|
||||
// Make sure to catch any exceptions because otherwise we'd crash
|
||||
// the runner
|
||||
try {
|
||||
var serviceName = oauthServiceName(req);
|
||||
const serviceName = oauthServiceName(req);
|
||||
if (!serviceName) {
|
||||
// not an oauth request. pass to next middleware.
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
var service = registeredServices[serviceName];
|
||||
const service = registeredServices[serviceName];
|
||||
|
||||
// Skip everything if there's no service set by the oauth middleware
|
||||
if (!service)
|
||||
throw new Error("Unexpected OAuth service " + serviceName);
|
||||
throw new Error(`Unexpected OAuth service ${serviceName}`);
|
||||
|
||||
// Make sure we're configured
|
||||
ensureConfigured(serviceName);
|
||||
|
||||
var handler = OAuth._requestHandlers[service.version];
|
||||
const handler = OAuth._requestHandlers[service.version];
|
||||
if (!handler)
|
||||
throw new Error("Unexpected OAuth version " + service.version);
|
||||
throw new Error(`Unexpected OAuth version ${service.version}`);
|
||||
handler(service, req.query, res);
|
||||
} catch (err) {
|
||||
// if we got thrown an error, save it off, it will get passed to
|
||||
@@ -213,15 +210,15 @@ OAuthTest.middleware = middleware;
|
||||
//
|
||||
// @returns {String|null} e.g. "facebook", or null if this isn't an
|
||||
// oauth request
|
||||
var oauthServiceName = function (req) {
|
||||
const oauthServiceName = req => {
|
||||
// req.url will be "/_oauth/<service name>" with an optional "?close".
|
||||
var i = req.url.indexOf('?');
|
||||
var barePath;
|
||||
const i = req.url.indexOf('?');
|
||||
let barePath;
|
||||
if (i === -1)
|
||||
barePath = req.url;
|
||||
else
|
||||
barePath = req.url.substring(0, i);
|
||||
var splitPath = barePath.split('/');
|
||||
const splitPath = barePath.split('/');
|
||||
|
||||
// Any non-oauth request will continue down the default
|
||||
// middlewares.
|
||||
@@ -229,18 +226,18 @@ var oauthServiceName = function (req) {
|
||||
return null;
|
||||
|
||||
// Find service based on url
|
||||
var serviceName = splitPath[2];
|
||||
const serviceName = splitPath[2];
|
||||
return serviceName;
|
||||
};
|
||||
|
||||
// Make sure we're configured
|
||||
var ensureConfigured = function(serviceName) {
|
||||
const ensureConfigured = serviceName => {
|
||||
if (!ServiceConfiguration.configurations.findOne({service: serviceName})) {
|
||||
throw new ServiceConfiguration.ConfigError();
|
||||
}
|
||||
};
|
||||
|
||||
var isSafe = function (value) {
|
||||
const isSafe = value => {
|
||||
// This matches strings generated by `Random.secret` and
|
||||
// `Random.id`.
|
||||
return typeof value === "string" &&
|
||||
@@ -248,7 +245,7 @@ var isSafe = function (value) {
|
||||
};
|
||||
|
||||
// Internal: used by the oauth1 and oauth2 packages
|
||||
OAuth._renderOauthResults = function(res, query, credentialSecret) {
|
||||
OAuth._renderOauthResults = (res, query, credentialSecret) => {
|
||||
// For tests, we support the `only_credential_secret_for_test`
|
||||
// parameter, which just returns the credential secret without any
|
||||
// surrounding HTML. (The test needs to be able to easily grab the
|
||||
@@ -262,15 +259,15 @@ OAuth._renderOauthResults = function(res, query, credentialSecret) {
|
||||
res.writeHead(200, {'Content-Type': 'text/html'});
|
||||
res.end(credentialSecret, 'utf-8');
|
||||
} else {
|
||||
var details = {
|
||||
query: query,
|
||||
const details = {
|
||||
query,
|
||||
loginStyle: OAuth._loginStyleFromQuery(query)
|
||||
};
|
||||
if (query.error) {
|
||||
details.error = query.error;
|
||||
} else {
|
||||
var token = OAuth._credentialTokenFromQuery(query);
|
||||
var secret = credentialSecret;
|
||||
const token = OAuth._credentialTokenFromQuery(query);
|
||||
const secret = credentialSecret;
|
||||
if (token && secret &&
|
||||
isSafe(token) && isSafe(secret)) {
|
||||
details.credentials = { token: token, secret: secret};
|
||||
@@ -303,13 +300,13 @@ OAuth._endOfRedirectResponseTemplate = Assets.getText(
|
||||
// - redirectUrl
|
||||
// - isCordova (boolean)
|
||||
//
|
||||
var renderEndOfLoginResponse = function (options) {
|
||||
const renderEndOfLoginResponse = options => {
|
||||
// It would be nice to use Blaze here, but it's a little tricky
|
||||
// because our mustaches would be inside a <script> tag, and Blaze
|
||||
// would treat the <script> tag contents as text (e.g. encode '&' as
|
||||
// '&'). So we just do a simple replace.
|
||||
|
||||
var escape = function (s) {
|
||||
const escape = s => {
|
||||
if (s) {
|
||||
return s.replace(/&/g, "&").
|
||||
replace(/</g, "<").
|
||||
@@ -324,7 +321,7 @@ var renderEndOfLoginResponse = function (options) {
|
||||
|
||||
// Escape everything just to be safe (we've already checked that some
|
||||
// of this data -- the token and secret -- are safe).
|
||||
var config = {
|
||||
const config = {
|
||||
setCredentialToken: !! options.setCredentialToken,
|
||||
credentialToken: escape(options.credentialToken),
|
||||
credentialSecret: escape(options.credentialSecret),
|
||||
@@ -333,21 +330,21 @@ var renderEndOfLoginResponse = function (options) {
|
||||
isCordova: !! options.isCordova
|
||||
};
|
||||
|
||||
var template;
|
||||
let template;
|
||||
if (options.loginStyle === 'popup') {
|
||||
template = OAuth._endOfPopupResponseTemplate;
|
||||
} else if (options.loginStyle === 'redirect') {
|
||||
template = OAuth._endOfRedirectResponseTemplate;
|
||||
} else {
|
||||
throw new Error('invalid loginStyle: ' + options.loginStyle);
|
||||
throw new Error(`invalid loginStyle: ${options.loginStyle}`);
|
||||
}
|
||||
|
||||
var result = template.replace(/##CONFIG##/, JSON.stringify(config))
|
||||
const result = template.replace(/##CONFIG##/, JSON.stringify(config))
|
||||
.replace(
|
||||
/##ROOT_URL_PATH_PREFIX##/, __meteor_runtime_config__.ROOT_URL_PATH_PREFIX
|
||||
);
|
||||
|
||||
return "<!DOCTYPE html>\n" + result;
|
||||
return `<!DOCTYPE html>\n${result}`;
|
||||
};
|
||||
|
||||
// Writes an HTTP response to the popup window at the end of an OAuth
|
||||
@@ -381,21 +378,21 @@ var renderEndOfLoginResponse = function (options) {
|
||||
// so shouldn't be trusted for security decisions or included in
|
||||
// the response without sanitizing it first. Only one of `error`
|
||||
// or `credentials` should be set.
|
||||
OAuth._endOfLoginResponse = function (res, details) {
|
||||
OAuth._endOfLoginResponse = (res, details) => {
|
||||
res.writeHead(200, {'Content-Type': 'text/html'});
|
||||
|
||||
var redirectUrl;
|
||||
let redirectUrl;
|
||||
if (details.loginStyle === 'redirect') {
|
||||
redirectUrl = OAuth._stateFromQuery(details.query).redirectUrl;
|
||||
var appHost = Meteor.absoluteUrl();
|
||||
const appHost = Meteor.absoluteUrl();
|
||||
if (OAuth._checkRedirectUrlOrigin(redirectUrl)) {
|
||||
details.error = "redirectUrl (" + redirectUrl +
|
||||
") is not on the same host as the app (" + appHost + ")";
|
||||
details.error = `redirectUrl (${redirectUrl}` +
|
||||
`) is not on the same host as the app (${appHost})`;
|
||||
redirectUrl = appHost;
|
||||
}
|
||||
}
|
||||
|
||||
var isCordova = OAuth._isCordovaFromQuery(details.query);
|
||||
const isCordova = OAuth._isCordovaFromQuery(details.query);
|
||||
|
||||
if (details.error) {
|
||||
Log.warn("Error in OAuth Server: " +
|
||||
@@ -404,8 +401,8 @@ OAuth._endOfLoginResponse = function (res, details) {
|
||||
res.end(renderEndOfLoginResponse({
|
||||
loginStyle: details.loginStyle,
|
||||
setCredentialToken: false,
|
||||
redirectUrl: redirectUrl,
|
||||
isCordova: isCordova
|
||||
redirectUrl,
|
||||
isCordova,
|
||||
}), "utf-8");
|
||||
return;
|
||||
}
|
||||
@@ -418,17 +415,16 @@ OAuth._endOfLoginResponse = function (res, details) {
|
||||
setCredentialToken: true,
|
||||
credentialToken: details.credentials.token,
|
||||
credentialSecret: details.credentials.secret,
|
||||
redirectUrl: redirectUrl,
|
||||
isCordova: isCordova
|
||||
redirectUrl,
|
||||
isCordova,
|
||||
}), "utf-8");
|
||||
};
|
||||
|
||||
|
||||
var OAuthEncryption = Package["oauth-encryption"] && Package["oauth-encryption"].OAuthEncryption;
|
||||
const OAuthEncryption = Package["oauth-encryption"] && Package["oauth-encryption"].OAuthEncryption;
|
||||
|
||||
var usingOAuthEncryption = function () {
|
||||
return OAuthEncryption && OAuthEncryption.keyIsLoaded();
|
||||
};
|
||||
const usingOAuthEncryption = () =>
|
||||
OAuthEncryption && OAuthEncryption.keyIsLoaded();
|
||||
|
||||
// Encrypt sensitive service data such as access tokens if the
|
||||
// "oauth-encryption" package is loaded and the oauth secret key has
|
||||
@@ -440,7 +436,7 @@ var usingOAuthEncryption = function () {
|
||||
// will be re-encrypted with the user id included before inserting the
|
||||
// service data into the user document.
|
||||
//
|
||||
OAuth.sealSecret = function (plaintext) {
|
||||
OAuth.sealSecret = plaintext => {
|
||||
if (usingOAuthEncryption())
|
||||
return OAuthEncryption.seal(plaintext);
|
||||
else
|
||||
@@ -453,7 +449,7 @@ OAuth.sealSecret = function (plaintext) {
|
||||
// Throws an error if the "oauth-encryption" package is loaded and the
|
||||
// field is encrypted, but the oauth secret key hasn't been specified.
|
||||
//
|
||||
OAuth.openSecret = function (maybeSecret, userId) {
|
||||
OAuth.openSecret = (maybeSecret, userId) => {
|
||||
if (!Package["oauth-encryption"] || !OAuthEncryption.isSealed(maybeSecret))
|
||||
return maybeSecret;
|
||||
|
||||
@@ -462,10 +458,10 @@ OAuth.openSecret = function (maybeSecret, userId) {
|
||||
|
||||
// Unencrypt fields in the service data object.
|
||||
//
|
||||
OAuth.openSecrets = function (serviceData, userId) {
|
||||
var result = {};
|
||||
_.each(_.keys(serviceData), function (key) {
|
||||
result[key] = OAuth.openSecret(serviceData[key], userId);
|
||||
});
|
||||
OAuth.openSecrets = (serviceData, userId) => {
|
||||
const result = {};
|
||||
Object.keys(serviceData).forEach(key =>
|
||||
result[key] = OAuth.openSecret(serviceData[key], userId)
|
||||
);
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
Tinytest.add("oauth - pendingCredential handles Errors", function (test) {
|
||||
var credentialToken = Random.id();
|
||||
Tinytest.add("oauth - pendingCredential handles Errors", test => {
|
||||
const credentialToken = Random.id();
|
||||
|
||||
var testError = new Error("This is a test error");
|
||||
const testError = new Error("This is a test error");
|
||||
testError.stack = 'test stack';
|
||||
OAuth._storePendingCredential(credentialToken, testError);
|
||||
|
||||
// Test that the result for the token is the expected error
|
||||
var result = OAuth._retrievePendingCredential(credentialToken);
|
||||
const result = OAuth._retrievePendingCredential(credentialToken);
|
||||
test.instanceOf(result, Error);
|
||||
test.equal(result.message, testError.message);
|
||||
test.equal(result.stack, testError.stack);
|
||||
});
|
||||
|
||||
Tinytest.add("oauth - pendingCredential handles Meteor.Errors", function (test) {
|
||||
var credentialToken = Random.id();
|
||||
Tinytest.add("oauth - pendingCredential handles Meteor.Errors", test => {
|
||||
const credentialToken = Random.id();
|
||||
|
||||
var testError = new Meteor.Error(401, "This is a test error");
|
||||
const testError = new Meteor.Error(401, "This is a test error");
|
||||
testError.stack = 'test stack';
|
||||
OAuth._storePendingCredential(credentialToken, testError);
|
||||
|
||||
// Test that the result for the token is the expected error
|
||||
var result = OAuth._retrievePendingCredential(credentialToken);
|
||||
const result = OAuth._retrievePendingCredential(credentialToken);
|
||||
test.instanceOf(result, Meteor.Error);
|
||||
test.equal(result.error, testError.error);
|
||||
test.equal(result.message, testError.message);
|
||||
@@ -29,49 +29,42 @@ Tinytest.add("oauth - pendingCredential handles Meteor.Errors", function (test)
|
||||
test.isUndefined(result.meteorError);
|
||||
});
|
||||
|
||||
Tinytest.add("oauth - null, undefined key for pendingCredential", function (test) {
|
||||
var cred = Random.id();
|
||||
test.throws(function () {
|
||||
OAuth._storePendingCredential(null, cred);
|
||||
});
|
||||
test.throws(function () {
|
||||
OAuth._storePendingCredential(undefined, cred);
|
||||
});
|
||||
Tinytest.add("oauth - null, undefined key for pendingCredential", test => {
|
||||
const cred = Random.id();
|
||||
test.throws(() => OAuth._storePendingCredential(null, cred));
|
||||
test.throws(() => OAuth._storePendingCredential(undefined, cred));
|
||||
});
|
||||
|
||||
Tinytest.add("oauth - pendingCredential handles duplicate key", function (test) {
|
||||
var key = Random.id();
|
||||
var cred = Random.id();
|
||||
Tinytest.add("oauth - pendingCredential handles duplicate key", test => {
|
||||
const key = Random.id();
|
||||
const cred = Random.id();
|
||||
OAuth._storePendingCredential(key, cred);
|
||||
var newCred = Random.id();
|
||||
const newCred = Random.id();
|
||||
OAuth._storePendingCredential(key, newCred);
|
||||
test.equal(OAuth._retrievePendingCredential(key), newCred);
|
||||
});
|
||||
|
||||
Tinytest.add(
|
||||
"oauth - pendingCredential requires credential secret",
|
||||
function (test) {
|
||||
var key = Random.id();
|
||||
var cred = Random.id();
|
||||
var secret = Random.id();
|
||||
OAuth._storePendingCredential(key, cred, secret);
|
||||
test.equal(OAuth._retrievePendingCredential(key), undefined);
|
||||
test.equal(OAuth._retrievePendingCredential(key, secret), cred);
|
||||
}
|
||||
);
|
||||
Tinytest.add("oauth - pendingCredential requires credential secret", test => {
|
||||
const key = Random.id();
|
||||
const cred = Random.id();
|
||||
const secret = Random.id();
|
||||
OAuth._storePendingCredential(key, cred, secret);
|
||||
test.equal(OAuth._retrievePendingCredential(key), undefined);
|
||||
test.equal(OAuth._retrievePendingCredential(key, secret), cred);
|
||||
});
|
||||
|
||||
Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports unspecified ROOT_URL_PATH_PREFIX",
|
||||
function (test) {
|
||||
var res = {
|
||||
writeHead: function () {},
|
||||
end: function (content) {
|
||||
test => {
|
||||
const res = {
|
||||
writeHead: () => {},
|
||||
end: content => {
|
||||
test.matches(
|
||||
content,
|
||||
/\/packages\/oauth\/end_of_popup_response\.js/
|
||||
);
|
||||
}
|
||||
};
|
||||
var details = {
|
||||
const details = {
|
||||
credentials: {},
|
||||
loginStyle: 'popup'
|
||||
};
|
||||
@@ -80,12 +73,12 @@ Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports unspeci
|
||||
);
|
||||
|
||||
Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports ROOT_URL_PATH_PREFIX",
|
||||
function (test) {
|
||||
var rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
|
||||
test => {
|
||||
const rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
|
||||
__meteor_runtime_config__.ROOT_URL_PATH_PREFIX = '/test-root-url-prefix';
|
||||
var res = {
|
||||
writeHead: function () {},
|
||||
end: function (content) {
|
||||
const res = {
|
||||
writeHead: () => {},
|
||||
end: content => {
|
||||
__meteor_runtime_config__.ROOT_URL_PATH_PREFIX = rootUrlPathPrefix;
|
||||
test.matches(
|
||||
content,
|
||||
@@ -93,7 +86,7 @@ Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports ROOT_UR
|
||||
);
|
||||
}
|
||||
};
|
||||
var details = {
|
||||
const details = {
|
||||
credentials: {},
|
||||
loginStyle: 'popup'
|
||||
};
|
||||
@@ -102,17 +95,17 @@ Tinytest.add("oauth - _endOfLoginResponse with popup loginStyle supports ROOT_UR
|
||||
);
|
||||
|
||||
Tinytest.add("oauth - _endOfLoginResponse with redirect loginStyle supports unspecified ROOT_URL_PATH_PREFIX",
|
||||
function (test) {
|
||||
var res = {
|
||||
writeHead: function () {},
|
||||
end: function (content) {
|
||||
test => {
|
||||
const res = {
|
||||
writeHead: () => {},
|
||||
end: content => {
|
||||
test.matches(
|
||||
content,
|
||||
/\/packages\/oauth\/end_of_redirect_response\.js/
|
||||
);
|
||||
}
|
||||
};
|
||||
var details = {
|
||||
const details = {
|
||||
credentials: {},
|
||||
loginStyle: 'redirect',
|
||||
query: {
|
||||
@@ -127,12 +120,12 @@ Tinytest.add("oauth - _endOfLoginResponse with redirect loginStyle supports unsp
|
||||
|
||||
|
||||
Tinytest.add("oauth - _endOfLoginResponse with redirect loginStyle supports ROOT_URL_PATH_PREFIX",
|
||||
function (test) {
|
||||
var rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
|
||||
test => {
|
||||
const rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
|
||||
__meteor_runtime_config__.ROOT_URL_PATH_PREFIX = '/test-root-url-prefix';
|
||||
var res = {
|
||||
writeHead: function () {},
|
||||
end: function (content) {
|
||||
const res = {
|
||||
writeHead: () => {},
|
||||
end: content => {
|
||||
__meteor_runtime_config__.ROOT_URL_PATH_PREFIX = rootUrlPathPrefix;
|
||||
test.matches(
|
||||
content,
|
||||
@@ -140,7 +133,7 @@ Tinytest.add("oauth - _endOfLoginResponse with redirect loginStyle supports ROOT
|
||||
);
|
||||
}
|
||||
};
|
||||
var details = {
|
||||
const details = {
|
||||
credentials: {},
|
||||
loginStyle: 'redirect',
|
||||
query: {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Package.describe({
|
||||
summary: "Common code for OAuth-based services",
|
||||
version: "1.2.1"
|
||||
version: "1.2.2",
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
Package.onUse(api => {
|
||||
api.use('check');
|
||||
api.use('underscore');
|
||||
api.use('ecmascript');
|
||||
|
||||
api.use('routepolicy', 'server');
|
||||
api.use('webapp', 'server');
|
||||
@@ -48,7 +48,7 @@ Package.onUse(function (api) {
|
||||
});
|
||||
|
||||
|
||||
Package.onTest(function (api) {
|
||||
Package.onTest(api => {
|
||||
api.use('tinytest');
|
||||
api.use('random');
|
||||
api.use('service-configuration', 'server');
|
||||
|
||||
@@ -23,13 +23,13 @@ OAuth._pendingCredentials._ensureIndex('createdAt');
|
||||
|
||||
|
||||
// Periodically clear old entries that were never retrieved
|
||||
var _cleanStaleResults = function() {
|
||||
const _cleanStaleResults = () => {
|
||||
// Remove credentials older than 1 minute
|
||||
var timeCutoff = new Date();
|
||||
const timeCutoff = new Date();
|
||||
timeCutoff.setMinutes(timeCutoff.getMinutes() - 1);
|
||||
OAuth._pendingCredentials.remove({ createdAt: { $lt: timeCutoff } });
|
||||
};
|
||||
var _cleanupHandle = Meteor.setInterval(_cleanStaleResults, 60 * 1000);
|
||||
const _cleanupHandle = Meteor.setInterval(_cleanStaleResults, 60 * 1000);
|
||||
|
||||
|
||||
// Stores the key and credential in the _pendingCredentials collection.
|
||||
@@ -40,9 +40,9 @@ var _cleanupHandle = Meteor.setInterval(_cleanStaleResults, 60 * 1000);
|
||||
// @param credentialSecret {string} A secret that must be presented in
|
||||
// addition to the `key` to retrieve the credential
|
||||
//
|
||||
OAuth._storePendingCredential = function (key, credential, credentialSecret) {
|
||||
OAuth._storePendingCredential = (key, credential, credentialSecret = null) => {
|
||||
check(key, String);
|
||||
check(credentialSecret, Match.Optional(String));
|
||||
check(credentialSecret, Match.Maybe(String));
|
||||
|
||||
if (credential instanceof Error) {
|
||||
credential = storableError(credential);
|
||||
@@ -54,11 +54,11 @@ OAuth._storePendingCredential = function (key, credential, credentialSecret) {
|
||||
// to somehow send the same `state` parameter twice during an OAuth
|
||||
// login; we don't want a duplicate key error.
|
||||
OAuth._pendingCredentials.upsert({
|
||||
key: key
|
||||
key,
|
||||
}, {
|
||||
key: key,
|
||||
credential: credential,
|
||||
credentialSecret: credentialSecret || null,
|
||||
key,
|
||||
credential,
|
||||
credentialSecret,
|
||||
createdAt: new Date()
|
||||
});
|
||||
};
|
||||
@@ -69,13 +69,14 @@ OAuth._storePendingCredential = function (key, credential, credentialSecret) {
|
||||
// @param key {string}
|
||||
// @param credentialSecret {string}
|
||||
//
|
||||
OAuth._retrievePendingCredential = function (key, credentialSecret) {
|
||||
OAuth._retrievePendingCredential = (key, credentialSecret = null) => {
|
||||
check(key, String);
|
||||
|
||||
var pendingCredential = OAuth._pendingCredentials.findOne({
|
||||
key: key,
|
||||
credentialSecret: credentialSecret || null
|
||||
const pendingCredential = OAuth._pendingCredentials.findOne({
|
||||
key,
|
||||
credentialSecret,
|
||||
});
|
||||
|
||||
if (pendingCredential) {
|
||||
OAuth._pendingCredentials.remove({ _id: pendingCredential._id });
|
||||
if (pendingCredential.credential.error)
|
||||
@@ -91,11 +92,12 @@ OAuth._retrievePendingCredential = function (key, credentialSecret) {
|
||||
// Convert an Error into an object that can be stored in mongo
|
||||
// Note: A Meteor.Error is reconstructed as a Meteor.Error
|
||||
// All other error classes are reconstructed as a plain Error.
|
||||
var storableError = function(error) {
|
||||
var plainObject = {};
|
||||
Object.getOwnPropertyNames(error).forEach(function(key) {
|
||||
plainObject[key] = error[key];
|
||||
});
|
||||
// TODO: Can we do this more simply with EJSON?
|
||||
const storableError = error => {
|
||||
const plainObject = {};
|
||||
Object.getOwnPropertyNames(error).forEach(
|
||||
key => plainObject[key] = error[key]
|
||||
);
|
||||
|
||||
// Keep track of whether it's a Meteor.Error
|
||||
if(error instanceof Meteor.Error) {
|
||||
@@ -106,8 +108,8 @@ var storableError = function(error) {
|
||||
};
|
||||
|
||||
// Create an error from the error format stored in mongo
|
||||
var recreateError = function(errorDoc) {
|
||||
var error;
|
||||
const recreateError = errorDoc => {
|
||||
let error;
|
||||
|
||||
if (errorDoc.meteorError) {
|
||||
error = new Meteor.Error();
|
||||
@@ -116,9 +118,9 @@ var recreateError = function(errorDoc) {
|
||||
error = new Error();
|
||||
}
|
||||
|
||||
Object.getOwnPropertyNames(errorDoc).forEach(function(key) {
|
||||
error[key] = errorDoc[key];
|
||||
});
|
||||
Object.getOwnPropertyNames(errorDoc).forEach(key =>
|
||||
error[key] = errorDoc[key]
|
||||
);
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user