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 request = require('request');
|
||||||
var Config = require("../src/Config");
|
var Config = require("../src/Config");
|
||||||
var defaultColumns = require('../src/Controllers/SchemaController').defaultColumns;
|
var defaultColumns = require('../src/Controllers/SchemaController').defaultColumns;
|
||||||
|
var authenticationLoader = require('../src/Adapters/Auth');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
describe('OAuth', function() {
|
describe('AuthenticationProviers', 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();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter", "janrainengage", "janraincapture", "vkontakte"].map(function(providerName){
|
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter", "janrainengage", "janraincapture", "vkontakte"].map(function(providerName){
|
||||||
it("Should validate structure of "+providerName, (done) => {
|
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.validateAuthData, "function");
|
||||||
jequal(typeof provider.validateAppId, "function");
|
jequal(typeof provider.validateAppId, "function");
|
||||||
jequal(provider.validateAuthData({}, {}).constructor, Promise.prototype.constructor);
|
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', () => {
|
describe('Twitter Auth', () => {
|
||||||
it('should use the proper configuration', () => {
|
it('should use the proper configuration', () => {
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ var defaultConfiguration = {
|
|||||||
bundleId: 'bundleId',
|
bundleId: 'bundleId',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
oauth: { // Override the facebook provider
|
auth: { // Override the facebook provider
|
||||||
facebook: mockFacebook(),
|
facebook: mockFacebook(),
|
||||||
myoauth: {
|
myoauth: {
|
||||||
module: path.resolve(__dirname, "myoauth") // relative path as it's run from src
|
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") {
|
} else if (typeof adapter === "string") {
|
||||||
|
/* eslint-disable */
|
||||||
adapter = require(adapter);
|
adapter = require(adapter);
|
||||||
// If it's define as a module, get the default
|
// If it's define as a module, get the default
|
||||||
if (adapter.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.
|
// Helper functions for accessing the twitter API.
|
||||||
var OAuth = require('./OAuth1Client');
|
var OAuth = require('./OAuth1Client');
|
||||||
var Parse = require('parse/node').Parse;
|
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.
|
// Returns a promise that fulfills iff this user id is valid.
|
||||||
function validateAuthData(authData, options) {
|
function validateAuthData(authData, options) {
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
var https = require('https');
|
var https = require('https');
|
||||||
var Parse = require('parse/node').Parse;
|
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.
|
// Returns a promise that fulfills iff this user id is valid.
|
||||||
function validateAuthData(authData, params) {
|
function validateAuthData(authData, params) {
|
||||||
@@ -32,7 +32,6 @@ export class Config {
|
|||||||
this.restAPIKey = cacheInfo.restAPIKey;
|
this.restAPIKey = cacheInfo.restAPIKey;
|
||||||
this.webhookKey = cacheInfo.webhookKey;
|
this.webhookKey = cacheInfo.webhookKey;
|
||||||
this.fileKey = cacheInfo.fileKey;
|
this.fileKey = cacheInfo.fileKey;
|
||||||
this.facebookAppIds = cacheInfo.facebookAppIds;
|
|
||||||
this.allowClientClassCreation = cacheInfo.allowClientClassCreation;
|
this.allowClientClassCreation = cacheInfo.allowClientClassCreation;
|
||||||
this.userSensitiveFields = cacheInfo.userSensitiveFields;
|
this.userSensitiveFields = cacheInfo.userSensitiveFields;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ var batch = require('./batch'),
|
|||||||
Parse = require('parse/node').Parse,
|
Parse = require('parse/node').Parse,
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
authDataManager = require('./authDataManager');
|
authDataManager = require('./Adapters/Auth');
|
||||||
|
|
||||||
import defaults from './defaults';
|
import defaults from './defaults';
|
||||||
import * as logging from './logger';
|
import * as logging from './logger';
|
||||||
@@ -73,8 +73,6 @@ addParseCloud();
|
|||||||
// to register your cloud code hooks and functions.
|
// to register your cloud code hooks and functions.
|
||||||
// "appId": the application id to host
|
// "appId": the application id to host
|
||||||
// "masterKey": the master key for requests to this app
|
// "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
|
// "collectionPrefix": optional prefix for database collection names
|
||||||
// "fileKey": optional key from Parse dashboard for supporting older files
|
// "fileKey": optional key from Parse dashboard for supporting older files
|
||||||
// hosted by Parse
|
// hosted by Parse
|
||||||
@@ -112,11 +110,11 @@ class ParseServer {
|
|||||||
restAPIKey,
|
restAPIKey,
|
||||||
webhookKey,
|
webhookKey,
|
||||||
fileKey,
|
fileKey,
|
||||||
facebookAppIds = [],
|
|
||||||
userSensitiveFields = [],
|
userSensitiveFields = [],
|
||||||
enableAnonymousUsers = defaults.enableAnonymousUsers,
|
enableAnonymousUsers = defaults.enableAnonymousUsers,
|
||||||
allowClientClassCreation = defaults.allowClientClassCreation,
|
allowClientClassCreation = defaults.allowClientClassCreation,
|
||||||
oauth = {},
|
oauth = {},
|
||||||
|
auth = {},
|
||||||
serverURL = requiredParameter('You must provide a serverURL!'),
|
serverURL = requiredParameter('You must provide a serverURL!'),
|
||||||
maxUploadSize = defaults.maxUploadSize,
|
maxUploadSize = defaults.maxUploadSize,
|
||||||
verifyUserEmails = defaults.verifyUserEmails,
|
verifyUserEmails = defaults.verifyUserEmails,
|
||||||
@@ -191,6 +189,17 @@ class ParseServer {
|
|||||||
|
|
||||||
const dbInitPromise = databaseController.performInitialization();
|
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, {
|
AppCache.put(appId, {
|
||||||
appId,
|
appId,
|
||||||
masterKey: masterKey,
|
masterKey: masterKey,
|
||||||
@@ -202,7 +211,6 @@ class ParseServer {
|
|||||||
restAPIKey: restAPIKey,
|
restAPIKey: restAPIKey,
|
||||||
webhookKey: webhookKey,
|
webhookKey: webhookKey,
|
||||||
fileKey: fileKey,
|
fileKey: fileKey,
|
||||||
facebookAppIds: facebookAppIds,
|
|
||||||
analyticsController: analyticsController,
|
analyticsController: analyticsController,
|
||||||
cacheController: cacheController,
|
cacheController: cacheController,
|
||||||
filesController: filesController,
|
filesController: filesController,
|
||||||
@@ -216,7 +224,7 @@ class ParseServer {
|
|||||||
accountLockout: accountLockout,
|
accountLockout: accountLockout,
|
||||||
passwordPolicy: passwordPolicy,
|
passwordPolicy: passwordPolicy,
|
||||||
allowClientClassCreation: allowClientClassCreation,
|
allowClientClassCreation: allowClientClassCreation,
|
||||||
authDataManager: authDataManager(oauth, enableAnonymousUsers),
|
authDataManager: authDataManager(auth, enableAnonymousUsers),
|
||||||
appName: appName,
|
appName: appName,
|
||||||
publicServerURL: publicServerURL,
|
publicServerURL: publicServerURL,
|
||||||
customPages: customPages,
|
customPages: customPages,
|
||||||
@@ -232,11 +240,6 @@ class ParseServer {
|
|||||||
userSensitiveFields
|
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));
|
Config.validate(AppCache.get(appId));
|
||||||
this.config = AppCache.get(appId);
|
this.config = AppCache.get(appId);
|
||||||
Config.setupPasswordValidator(this.config.passwordPolicy);
|
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": {
|
"oauth": {
|
||||||
env: "PARSE_SERVER_OAUTH_PROVIDERS",
|
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
|
action: objectParser
|
||||||
},
|
},
|
||||||
"fileKey": {
|
"fileKey": {
|
||||||
@@ -92,9 +97,15 @@ export default {
|
|||||||
},
|
},
|
||||||
"facebookAppIds": {
|
"facebookAppIds": {
|
||||||
env: "PARSE_SERVER_FACEBOOK_APP_IDS",
|
env: "PARSE_SERVER_FACEBOOK_APP_IDS",
|
||||||
help: "Comma separated list for your facebook app Ids",
|
help: "[DEPRECATED (use auth option)]",
|
||||||
type: "list",
|
action: function() {
|
||||||
action: arrayParser
|
throw 'facebookAppIds is deprecated, please use { auth: \
|
||||||
|
{facebook: \
|
||||||
|
{ appIds: [] } \
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
}';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"enableAnonymousUsers": {
|
"enableAnonymousUsers": {
|
||||||
env: "PARSE_SERVER_ENABLE_ANON_USERS",
|
env: "PARSE_SERVER_ENABLE_ANON_USERS",
|
||||||
|
|||||||
Reference in New Issue
Block a user