* added an RFC 7662 compliant OAuth2 auth adapter * forgot to add the actual auth adapter to the previous commit * fixed lint errors * * added test coverage * changed option names in auth adapter from snake case to camel case * added underscore prefix to helper function names * merged consecutive logger calls into one call and use JSON.stringify() to convert JSON objects to strings * changed error handling (ParseErrors are no longer thrown, but returned) * added description of the "debug" option and added this option to the tests too * added a check of the "debug" option to the unittests and replaced require() of the logger with an import (the former does not work correctly) * added AuthAdapter based auth adapter runtime validation to src/Adapters/Auth/index.js, added capability to define arbitrary providernames with an "adapter" property in auth config, replaced various "var" keywords with "const" in oauth2.js * incorporated changes requested by flovilmart (mainly that oauth2 is now not a standalone adapter, but can be selected by setting the "oauth2" property to true in auth config * modified oauth2 adapter as requested by flovilmart * bugfix: defaultAdapter can be null in loadAuthAdapter() of index.js (my change broke the tests) * added TODO on need for a validateAdapter() to validate auth adapters * test cases and cleanup
132 lines
3.3 KiB
JavaScript
Executable File
132 lines
3.3 KiB
JavaScript
Executable File
import loadAdapter from '../AdapterLoader';
|
|
|
|
const facebook = require('./facebook');
|
|
const facebookaccountkit = require('./facebookaccountkit');
|
|
const instagram = require('./instagram');
|
|
const linkedin = require('./linkedin');
|
|
const meetup = require('./meetup');
|
|
const google = require('./google');
|
|
const github = require('./github');
|
|
const twitter = require('./twitter');
|
|
const spotify = require('./spotify');
|
|
const digits = require('./twitter'); // digits tokens are validated by twitter
|
|
const janrainengage = require('./janrainengage');
|
|
const janraincapture = require('./janraincapture');
|
|
const vkontakte = require('./vkontakte');
|
|
const qq = require('./qq');
|
|
const wechat = require('./wechat');
|
|
const weibo = require('./weibo');
|
|
const oauth2 = require('./oauth2');
|
|
|
|
const anonymous = {
|
|
validateAuthData: () => {
|
|
return Promise.resolve();
|
|
},
|
|
validateAppId: () => {
|
|
return Promise.resolve();
|
|
},
|
|
};
|
|
|
|
const providers = {
|
|
facebook,
|
|
facebookaccountkit,
|
|
instagram,
|
|
linkedin,
|
|
meetup,
|
|
google,
|
|
github,
|
|
twitter,
|
|
spotify,
|
|
anonymous,
|
|
digits,
|
|
janrainengage,
|
|
janraincapture,
|
|
vkontakte,
|
|
qq,
|
|
wechat,
|
|
weibo,
|
|
};
|
|
|
|
function authDataValidator(adapter, appIds, options) {
|
|
return function(authData) {
|
|
return adapter.validateAuthData(authData, options).then(() => {
|
|
if (appIds) {
|
|
return adapter.validateAppId(appIds, authData, options);
|
|
}
|
|
return Promise.resolve();
|
|
});
|
|
};
|
|
}
|
|
|
|
function loadAuthAdapter(provider, authOptions) {
|
|
let defaultAdapter = providers[provider];
|
|
const providerOptions = authOptions[provider];
|
|
if (
|
|
providerOptions &&
|
|
providerOptions.hasOwnProperty('oauth2') &&
|
|
providerOptions['oauth2'] === true
|
|
) {
|
|
defaultAdapter = oauth2;
|
|
}
|
|
|
|
if (!defaultAdapter && !providerOptions) {
|
|
return;
|
|
}
|
|
|
|
const adapter = Object.assign({}, defaultAdapter);
|
|
const appIds = providerOptions ? providerOptions.appIds : undefined;
|
|
|
|
// Try the configuration methods
|
|
if (providerOptions) {
|
|
const optionalAdapter = loadAdapter(
|
|
providerOptions,
|
|
undefined,
|
|
providerOptions
|
|
);
|
|
if (optionalAdapter) {
|
|
['validateAuthData', 'validateAppId'].forEach(key => {
|
|
if (optionalAdapter[key]) {
|
|
adapter[key] = optionalAdapter[key];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// TODO: create a new module from validateAdapter() in
|
|
// src/Controllers/AdaptableController.js so we can use it here for adapter
|
|
// validation based on the src/Adapters/Auth/AuthAdapter.js expected class
|
|
// signature.
|
|
if (!adapter.validateAuthData || !adapter.validateAppId) {
|
|
return;
|
|
}
|
|
|
|
return { adapter, appIds, providerOptions };
|
|
}
|
|
|
|
module.exports = function(authOptions = {}, enableAnonymousUsers = true) {
|
|
let _enableAnonymousUsers = enableAnonymousUsers;
|
|
const setEnableAnonymousUsers = function(enable) {
|
|
_enableAnonymousUsers = enable;
|
|
};
|
|
// To handle the test cases on configuration
|
|
const getValidatorForProvider = function(provider) {
|
|
if (provider === 'anonymous' && !_enableAnonymousUsers) {
|
|
return;
|
|
}
|
|
|
|
const { adapter, appIds, providerOptions } = loadAuthAdapter(
|
|
provider,
|
|
authOptions
|
|
);
|
|
|
|
return authDataValidator(adapter, appIds, providerOptions);
|
|
};
|
|
|
|
return Object.freeze({
|
|
getValidatorForProvider,
|
|
setEnableAnonymousUsers,
|
|
});
|
|
};
|
|
|
|
module.exports.loadAuthAdapter = loadAuthAdapter;
|