passport-dkt-oauth2
Version:
Decathlon passport strategy OAuth 2
81 lines (68 loc) • 2.06 kB
JavaScript
const OAuth2Strategy = require('passport-oauth2')
const { InternalOAuthError } = OAuth2Strategy
const axios = require('axios')
const qs = require('querystring')
const defaults = require('defaults')
/**
* `Strategy` constructor.
*
* @param {Object} options
* @param {Function} verify
* @api public
*/
class Strategy extends OAuth2Strategy {
constructor (options = {}, verify) {
super(options, verify)
if (!options.userProfileURL) { throw new TypeError('OAuth 2.0-based strategy requires a userProfileURL option') }
this._userProfileURL = options.userProfileURL
}
/**
* Retrieve user profile.
*
* @param {String} accessToken
* @param {Function} done
* @api protected
*/
userProfile (accessToken, done = null) {
this._oauth2.get(this._userProfileURL, accessToken, function (err, body, res) {
let profile = {}
if (err) return done(new InternalOAuthError('Failed to fetch user profile', err))
try {
profile = JSON.parse(body)
} catch (ex) {
return done(new Error('Failed to parse user profile'))
}
return done(null, profile)
})
}
async getAccessToken (code, opt = {}) {
try {
opt = defaults(opt, {
tokenURL: this._oauth2._accessTokenUrl,
redirectUri: this._callbackURL,
clientId: this._oauth2._clientId,
grantType: 'authorization_code',
clientSecret: this._oauth2._clientSecret
})
const { data } = await axios({
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${Buffer.from(`${opt.clientId}:${opt.clientSecret}`).toString('base64')}`
},
data: qs.stringify({
grant_type: opt.grantType,
code,
redirect_uri: opt.redirectUri,
client_id: opt.clientId
}),
url: opt.tokenURL
})
return Promise.resolve(data)
} catch (error) {
return Promise.reject(error)
}
}
}
module.exports = Strategy