Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Commit

Permalink
Send clientSecret with header in code flow (#44)
Browse files Browse the repository at this point in the history
Also fixed a deviation from spec related to `redirect_uri` - it's not always required.
  • Loading branch information
blakeembrey authored Mar 22, 2017
1 parent ba24e57 commit 7ae072f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 36 deletions.
62 changes: 28 additions & 34 deletions src/client-oauth2.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ function btoaBuffer (string) {
*
* @throws {TypeError} If an expected property is missing.
*
* @param {Object} obj
* @param {Array} props
* @param {Object} obj
* @param {...string} props
*/
function expects (obj, props) {
for (var i = 0; i < props.length; i++) {
var prop = props[i]
function expects (obj) {
for (var i = 1; i < arguments.length; i++) {
var prop = arguments[i]

if (obj[prop] == null) {
throw new TypeError('Expected "' + prop + '" to exist')
Expand Down Expand Up @@ -153,11 +153,7 @@ function sanitizeScope (scopes) {
*/
function createUri (options, tokenType) {
// Check the required parameters are set.
expects(options, [
'clientId',
'redirectUri',
'authorizationUri'
])
expects(options, 'clientId', 'authorizationUri')

return options.authorizationUri + '?' + Querystring.stringify(extend(
options.query,
Expand Down Expand Up @@ -525,11 +521,7 @@ CredentialsFlow.prototype.getToken = function (options) {

options = extend(this.client.options, options)

expects(options, [
'clientId',
'clientSecret',
'accessTokenUri'
])
expects(options, 'clientId', 'clientSecret', 'accessTokenUri')

return this.client._request(requestOptions({
url: options.accessTokenUri,
Expand Down Expand Up @@ -582,17 +574,15 @@ CodeFlow.prototype.getToken = function (uri, options) {

options = extend(this.client.options, options)

expects(options, [
'clientId',
'clientSecret',
'redirectUri',
'accessTokenUri'
])
expects(options, 'clientId', 'accessTokenUri')

var url = typeof uri === 'object' ? uri : Url.parse(uri, true)
var expectedUrl = Url.parse(options.redirectUri)

if (typeof url.pathname === 'string' && url.pathname !== expectedUrl.pathname) {
if (
typeof options.redirectUri === 'string' &&
typeof url.pathname === 'string' &&
url.pathname !== Url.parse(options.redirectUri).pathname
) {
return Promise.reject(
new TypeError('Redirected path should match configured path, but got: ' + url.pathname)
)
Expand All @@ -618,17 +608,23 @@ CodeFlow.prototype.getToken = function (uri, options) {
return Promise.reject(new TypeError('Missing code, unable to request token'))
}

var headers = extend(DEFAULT_HEADERS)
var body = { code: data.code, grant_type: 'authorization_code', redirect_uri: options.redirectUri }

// `client_id`: REQUIRED, if the client is not authenticating with the
// authorization server as described in Section 3.2.1.
// Reference: https://tools.ietf.org/html/rfc6749#section-3.2.1
if (options.clientSecret) {
headers.Authorization = auth(options.clientId, options.clientSecret)
} else {
body.client_id = options.clientId
}

return this.client._request(requestOptions({
url: options.accessTokenUri,
method: 'POST',
headers: extend(DEFAULT_HEADERS),
body: {
code: data.code,
grant_type: 'authorization_code',
redirect_uri: options.redirectUri,
client_id: options.clientId,
client_secret: options.clientSecret
}
headers: headers,
body: body
}, options))
.then(function (data) {
return self.client.createToken(data)
Expand Down Expand Up @@ -658,9 +654,7 @@ JwtBearerFlow.prototype.getToken = function (token, options) {

options = extend(this.client.options, options)

expects(options, [
'accessTokenUri'
])
expects(options, 'accessTokenUri')

var headers = extend(DEFAULT_HEADERS)

Expand Down
3 changes: 1 addition & 2 deletions test/support/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ app.post(
}

if (grantType === 'authorization_code') {
assert.equal(req.body.client_id, config.clientId)
assert.equal(req.body.client_secret, config.clientSecret)
assert.equal(req.body.code, config.code)
assert.equal(req.headers.authorization, credentials)
} else if (grantType === 'urn:ietf:params:oauth:grant-type:jwt-bearer') {
assert.equal(req.body.assertion, config.jwt)
assert.equal(req.headers.authorization, credentials)
Expand Down

0 comments on commit 7ae072f

Please sign in to comment.