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
@@ -1,145 +1,13 @@
|
||||
var OAuth = require("../src/authDataManager/OAuth1Client");
|
||||
var request = require('request');
|
||||
var Config = require("../src/Config");
|
||||
var defaultColumns = require('../src/Controllers/SchemaController').defaultColumns;
|
||||
var authenticationLoader = require('../src/Adapters/Auth');
|
||||
var path = require('path');
|
||||
|
||||
describe('OAuth', function() {
|
||||
it("Nonce should have right length", (done) => {
|
||||
jequal(OAuth.nonce().length, 30);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build parameter string", (done) => {
|
||||
var string = OAuth.buildParameterString({c:1, a:2, b:3})
|
||||
jequal(string, "a=2&b=3&c=1");
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build empty parameter string", (done) => {
|
||||
var string = OAuth.buildParameterString()
|
||||
jequal(string, "");
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build signature string", (done) => {
|
||||
var string = OAuth.buildSignatureString("get", "http://dummy.com", "");
|
||||
jequal(string, "GET&http%3A%2F%2Fdummy.com&");
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly generate request signature", (done) => {
|
||||
var request = {
|
||||
host: "dummy.com",
|
||||
path: "path"
|
||||
};
|
||||
|
||||
var oauth_params = {
|
||||
oauth_timestamp: 123450000,
|
||||
oauth_nonce: "AAAAAAAAAAAAAAAAA",
|
||||
oauth_consumer_key: "hello",
|
||||
oauth_token: "token"
|
||||
};
|
||||
|
||||
var consumer_secret = "world";
|
||||
var auth_token_secret = "secret";
|
||||
request = OAuth.signRequest(request, oauth_params, consumer_secret, auth_token_secret);
|
||||
jequal(request.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="8K95bpQcDi9Nd2GkhumTVcw4%2BXw%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"');
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build request", (done) => {
|
||||
var options = {
|
||||
host: "dummy.com",
|
||||
consumer_key: "hello",
|
||||
consumer_secret: "world",
|
||||
auth_token: "token",
|
||||
auth_token_secret: "secret",
|
||||
// Custom oauth params for tests
|
||||
oauth_params: {
|
||||
oauth_timestamp: 123450000,
|
||||
oauth_nonce: "AAAAAAAAAAAAAAAAA"
|
||||
}
|
||||
};
|
||||
var path = "path";
|
||||
var method = "get";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
var req = oauthClient.buildRequest(method, path, {"query": "param"});
|
||||
|
||||
jequal(req.host, options.host);
|
||||
jequal(req.path, "/"+path+"?query=param");
|
||||
jequal(req.method, "GET");
|
||||
jequal(req.headers['Content-Type'], 'application/x-www-form-urlencoded');
|
||||
jequal(req.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="wNkyEkDE%2F0JZ2idmqyrgHdvC0rs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"')
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
function validateCannotAuthenticateError(data, done) {
|
||||
jequal(typeof data, "object");
|
||||
jequal(typeof data.errors, "object");
|
||||
var errors = data.errors;
|
||||
jequal(typeof errors[0], "object");
|
||||
// Cannot authenticate error
|
||||
jequal(errors[0].code, 32);
|
||||
done();
|
||||
}
|
||||
|
||||
it("Should fail a GET request", (done) => {
|
||||
var options = {
|
||||
host: "api.twitter.com",
|
||||
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
};
|
||||
var path = "/1.1/help/configuration.json";
|
||||
var params = {"lang": "en"};
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.get(path, params).then(function(data){
|
||||
validateCannotAuthenticateError(data, done);
|
||||
})
|
||||
});
|
||||
|
||||
it("Should fail a POST request", (done) => {
|
||||
var options = {
|
||||
host: "api.twitter.com",
|
||||
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
};
|
||||
var body = {
|
||||
lang: "en"
|
||||
};
|
||||
var path = "/1.1/account/settings.json";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.post(path, null, body).then(function(data){
|
||||
validateCannotAuthenticateError(data, done);
|
||||
})
|
||||
});
|
||||
|
||||
it("Should fail a request", (done) => {
|
||||
var options = {
|
||||
host: "localhost",
|
||||
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
};
|
||||
var body = {
|
||||
lang: "en"
|
||||
};
|
||||
var path = "/";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.post(path, null, body).then(function(){
|
||||
jequal(false, true);
|
||||
done();
|
||||
}).catch(function(){
|
||||
jequal(true, true);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
describe('AuthenticationProviers', function() {
|
||||
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter", "janrainengage", "janraincapture", "vkontakte"].map(function(providerName){
|
||||
it("Should validate structure of "+providerName, (done) => {
|
||||
var provider = require("../src/authDataManager/"+providerName);
|
||||
var provider = require("../src/Adapters/Auth/"+providerName);
|
||||
jequal(typeof provider.validateAuthData, "function");
|
||||
jequal(typeof provider.validateAppId, "function");
|
||||
jequal(provider.validateAuthData({}, {}).constructor, Promise.prototype.constructor);
|
||||
@@ -325,5 +193,90 @@ describe('OAuth', function() {
|
||||
});
|
||||
});
|
||||
|
||||
function validateValidator(validator) {
|
||||
expect(typeof validator).toBe('function');
|
||||
}
|
||||
|
||||
function validateAuthenticationHandler(authenticatonHandler) {
|
||||
expect(authenticatonHandler).not.toBeUndefined();
|
||||
expect(typeof authenticatonHandler.getValidatorForProvider).toBe('function');
|
||||
expect(typeof authenticatonHandler.getValidatorForProvider).toBe('function');
|
||||
}
|
||||
|
||||
it('properly loads custom adapter', (done) => {
|
||||
var validAuthData = {
|
||||
id: 'hello',
|
||||
token: 'world'
|
||||
}
|
||||
let adapter = {
|
||||
validateAppId: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
validateAuthData: function(authData) {
|
||||
if (authData.id == validAuthData.id && authData.token == validAuthData.token) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
};
|
||||
|
||||
let authDataSpy = spyOn(adapter, 'validateAuthData').and.callThrough();
|
||||
let appIdSpy = spyOn(adapter, 'validateAppId').and.callThrough();
|
||||
|
||||
let authenticationHandler = authenticationLoader({
|
||||
customAuthentication: adapter
|
||||
});
|
||||
|
||||
validateAuthenticationHandler(authenticationHandler);
|
||||
let validator = authenticationHandler.getValidatorForProvider('customAuthentication');
|
||||
validateValidator(validator);
|
||||
|
||||
validator(validAuthData).then(() => {
|
||||
expect(authDataSpy).toHaveBeenCalled();
|
||||
// AppIds are not provided in the adapter, should not be called
|
||||
expect(appIdSpy).not.toHaveBeenCalled();
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('properly loads custom adapter module object', (done) => {
|
||||
let authenticationHandler = authenticationLoader({
|
||||
customAuthentication: path.resolve('./spec/support/CustomAuth.js')
|
||||
});
|
||||
|
||||
validateAuthenticationHandler(authenticationHandler);
|
||||
let validator = authenticationHandler.getValidatorForProvider('customAuthentication');
|
||||
validateValidator(validator);
|
||||
|
||||
validator({
|
||||
token: 'my-token'
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('properly loads custom adapter module object', (done) => {
|
||||
let authenticationHandler = authenticationLoader({
|
||||
customAuthentication: { module: path.resolve('./spec/support/CustomAuthFunction.js'), options: { token: 'valid-token' }}
|
||||
});
|
||||
|
||||
validateAuthenticationHandler(authenticationHandler);
|
||||
let validator = authenticationHandler.getValidatorForProvider('customAuthentication');
|
||||
validateValidator(validator);
|
||||
|
||||
validator({
|
||||
token: 'valid-token'
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
});
|
||||
136
spec/OAuth1.spec.js
Normal file
136
spec/OAuth1.spec.js
Normal file
@@ -0,0 +1,136 @@
|
||||
var OAuth = require("../src/Adapters/Auth/OAuth1Client");
|
||||
|
||||
describe('OAuth', function() {
|
||||
it("Nonce should have right length", (done) => {
|
||||
jequal(OAuth.nonce().length, 30);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build parameter string", (done) => {
|
||||
var string = OAuth.buildParameterString({c:1, a:2, b:3})
|
||||
jequal(string, "a=2&b=3&c=1");
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build empty parameter string", (done) => {
|
||||
var string = OAuth.buildParameterString()
|
||||
jequal(string, "");
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build signature string", (done) => {
|
||||
var string = OAuth.buildSignatureString("get", "http://dummy.com", "");
|
||||
jequal(string, "GET&http%3A%2F%2Fdummy.com&");
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly generate request signature", (done) => {
|
||||
var request = {
|
||||
host: "dummy.com",
|
||||
path: "path"
|
||||
};
|
||||
|
||||
var oauth_params = {
|
||||
oauth_timestamp: 123450000,
|
||||
oauth_nonce: "AAAAAAAAAAAAAAAAA",
|
||||
oauth_consumer_key: "hello",
|
||||
oauth_token: "token"
|
||||
};
|
||||
|
||||
var consumer_secret = "world";
|
||||
var auth_token_secret = "secret";
|
||||
request = OAuth.signRequest(request, oauth_params, consumer_secret, auth_token_secret);
|
||||
jequal(request.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="8K95bpQcDi9Nd2GkhumTVcw4%2BXw%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"');
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should properly build request", (done) => {
|
||||
var options = {
|
||||
host: "dummy.com",
|
||||
consumer_key: "hello",
|
||||
consumer_secret: "world",
|
||||
auth_token: "token",
|
||||
auth_token_secret: "secret",
|
||||
// Custom oauth params for tests
|
||||
oauth_params: {
|
||||
oauth_timestamp: 123450000,
|
||||
oauth_nonce: "AAAAAAAAAAAAAAAAA"
|
||||
}
|
||||
};
|
||||
var path = "path";
|
||||
var method = "get";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
var req = oauthClient.buildRequest(method, path, {"query": "param"});
|
||||
|
||||
jequal(req.host, options.host);
|
||||
jequal(req.path, "/"+path+"?query=param");
|
||||
jequal(req.method, "GET");
|
||||
jequal(req.headers['Content-Type'], 'application/x-www-form-urlencoded');
|
||||
jequal(req.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="wNkyEkDE%2F0JZ2idmqyrgHdvC0rs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"')
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
function validateCannotAuthenticateError(data, done) {
|
||||
jequal(typeof data, "object");
|
||||
jequal(typeof data.errors, "object");
|
||||
var errors = data.errors;
|
||||
jequal(typeof errors[0], "object");
|
||||
// Cannot authenticate error
|
||||
jequal(errors[0].code, 32);
|
||||
done();
|
||||
}
|
||||
|
||||
it("Should fail a GET request", (done) => {
|
||||
var options = {
|
||||
host: "api.twitter.com",
|
||||
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
};
|
||||
var path = "/1.1/help/configuration.json";
|
||||
var params = {"lang": "en"};
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.get(path, params).then(function(data){
|
||||
validateCannotAuthenticateError(data, done);
|
||||
})
|
||||
});
|
||||
|
||||
it("Should fail a POST request", (done) => {
|
||||
var options = {
|
||||
host: "api.twitter.com",
|
||||
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
};
|
||||
var body = {
|
||||
lang: "en"
|
||||
};
|
||||
var path = "/1.1/account/settings.json";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.post(path, null, body).then(function(data){
|
||||
validateCannotAuthenticateError(data, done);
|
||||
})
|
||||
});
|
||||
|
||||
it("Should fail a request", (done) => {
|
||||
var options = {
|
||||
host: "localhost",
|
||||
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
};
|
||||
var body = {
|
||||
lang: "en"
|
||||
};
|
||||
var path = "/";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.post(path, null, body).then(function(){
|
||||
jequal(false, true);
|
||||
done();
|
||||
}).catch(function(){
|
||||
jequal(true, true);
|
||||
done();
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
let twitter = require('../src/authDataManager/twitter');
|
||||
let twitter = require('../src/Adapters/Auth/twitter');
|
||||
|
||||
describe('Twitter Auth', () => {
|
||||
it('should use the proper configuration', () => {
|
||||
|
||||
@@ -102,7 +102,7 @@ var defaultConfiguration = {
|
||||
bundleId: 'bundleId',
|
||||
}
|
||||
},
|
||||
oauth: { // Override the facebook provider
|
||||
auth: { // Override the facebook provider
|
||||
facebook: mockFacebook(),
|
||||
myoauth: {
|
||||
module: path.resolve(__dirname, "myoauth") // relative path as it's run from src
|
||||
|
||||
12
spec/support/CustomAuth.js
Normal file
12
spec/support/CustomAuth.js
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
module.exports = {
|
||||
validateAppId: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
validateAuthData: function(authData) {
|
||||
if (authData.token == 'my-token') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
14
spec/support/CustomAuthFunction.js
Normal file
14
spec/support/CustomAuthFunction.js
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
module.exports = function(validAuthData) {
|
||||
return {
|
||||
validateAppId: function() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
validateAuthData: function(authData) {
|
||||
if (authData.token == validAuthData.token) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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