mirror of https://gitee.com/bigwinds/arangodb
Removed oauth2 app from system apps.
This commit is contained in:
parent
3b00e307ea
commit
6a89d78929
|
@ -1,305 +0,0 @@
|
|||
!CHAPTER The OAuth2 Authentication App
|
||||
|
||||
The OAuth2 authentication app provides authentication abstractions over OAuth2 providers like Facebook, GitHub and Google. If you want to support additional providers, you can easily define your own.
|
||||
|
||||
!SECTION Configuration
|
||||
|
||||
The app requires no configuration, but you need to update its *providers* collection with your client ID and client secret for each provider you wish to support.
|
||||
|
||||
!SUBSECTION Registering your app with GitHub
|
||||
|
||||
If you want to use the *github* provider, you need to obtain a client ID and client secret from GitHub:
|
||||
|
||||
1. Create a regular account at [GitHub](https://github.com) or use an existing account you own.
|
||||
2. Go to [Account Settings > Applications > Register new application](https://github.com/settings/applications/new).
|
||||
3. Provide an *authorization callback URL*. This must match your *redirect_uri* later.
|
||||
4. Fill in the other required details and follow the instructions provided.
|
||||
5. Open the application page, then note down the *Client ID* and *Client Secret*.
|
||||
6. Update the *github* provider by setting its *clientId* attribute to the *Client ID* and its *clientSecret* attribute to the *Client Secret*. Don't forget to save your changes.
|
||||
|
||||
!SUBSECTION Registering your app with Facebook
|
||||
|
||||
If you want to use the *facebook* provider, you need to obtain a client ID and client secret from Facebook:
|
||||
|
||||
1. Create a regular account at [Facebook](https://www.facebook.com) or use an existing account you own.
|
||||
2. Visit the [Facebook Developers](https://developers.facebook.com) page.
|
||||
3. Click on *Apps* in the menu, then select *Register as a Developer* (the only option) and follow the instructions provided. You may need to verify your account by phone.
|
||||
4. Click on *Apps* in the menu, then select *Create a New App* and follow the instructions provided.
|
||||
5. Open the app dashboard, then note down the *App ID* and *App Secret*. The secret may be hidden by default.
|
||||
6. Click on *Settings*, then *Advanced* and enter one or more *Valid OAuth redirect URIs*. At least one of them must match your *redirect_uri* later. Don't forget to save your changes.
|
||||
7. Update the *facebook* provider by setting its *clientId* attribute to the *App ID* and its *clientSecret* attribute to the *App Secret*. Don't forget to save your changes.
|
||||
|
||||
!SUBSECTION Registering your app with Google
|
||||
|
||||
If you want to use the *google* provider, you need to obtain a client ID and client secret from Google:
|
||||
|
||||
1. Create a regular account at [Google](https://www.google.com) or use an existing account you own.
|
||||
2. Visit the [Google Developers Console](https://console.developers.google.com).
|
||||
3. Click on *Create Project*, then follow the instructions provided.
|
||||
4. When your project is ready, open the project dashboard, then click on *Enable an API*.
|
||||
5. Enable the *Google+ API* to allow your app to distinguish between different users.
|
||||
6. Open the *Credentials* page and click *Create new Client ID*, then follow the instructions provided. At least one *Authorized Redirect URI* must match your *redirect_uri* later. At least one *Authorized JavaScript Origin* must match your app's fully-qualified domain.
|
||||
7. When the Client ID is ready, note down the *Client ID* and *Client secret*.
|
||||
8. Update the *google* provider by settiing its *clientId* attribute to the *Client ID* and its *clientSecret* attribute to the *Client secret*. Don't forget to save your changes.
|
||||
|
||||
!SECTION JavaScript API: *providers*
|
||||
|
||||
This app exposes its functionality via a JavaScript API named *providers*.
|
||||
|
||||
```js
|
||||
var providers = Foxx.requireApp('/_system/oauth2').providers;
|
||||
```
|
||||
|
||||
!SUBSECTION Exceptions
|
||||
|
||||
!SUBSUBSECTION Provider Not Found
|
||||
|
||||
Indicates a provider could not be found in the database.
|
||||
|
||||
`new providers.errors.ProviderNotFound(providerId)`
|
||||
|
||||
Thrown by the provider storage's *delete* and *get* methods if passed a provider ID that does not exist in the database.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
try {
|
||||
providers.get(invalidProviderId);
|
||||
} catch(err) {
|
||||
assertTrue(err instanceof providers.errors.ProviderNotFound);
|
||||
}
|
||||
```
|
||||
|
||||
!SUBSECTION The provider object
|
||||
|
||||
Provider objects are instances of a Foxx model with the following attributes:
|
||||
|
||||
* *label*: a human-readable identifier for the provider (e.g. *"GitHub"*).
|
||||
* *authEndpoint*: the fully-qualified URL of the provider's [authorization endpoint](http://tools.ietf.org/html/rfc6749#section-3.1).
|
||||
* *tokenEndpoint*: the fully-qualified URL of the provider's [token endpoint](http://tools.ietf.org/html/rfc6749#section-3.2).
|
||||
* *refreshEndpoint* (optional): the fully-qualified URL of the provider's [refresh token](http://tools.ietf.org/html/rfc6749#section-6) endpoint.
|
||||
* *activeUserEndpoint* (optional): the fully-qualified URL of the provider's endpoint for fetching details about the current user.
|
||||
* *usernameTemplate* (optional): An underscore.js template for extracting the user's permanent identifier from the user's details. Default: *"<%= id %>"*.
|
||||
* *clientId*: the client ID of the app registered with the provider.
|
||||
* *clientSecret*: the client secret of the app registered with the provider.
|
||||
|
||||
!SUBSECTION List available OAuth2 providers
|
||||
|
||||
Returns a list of OAuth2 providers that can be presented to the front-end.
|
||||
|
||||
`providers.list()`
|
||||
|
||||
Each item in the list is an object with the following properties:
|
||||
|
||||
* *_key*: *_key* of the provider.
|
||||
* *label*: a human-readable identifier that can be presented to the user.
|
||||
* *clientId*: the client ID stored for the given provider.
|
||||
|
||||
If you wish to exclude providers you don't support in your app, you need to filter the result manually.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var supportedProviders = providers.list().filter(function(obj) {
|
||||
return Boolean(obj.clientId);
|
||||
});
|
||||
```
|
||||
|
||||
!SUBSECTION Define a new OAuth2 provider
|
||||
|
||||
Creates a new OAuth2 provider with the given data.
|
||||
|
||||
`providers.create(data)`
|
||||
|
||||
Saves and returns a new instance of the provider model with its attributes set to the properties of the given object.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *data*: an arbitrary object, see above.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var provider = providers.create({
|
||||
_key: 'myoauth2',
|
||||
label: 'My OAuth2 Provider',
|
||||
authEndpoint: 'https://example.com/oauth2/authorize',
|
||||
tokenEndpoint: 'https://example.com/oauth2/access_token',
|
||||
refreshEndpoint: 'https://example.com/oauth2/access_token',
|
||||
activeUserEndpoint: 'https://example.com/api/v2/users/me',
|
||||
usernameTemplate: '<%= user_id %>',
|
||||
clientId: '1234567890',
|
||||
clientSecret: 'kEyBoArDcAt'
|
||||
});
|
||||
```
|
||||
|
||||
!SUBSECTION Fetch an existing OAuth2 provider
|
||||
|
||||
Fetches an existing OAuth2 provider from the database.
|
||||
|
||||
`providers.get(providerId)`
|
||||
|
||||
Throws a *ProviderNotFound* exception if the provider does not exist.
|
||||
|
||||
*Parameters*
|
||||
|
||||
* *providerId*: the provider's *_key*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var provider = providers.get('github');
|
||||
assertTrue(provider.get('_key'), 'github');
|
||||
```
|
||||
|
||||
!SUBSECTION Delete a provider
|
||||
|
||||
There are two ways to delete a provider from the database:
|
||||
|
||||
* calling the provider storage's *delete* method with a provider's *_key* directly
|
||||
* telling a provider to delete itself
|
||||
|
||||
!SUBSUBSECTION Delete a provider by its ID
|
||||
|
||||
Delete a provider with a given ID.
|
||||
|
||||
`providers.delete(providerId)`
|
||||
|
||||
Attempts to delete the provider with the given *providerId* from the database. If the provider does not exist, a *ProviderNotFound* exception will be thrown. The method always returns *null*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *providerId*: a provider *_key*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
providers.delete('github');
|
||||
```
|
||||
|
||||
!SUBSUBSECTION Tell a provider to delete itself
|
||||
|
||||
Delete a provider from the database.
|
||||
|
||||
`provider.delete()`
|
||||
|
||||
Attempts to delete the provider from the database.
|
||||
|
||||
Returns *true* if the provider was deleted successfully.
|
||||
|
||||
Returns *false* if the provider already didn't exist.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var provider = providers.get('github');
|
||||
provider.delete();
|
||||
```
|
||||
|
||||
!SUBSECTION Save a provider
|
||||
|
||||
Save a provider to the database.
|
||||
|
||||
`provider.save()`
|
||||
|
||||
In order to commit changes made to the provider in your code, you need to call this method.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
provider.set('clientId', '1234567890');
|
||||
provider.set('clientSecret', 'kEyBoArDcAt');
|
||||
provider.save();
|
||||
```
|
||||
|
||||
|
||||
!SUBSECTION Get the authorization URL of a provider
|
||||
|
||||
Generates the authorization URL for the authorization endpoint of the provider.
|
||||
|
||||
`provider.getAuthUrl(redirect_uri, args)`
|
||||
|
||||
Returns a fully-qualified URL for the authorization endpoint of the provider by appending the provider object's client ID and any additional arguments from *args* to the provider object's *authEndpoint*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *redirect_uri*: the fully-qualified URL of your app's OAuth2 callback.
|
||||
* *args* (optional): an object with any of the following properties:
|
||||
* *response_type* (optional): See [RFC 6749](http://tools.ietf.org/html/rfc6749). Default: *"code"*.
|
||||
|
||||
!SUBSECTION _getTokenRequest
|
||||
|
||||
(Internal.) Generates the token URL and request body for token endpoint of the provider.
|
||||
|
||||
`provider._getTokenRequest(code, redirect_uri, args)`
|
||||
|
||||
Returns an object with two properties:
|
||||
|
||||
* *url*: the fully-qualified URL for the token endpoint.
|
||||
* *body*: the form-encoded request body for the token endpoint created by appending the provider object's client ID, client secret and any additional arguments from *args* to the provider object's *tokenEndpoint*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *code*: a grant code returned by the provider's authorization endpoint.
|
||||
* *redirect_uri*: the original callback URL with which the code was requested.
|
||||
* *args* (optional): an object with any of the following properties:
|
||||
* *grant_type* (optional): see [RFC 6749](http://tools.ietf.org/html/rfc6749). Default: *"authorization_code"*.
|
||||
|
||||
!SUBSECTION Exchange a grant code for an access token
|
||||
|
||||
Exchanges a grant code for an access token.
|
||||
|
||||
`provider.exchangeGrantToken(code, redirect_uri)`
|
||||
|
||||
Performs a *POST* response to the provider object's *tokenEndpoint* and returns the parsed response body.
|
||||
|
||||
Throws an exception if the remote server responds with an empty response body.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *code*: a grant code returned by the provider's authorization endpoint.
|
||||
* *redirect_uri*: the original callback URL with which the code was requested.
|
||||
* *args* (optional): an object with any of the following properties:
|
||||
* *grant_type* (optional): see [RFC 6749](http://tools.ietf.org/html/rfc6749). Default: *"authorization_code"*.
|
||||
|
||||
!SUBSECTION Fetch the active user
|
||||
|
||||
Fetches details of the active user.
|
||||
|
||||
`provider.fetchActiveUser(access_token)`
|
||||
|
||||
Performs a *GET* response to the provider object's *activeUserEndpoint* and returns the parsed response body.
|
||||
|
||||
Throws an exception if the remote server responds with an empty response body.
|
||||
|
||||
Also throws an exception if the provider object has no *activeUserEndpoint*.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *access_token*: an OAuth2 access token as returned by *exchangeGrantToken*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var authData = provider.exchangeGrantToken(code, redirect_uri);
|
||||
var userData = provider.fetchActiveUser(authData.access_token);
|
||||
```
|
||||
|
||||
!SUBSECTION Get a user's identifier
|
||||
|
||||
Fetches the user's identifier from a user object returned by the provider.
|
||||
|
||||
`provider.getUsername(userData)`
|
||||
|
||||
Applies the provider's *usernameTemplate* to the given user object.
|
||||
|
||||
*Parameter*
|
||||
|
||||
* *userData*: the object returned by *getActiveUser*.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
```js
|
||||
var userData = provider.fetchActiveUser(access_token);
|
||||
var username = provider.getUsername(userData);
|
||||
```
|
|
@ -59,7 +59,6 @@ JAVASCRIPT_JSLINT = \
|
|||
\
|
||||
`find @srcdir@/js/apps/system/cerberus -name "*.js"` \
|
||||
`find @srcdir@/js/apps/system/gharial -name "*.js"` \
|
||||
`find @srcdir@/js/apps/system/oauth2 -name "*.js"` \
|
||||
`find @srcdir@/js/apps/system/sessions -name "*.js"` \
|
||||
`find @srcdir@/js/apps/system/simple-auth -name "*.js"` \
|
||||
`find @srcdir@/js/apps/system/users -name "*.js"` \
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, white: true, plusplus: true, unparam: true, regexp: true, vars: true */
|
||||
/*global require, exports */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function ProviderNotFound(key) {
|
||||
this.message = 'Provider with key ' + key + ' not found.';
|
||||
}
|
||||
ProviderNotFound.prototype = new Error();
|
||||
|
||||
exports.ProviderNotFound = ProviderNotFound;
|
||||
}());
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"name": "oauth2",
|
||||
"author": "Alan Plum",
|
||||
"version": "0.1",
|
||||
"isSystem": true,
|
||||
"description": "OAuth2 authentication for Foxx.",
|
||||
|
||||
"exports": {
|
||||
"providers": "providers.js"
|
||||
},
|
||||
|
||||
"defaultDocument": "",
|
||||
|
||||
"lib": ".",
|
||||
|
||||
"setup": "setup.js"
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, es5: true */
|
||||
/*global require, exports, applicationContext */
|
||||
(function () {
|
||||
'use strict';
|
||||
var _ = require('underscore');
|
||||
var url = require('url');
|
||||
var querystring = require('querystring');
|
||||
var internal = require('internal');
|
||||
var arangodb = require('org/arangodb');
|
||||
var db = arangodb.db;
|
||||
var Foxx = require('org/arangodb/foxx');
|
||||
var errors = require('./errors');
|
||||
|
||||
var Provider = Foxx.Model.extend({}, {
|
||||
attributes: {
|
||||
_key: {type: 'string', required: true},
|
||||
label: {type: 'string', required: true},
|
||||
authEndpoint: {type: 'string', required: true},
|
||||
tokenEndpoint: {type: 'string', required: true},
|
||||
refreshEndpoint: {type: 'string', required: false},
|
||||
activeUserEndpoint: {type: 'string', required: false},
|
||||
usernameTemplate: {type: 'string', required: false},
|
||||
clientId: {type: 'string', required: true},
|
||||
clientSecret: {type: 'string', required: true}
|
||||
}
|
||||
});
|
||||
|
||||
var providers = new Foxx.Repository(
|
||||
applicationContext.collection('providers'),
|
||||
{model: Provider}
|
||||
);
|
||||
|
||||
function listProviders() {
|
||||
return providers.collection.all().toArray().forEach(function (provider) {
|
||||
return _.pick(provider, '_key', 'label', 'clientId');
|
||||
});
|
||||
}
|
||||
|
||||
function createProvider(data) {
|
||||
var provider = new Provider(data);
|
||||
providers.save(provider);
|
||||
return provider;
|
||||
}
|
||||
|
||||
function getProvider(key) {
|
||||
var provider;
|
||||
try {
|
||||
provider = providers.byId(key);
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof arangodb.ArangoError &&
|
||||
err.errorNum === arangodb.ERROR_ARANGO_DOCUMENT_NOT_FOUND
|
||||
) {
|
||||
throw new errors.ProviderNotFound(key);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
function deleteProvider(key) {
|
||||
try {
|
||||
providers.removeById(key);
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof arangodb.ArangoError
|
||||
&& err.errorNum === arangodb.ERROR_ARANGO_DOCUMENT_NOT_FOUND
|
||||
) {
|
||||
throw new errors.ProviderNotFound(key);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_.extend(Provider.prototype, {
|
||||
getAuthUrl: function (redirect_uri, args) {
|
||||
if (redirect_uri && typeof redirect_uri === 'object') {
|
||||
args = redirect_uri;
|
||||
redirect_uri = undefined;
|
||||
}
|
||||
var endpoint = url.parse(this.get('authEndpoint'));
|
||||
args = _.extend(querystring.parse(endpoint.query), args);
|
||||
if (redirect_uri) {
|
||||
args.redirect_uri = redirect_uri;
|
||||
}
|
||||
if (!args.response_type) {
|
||||
args.response_type = 'code';
|
||||
}
|
||||
args.client_id = this.get('clientId');
|
||||
endpoint.search = '?' + querystring.stringify(args);
|
||||
return url.format(endpoint);
|
||||
},
|
||||
_getTokenRequest: function (code, redirect_uri, args) {
|
||||
if (code && typeof code === 'object') {
|
||||
args = code;
|
||||
code = undefined;
|
||||
redirect_uri = undefined;
|
||||
} else if (redirect_uri && typeof redirect_uri === 'object') {
|
||||
args = redirect_uri;
|
||||
redirect_uri = undefined;
|
||||
}
|
||||
var endpoint = url.parse(this.get('tokenEndpoint'));
|
||||
args = _.extend(querystring.parse(endpoint.query), args);
|
||||
if (code) {
|
||||
args.code = code;
|
||||
}
|
||||
if (redirect_uri) {
|
||||
args.redirect_uri = redirect_uri;
|
||||
}
|
||||
if (!args.grant_type) {
|
||||
args.grant_type = 'authorization_code';
|
||||
}
|
||||
args.client_id = this.get('clientId');
|
||||
args.client_secret = this.get('clientSecret');
|
||||
delete endpoint.search;
|
||||
delete endpoint.query;
|
||||
return {url: url.format(endpoint), body: args};
|
||||
},
|
||||
getActiveUserUrl: function (access_token, args) {
|
||||
var endpoint = this.get('activeUserEndpoint');
|
||||
if (!endpoint) {
|
||||
return null;
|
||||
}
|
||||
if (access_token && typeof access_token === 'object') {
|
||||
args = access_token;
|
||||
access_token = undefined;
|
||||
}
|
||||
args = _.extend(querystring.parse(endpoint.query), args);
|
||||
if (access_token) {
|
||||
args.access_token = access_token;
|
||||
}
|
||||
endpoint = url.parse(endpoint);
|
||||
args = _.extend(querystring.parse(endpoint.query), args);
|
||||
endpoint.search = '?' + querystring.stringify(args);
|
||||
return url.format(endpoint);
|
||||
},
|
||||
getUsername: function (obj) {
|
||||
var tpl = this.get('usernameTemplate');
|
||||
if (!tpl) {
|
||||
tpl = '<%= id %>';
|
||||
}
|
||||
return _.template(tpl)(obj);
|
||||
},
|
||||
exchangeGrantToken: function (code, redirect_uri) {
|
||||
var request = this._getTokenRequest(code, redirect_uri);
|
||||
var response = internal.download(
|
||||
request.url,
|
||||
querystring.stringify(request.body),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!response.body) {
|
||||
throw new Error('OAuth provider ' + this.get('_key') + ' returned HTTP ' + response.code);
|
||||
}
|
||||
try {
|
||||
return JSON.parse(response.body);
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError) {
|
||||
return querystring.parse(response.body);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
fetchActiveUser: function (access_token) {
|
||||
var url = this.getActiveUserUrl(access_token);
|
||||
if (!url) {
|
||||
throw new Error('Provider ' + this.get('_key') + ' does not support active user lookup');
|
||||
}
|
||||
var response = internal.download(url);
|
||||
if (!response.body) {
|
||||
throw new Error('OAuth provider ' + this.get('_key') + ' returned HTTP ' + response.code);
|
||||
}
|
||||
try {
|
||||
return JSON.parse(response.body);
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError) {
|
||||
return querystring.parse(response.body);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
save: function () {
|
||||
var provider = this;
|
||||
providers.replace(provider);
|
||||
return provider;
|
||||
},
|
||||
delete: function () {
|
||||
try {
|
||||
deleteProvider(this.get('_key'));
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e instanceof errors.ProviderNotFound) {
|
||||
return false;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
exports.list = listProviders;
|
||||
exports.create = createProvider;
|
||||
exports.get = getProvider;
|
||||
exports.delete = deleteProvider;
|
||||
exports.errors = errors;
|
||||
exports.repository = providers;
|
||||
}());
|
|
@ -1,47 +0,0 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, white: true, plusplus: true, unparam: true, regexp: true, vars: true */
|
||||
/*global require, applicationContext */
|
||||
(function () {
|
||||
'use strict';
|
||||
var db = require('org/arangodb').db;
|
||||
var providersName = applicationContext.collectionName('providers');
|
||||
|
||||
if (db._collection(providersName) === null) {
|
||||
db._create(providersName);
|
||||
}
|
||||
|
||||
var providers = db._collection(providersName);
|
||||
[
|
||||
{
|
||||
_key: 'github',
|
||||
label: 'GitHub',
|
||||
authEndpoint: 'https://github.com/login/oauth/authorize?scope=user',
|
||||
tokenEndpoint: 'https://github.com/login/oauth/access_token',
|
||||
activeUserEndpoint: 'https://api.github.com/user',
|
||||
clientId: null,
|
||||
clientSecret: null
|
||||
},
|
||||
{
|
||||
_key: 'facebook',
|
||||
label: 'Facebook',
|
||||
authEndpoint: 'https://www.facebook.com/dialog/oauth',
|
||||
tokenEndpoint: 'https://graph.facebook.com/oauth/access_token',
|
||||
activeUserEndpoint: 'https://graph.facebook.com/v2.0/me',
|
||||
clientId: null,
|
||||
clientSecret: null
|
||||
},
|
||||
{
|
||||
_key: 'google',
|
||||
label: 'Google',
|
||||
authEndpoint: 'https://accounts.google.com/o/oauth2/auth?access_type=offline&scope=profile',
|
||||
tokenEndpoint: 'https://accounts.google.com/o/oauth2/token',
|
||||
refreshEndpoint: 'https://accounts.google.com/o/oauth2/token',
|
||||
activeUserEndpoint: 'https://www.googleapis.com/plus/v1/people/me',
|
||||
clientId: null,
|
||||
clientSecret: null
|
||||
}
|
||||
].forEach(function(provider) {
|
||||
if (!providers.exists(provider._key)) {
|
||||
providers.save(provider);
|
||||
}
|
||||
});
|
||||
}());
|
Loading…
Reference in New Issue