Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(social-auth):create social login via instagram * feat(social-auth):Add instagram auth tests * fix(social-auth):Fix standard and linting issues * fix data bugs * removing client id and client secret from config file * fix(adonis-ally):change twitter OauthException parameter from github to twitter in twitter driver file * feat(social-auth):wrote twitter tests * worked on the changes requested
- Loading branch information
1 parent
59d4a2e
commit 3d5ca8f
Showing
8 changed files
with
332 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,6 @@ coverage | |
node_modules | ||
.DS_Store | ||
npm-debug.log | ||
.env | ||
.idea | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use strict' | ||
|
||
const Ioc = require('adonis-fold').Ioc | ||
const config = require('./setup/config') | ||
const http = require('./setup/http') | ||
const AllyManager = require('../src/AllyManager') | ||
Ioc.bind('Adonis/Src/Config', () => { | ||
return config | ||
}) | ||
|
||
http.get('/instagram', function * (request, response) { | ||
const ally = new AllyManager(request, response) | ||
const instagram = ally.driver('instagram') | ||
response.writeHead(200, {'content-type': 'text/html'}) | ||
const url = yield instagram.getRedirectUrl() | ||
response.write(`<a href="${url}">Login With Instagram</a>`) | ||
response.end() | ||
}) | ||
|
||
http.get('/instagram/authenticated', function * (request, response) { | ||
const ally = new AllyManager(request, response) | ||
const instagram = ally.driver('instagram') | ||
try { | ||
const user = yield instagram.getUser() | ||
response.writeHead(200, {'content-type': 'application/json'}) | ||
response.write(JSON.stringify({ original: user.getOriginal(), profile: user.toJSON() })) | ||
} catch (e) { | ||
response.writeHead(500, {'content-type': 'application/json'}) | ||
response.write(JSON.stringify({ error: e })) | ||
} | ||
response.end() | ||
}) | ||
|
||
http.start().listen(8000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
'use strict' | ||
|
||
/* | ||
* adonis-ally | ||
* | ||
* (c) Ayeni Olusegun <nsegun5@gmail.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
const CE = require('../Exceptions') | ||
const OAuth2Scheme = require('../Schemes/OAuth2') | ||
const AllyUser = require('../AllyUser') | ||
const got = require('got') | ||
const utils = require('../../lib/utils') | ||
const _ = utils.mixLodash(require('lodash')) | ||
|
||
class Instagram extends OAuth2Scheme { | ||
|
||
constructor (Config) { | ||
const config = Config.get('services.ally.instagram') | ||
|
||
if (!_.hasAll(config, ['clientId', 'clientSecret', 'redirectUri'])) { | ||
throw CE.OAuthException.missingConfig('instagram') | ||
} | ||
|
||
super(config.clientId, config.clientSecret, config.headers) | ||
|
||
/** | ||
* Oauth specific values to be used when creating the redirect | ||
* url or fetching user profile. | ||
*/ | ||
this._scope = this._getInitialScopes(config.scope) | ||
this._redirectUri = config.redirectUri | ||
this._redirectUriOptions = _.merge({response_type: 'code'}, config.options) | ||
} | ||
|
||
/** | ||
* Injections to be made by the IoC container | ||
* | ||
* @return {Array} | ||
*/ | ||
static get inject () { | ||
return ['Adonis/Src/Config'] | ||
} | ||
|
||
/** | ||
* Scope seperator for seperating multiple | ||
* scopes. | ||
* | ||
* @return {String} | ||
*/ | ||
get scopeSeperator () { | ||
return ' ' | ||
} | ||
|
||
/** | ||
* Base url to be used for constructing | ||
* facebook oauth urls. | ||
* | ||
* @return {String} | ||
*/ | ||
get baseUrl () { | ||
return 'https://api.instagram.com/' | ||
} | ||
|
||
/** | ||
* Relative url to be used for redirecting | ||
* user. | ||
* | ||
* @return {String} [description] | ||
*/ | ||
get authorizeUrl () { | ||
return 'oauth/authorize' | ||
} | ||
|
||
/** | ||
* Relative url to be used for exchanging | ||
* access token. | ||
* | ||
* @return {String} | ||
*/ | ||
get accessTokenUrl () { | ||
return 'oauth/access_token' | ||
} | ||
|
||
/** | ||
* Returns initial scopes to be used right from the | ||
* config file. Otherwise it will fallback to the | ||
* commonly used scopes | ||
* | ||
* @param {Array} scopes | ||
* | ||
* @return {Array} | ||
* | ||
* @private | ||
*/ | ||
_getInitialScopes (scopes) { | ||
return _.size(scopes) ? scopes : ['basic'] | ||
} | ||
|
||
/** | ||
* Returns the user profile as an object using the | ||
* access token | ||
* | ||
* @param {String} accessToken | ||
* | ||
* @return {Object} | ||
* | ||
* @private | ||
*/ | ||
* _getUserProfile (accessToken) { | ||
const profileUrl = `${this.baseUrl}v1/users/self?access_token=${accessToken}` | ||
const response = yield got(profileUrl, { | ||
headers: { | ||
'Accept': 'application/json' | ||
}, | ||
json: true | ||
}) | ||
return response.body | ||
} | ||
|
||
/** | ||
* Returns the redirect url for a given provider. | ||
* | ||
* @param {Array} scope | ||
* | ||
* @return {String} | ||
*/ | ||
* getRedirectUrl (scope) { | ||
scope = _.size(scope) ? scope : this._scope | ||
return this.getUrl(this._redirectUri, scope, this._redirectUriOptions) | ||
} | ||
|
||
/** | ||
* Parses the redirect errors returned by facebook | ||
* and returns the error message. | ||
* | ||
* @param {Object} queryParams | ||
* | ||
* @return {String} | ||
*/ | ||
parseRedirectError (queryParams) { | ||
return queryParams.error_description || queryParams.error || 'Oauth failed during redirect' | ||
} | ||
|
||
/** | ||
* Returns the user profile with it's access token, refresh token | ||
* and token expiry | ||
* | ||
* @param {Object} queryParams | ||
* | ||
* @return {Object} | ||
*/ | ||
* getUser (queryParams) { | ||
const code = queryParams.code | ||
|
||
/** | ||
* Throw an exception when query string does not have | ||
* code. | ||
*/ | ||
if (!code) { | ||
const errorMessage = this.parseRedirectError(queryParams) | ||
throw CE.OAuthException.tokenExchangeException(errorMessage, null, errorMessage) | ||
} | ||
|
||
const accessTokenResponse = yield this.getAccessToken(code, this._redirectUri, { | ||
grant_type: 'authorization_code' | ||
}) | ||
const userProfile = yield this._getUserProfile(accessTokenResponse.accessToken) | ||
const user = new AllyUser() | ||
user | ||
.setOriginal(userProfile) | ||
.setFields( | ||
userProfile.data.id, | ||
userProfile.data.full_name, | ||
null, | ||
userProfile.data.username, | ||
userProfile.data.profile_picture | ||
) | ||
.setToken( | ||
accessTokenResponse.accessToken, | ||
accessTokenResponse.refreshToken, | ||
null, | ||
null | ||
) | ||
|
||
return user | ||
} | ||
} | ||
|
||
module.exports = Instagram |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters