Auth Adapters refactoring (#3177)
* Moves all authentication providers to Adapter/Auth * refactors specs * Deprecates oauth option in favor of auth option - Deprecates facebookAppIds option (in favor of auth.facebook.appIds) - Adds warnings about the deprecated options * nits
This commit is contained in:
committed by
Arthur Cinader
parent
a9067260fc
commit
c1dcaf1271
@@ -17,6 +17,7 @@ export function loadAdapter(adapter, defaultAdapter, options) {
|
||||
}
|
||||
}
|
||||
} else if (typeof adapter === "string") {
|
||||
/* eslint-disable */
|
||||
adapter = require(adapter);
|
||||
// If it's define as a module, get the default
|
||||
if (adapter.default) {
|
||||
|
||||
22
src/Adapters/Auth/AuthAdapter.js
Normal file
22
src/Adapters/Auth/AuthAdapter.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
export class AuthAdapter {
|
||||
|
||||
/*
|
||||
@param appIds: the specified app ids in the configuration
|
||||
@param authData: the client provided authData
|
||||
@returns a promise that resolves if the applicationId is valid
|
||||
*/
|
||||
validateAppId(appIds, authData) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
/*
|
||||
@param authData: the client provided authData
|
||||
@param options: additional options
|
||||
*/
|
||||
validateAuthData(authData, options) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthAdapter;
|
||||
99
src/Adapters/Auth/index.js
Executable file
99
src/Adapters/Auth/index.js
Executable file
@@ -0,0 +1,99 @@
|
||||
import loadAdapter from '../AdapterLoader';
|
||||
|
||||
const facebook = require('./facebook');
|
||||
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 anonymous = {
|
||||
validateAuthData: () => {
|
||||
return Promise.resolve();
|
||||
},
|
||||
validateAppId: () => {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
const providers = {
|
||||
facebook,
|
||||
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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(authOptions = {}, enableAnonymousUsers = true) {
|
||||
let _enableAnonymousUsers = enableAnonymousUsers;
|
||||
let setEnableAnonymousUsers = function(enable) {
|
||||
_enableAnonymousUsers = enable;
|
||||
}
|
||||
// To handle the test cases on configuration
|
||||
let getValidatorForProvider = function(provider) {
|
||||
|
||||
if (provider === 'anonymous' && !_enableAnonymousUsers) {
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultAdapter = providers[provider];
|
||||
let adapter = defaultAdapter;
|
||||
const providerOptions = authOptions[provider];
|
||||
|
||||
if (!defaultAdapter && !providerOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
const appIds = providerOptions ? providerOptions.appIds : undefined;
|
||||
|
||||
// Try the configuration methods
|
||||
if (providerOptions) {
|
||||
const optionalAdapter = loadAdapter(providerOptions, undefined, providerOptions);
|
||||
if (optionalAdapter) {
|
||||
adapter = optionalAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
if (!adapter.validateAuthData || !adapter.validateAppId) {
|
||||
return;
|
||||
}
|
||||
|
||||
return authDataValidator(adapter, appIds, providerOptions);
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
getValidatorForProvider,
|
||||
setEnableAnonymousUsers,
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Helper functions for accessing the twitter API.
|
||||
var OAuth = require('./OAuth1Client');
|
||||
var Parse = require('parse/node').Parse;
|
||||
var logger = require('../logger').default;
|
||||
var logger = require('../../logger').default;
|
||||
|
||||
// Returns a promise that fulfills iff this user id is valid.
|
||||
function validateAuthData(authData, options) {
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
var https = require('https');
|
||||
var Parse = require('parse/node').Parse;
|
||||
var logger = require('../logger').default;
|
||||
var logger = require('../../logger').default;
|
||||
|
||||
// Returns a promise that fulfills iff this user id is valid.
|
||||
function validateAuthData(authData, params) {
|
||||
@@ -32,7 +32,6 @@ export class Config {
|
||||
this.restAPIKey = cacheInfo.restAPIKey;
|
||||
this.webhookKey = cacheInfo.webhookKey;
|
||||
this.fileKey = cacheInfo.fileKey;
|
||||
this.facebookAppIds = cacheInfo.facebookAppIds;
|
||||
this.allowClientClassCreation = cacheInfo.allowClientClassCreation;
|
||||
this.userSensitiveFields = cacheInfo.userSensitiveFields;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ var batch = require('./batch'),
|
||||
Parse = require('parse/node').Parse,
|
||||
path = require('path'),
|
||||
url = require('url'),
|
||||
authDataManager = require('./authDataManager');
|
||||
authDataManager = require('./Adapters/Auth');
|
||||
|
||||
import defaults from './defaults';
|
||||
import * as logging from './logger';
|
||||
@@ -73,8 +73,6 @@ addParseCloud();
|
||||
// to register your cloud code hooks and functions.
|
||||
// "appId": the application id to host
|
||||
// "masterKey": the master key for requests to this app
|
||||
// "facebookAppIds": an array of valid Facebook Application IDs, required
|
||||
// if using Facebook login
|
||||
// "collectionPrefix": optional prefix for database collection names
|
||||
// "fileKey": optional key from Parse dashboard for supporting older files
|
||||
// hosted by Parse
|
||||
@@ -112,11 +110,11 @@ class ParseServer {
|
||||
restAPIKey,
|
||||
webhookKey,
|
||||
fileKey,
|
||||
facebookAppIds = [],
|
||||
userSensitiveFields = [],
|
||||
enableAnonymousUsers = defaults.enableAnonymousUsers,
|
||||
allowClientClassCreation = defaults.allowClientClassCreation,
|
||||
oauth = {},
|
||||
auth = {},
|
||||
serverURL = requiredParameter('You must provide a serverURL!'),
|
||||
maxUploadSize = defaults.maxUploadSize,
|
||||
verifyUserEmails = defaults.verifyUserEmails,
|
||||
@@ -191,6 +189,17 @@ class ParseServer {
|
||||
|
||||
const dbInitPromise = databaseController.performInitialization();
|
||||
|
||||
if (Object.keys(oauth).length > 0) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn('oauth option is deprecated and will be removed in a future release, please use auth option instead');
|
||||
if (Object.keys(auth).length > 0) {
|
||||
console.warn('You should use only the auth option.');
|
||||
}
|
||||
/* eslint-enable */
|
||||
}
|
||||
|
||||
auth = Object.assign({}, oauth, auth);
|
||||
|
||||
AppCache.put(appId, {
|
||||
appId,
|
||||
masterKey: masterKey,
|
||||
@@ -202,7 +211,6 @@ class ParseServer {
|
||||
restAPIKey: restAPIKey,
|
||||
webhookKey: webhookKey,
|
||||
fileKey: fileKey,
|
||||
facebookAppIds: facebookAppIds,
|
||||
analyticsController: analyticsController,
|
||||
cacheController: cacheController,
|
||||
filesController: filesController,
|
||||
@@ -216,7 +224,7 @@ class ParseServer {
|
||||
accountLockout: accountLockout,
|
||||
passwordPolicy: passwordPolicy,
|
||||
allowClientClassCreation: allowClientClassCreation,
|
||||
authDataManager: authDataManager(oauth, enableAnonymousUsers),
|
||||
authDataManager: authDataManager(auth, enableAnonymousUsers),
|
||||
appName: appName,
|
||||
publicServerURL: publicServerURL,
|
||||
customPages: customPages,
|
||||
@@ -232,11 +240,6 @@ class ParseServer {
|
||||
userSensitiveFields
|
||||
});
|
||||
|
||||
// To maintain compatibility. TODO: Remove in some version that breaks backwards compatibility
|
||||
if (process.env.FACEBOOK_APP_ID) {
|
||||
AppCache.get(appId)['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
|
||||
}
|
||||
|
||||
Config.validate(AppCache.get(appId));
|
||||
this.config = AppCache.get(appId);
|
||||
Config.setupPasswordValidator(this.config.passwordPolicy);
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
let facebook = require('./facebook');
|
||||
let instagram = require("./instagram");
|
||||
let linkedin = require("./linkedin");
|
||||
let meetup = require("./meetup");
|
||||
let google = require("./google");
|
||||
let github = require("./github");
|
||||
let twitter = require("./twitter");
|
||||
let spotify = require("./spotify");
|
||||
let digits = require("./twitter"); // digits tokens are validated by twitter
|
||||
let janrainengage = require("./janrainengage");
|
||||
let janraincapture = require("./janraincapture");
|
||||
let vkontakte = require("./vkontakte");
|
||||
let qq = require("./qq");
|
||||
let wechat = require("./wechat");
|
||||
let weibo = require("./weibo");
|
||||
|
||||
let anonymous = {
|
||||
validateAuthData: () => {
|
||||
return Promise.resolve();
|
||||
},
|
||||
validateAppId: () => {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
let providers = {
|
||||
facebook,
|
||||
instagram,
|
||||
linkedin,
|
||||
meetup,
|
||||
google,
|
||||
github,
|
||||
twitter,
|
||||
spotify,
|
||||
anonymous,
|
||||
digits,
|
||||
janrainengage,
|
||||
janraincapture,
|
||||
vkontakte,
|
||||
qq,
|
||||
wechat,
|
||||
weibo
|
||||
}
|
||||
|
||||
module.exports = function(oauthOptions = {}, enableAnonymousUsers = true) {
|
||||
let _enableAnonymousUsers = enableAnonymousUsers;
|
||||
let setEnableAnonymousUsers = function(enable) {
|
||||
_enableAnonymousUsers = enable;
|
||||
}
|
||||
// To handle the test cases on configuration
|
||||
let getValidatorForProvider = function(provider) {
|
||||
|
||||
if (provider === 'anonymous' && !_enableAnonymousUsers) {
|
||||
return;
|
||||
}
|
||||
|
||||
let defaultProvider = providers[provider];
|
||||
let optionalProvider = oauthOptions[provider];
|
||||
|
||||
if (!defaultProvider && !optionalProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
let appIds;
|
||||
if (optionalProvider) {
|
||||
appIds = optionalProvider.appIds;
|
||||
}
|
||||
|
||||
var validateAuthData;
|
||||
var validateAppId;
|
||||
|
||||
if (defaultProvider) {
|
||||
validateAuthData = defaultProvider.validateAuthData;
|
||||
validateAppId = defaultProvider.validateAppId;
|
||||
}
|
||||
|
||||
// Try the configuration methods
|
||||
if (optionalProvider) {
|
||||
if (optionalProvider.module) {
|
||||
validateAuthData = require(optionalProvider.module).validateAuthData;
|
||||
validateAppId = require(optionalProvider.module).validateAppId;
|
||||
}
|
||||
|
||||
if (optionalProvider.validateAuthData) {
|
||||
validateAuthData = optionalProvider.validateAuthData;
|
||||
}
|
||||
if (optionalProvider.validateAppId) {
|
||||
validateAppId = optionalProvider.validateAppId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validateAuthData || !validateAppId) {
|
||||
return;
|
||||
}
|
||||
|
||||
return function(authData) {
|
||||
return validateAuthData(authData, optionalProvider).then(() => {
|
||||
if (appIds) {
|
||||
return validateAppId(appIds, authData, optionalProvider);
|
||||
}
|
||||
return Promise.resolve();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
getValidatorForProvider,
|
||||
setEnableAnonymousUsers,
|
||||
})
|
||||
}
|
||||
@@ -83,7 +83,12 @@ export default {
|
||||
},
|
||||
"oauth": {
|
||||
env: "PARSE_SERVER_OAUTH_PROVIDERS",
|
||||
help: "Configuration for your oAuth providers, as stringified JSON. See https://github.com/ParsePlatform/parse-server/wiki/Parse-Server-Guide#oauth",
|
||||
help: "[DEPRECATED (use auth option)] Configuration for your oAuth providers, as stringified JSON. See https://github.com/ParsePlatform/parse-server/wiki/Parse-Server-Guide#oauth",
|
||||
action: objectParser
|
||||
},
|
||||
"auth": {
|
||||
env: "PARSE_SERVER_AUTH_PROVIDERS",
|
||||
help: "Configuration for your authentication providers, as stringified JSON. See https://github.com/ParsePlatform/parse-server/wiki/Parse-Server-Guide#oauth",
|
||||
action: objectParser
|
||||
},
|
||||
"fileKey": {
|
||||
@@ -92,9 +97,15 @@ export default {
|
||||
},
|
||||
"facebookAppIds": {
|
||||
env: "PARSE_SERVER_FACEBOOK_APP_IDS",
|
||||
help: "Comma separated list for your facebook app Ids",
|
||||
type: "list",
|
||||
action: arrayParser
|
||||
help: "[DEPRECATED (use auth option)]",
|
||||
action: function() {
|
||||
throw 'facebookAppIds is deprecated, please use { auth: \
|
||||
{facebook: \
|
||||
{ appIds: [] } \
|
||||
}\
|
||||
}\
|
||||
}';
|
||||
}
|
||||
},
|
||||
"enableAnonymousUsers": {
|
||||
env: "PARSE_SERVER_ENABLE_ANON_USERS",
|
||||
|
||||
Reference in New Issue
Block a user