Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jan 20, 2024. It is now read-only.

Commita237644

Browse files
authored
Fixes#98: Do not send empty scopes to an auth server (#154)
If `scopes` is set to `""` or `[]` then we should send an empty string.If `scopes` is undefined (not set), then we don't send it at all.
1 parent75af020 commita237644

File tree

7 files changed

+302
-29
lines changed

7 files changed

+302
-29
lines changed

‎src/client-oauth2.js

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,19 @@ function createUri (options, tokenType) {
161161
// Check the required parameters are set.
162162
expects(options,'clientId','authorizationUri')
163163

164-
constsep=options.authorizationUri.includes('?') ?'&' :'?'
165-
166-
returnoptions.authorizationUri+sep+Querystring.stringify(Object.assign({
164+
constqs={
167165
client_id:options.clientId,
168166
redirect_uri:options.redirectUri,
169-
scope:sanitizeScope(options.scopes),
170167
response_type:tokenType,
171168
state:options.state
172-
},options.query))
169+
}
170+
if(options.scopes!==undefined){
171+
qs.scope=sanitizeScope(options.scopes)
172+
}
173+
174+
constsep=options.authorizationUri.includes('?') ?'&' :'?'
175+
returnoptions.authorizationUri+sep+Querystring.stringify(
176+
Object.assign(qs,options.query))
173177
}
174178

175179
/**
@@ -417,18 +421,22 @@ OwnerFlow.prototype.getToken = function (username, password, opts) {
417421
varself=this
418422
varoptions=Object.assign({},this.client.options,opts)
419423

424+
constbody={
425+
username:username,
426+
password:password,
427+
grant_type:'password'
428+
}
429+
if(options.scopes!==undefined){
430+
body.scope=sanitizeScope(options.scopes)
431+
}
432+
420433
returnthis.client._request(requestOptions({
421434
url:options.accessTokenUri,
422435
method:'POST',
423436
headers:Object.assign({},DEFAULT_HEADERS,{
424437
Authorization:auth(options.clientId,options.clientSecret)
425438
}),
426-
body:{
427-
scope:sanitizeScope(options.scopes),
428-
username:username,
429-
password:password,
430-
grant_type:'password'
431-
}
439+
body:body
432440
},options))
433441
.then(function(data){
434442
returnself.client.createToken(data)
@@ -530,16 +538,21 @@ CredentialsFlow.prototype.getToken = function (opts) {
530538

531539
expects(options,'clientId','clientSecret','accessTokenUri')
532540

541+
constbody={
542+
grant_type:'client_credentials'
543+
}
544+
545+
if(options.scopes!==undefined){
546+
body.scope=sanitizeScope(options.scopes)
547+
}
548+
533549
returnthis.client._request(requestOptions({
534550
url:options.accessTokenUri,
535551
method:'POST',
536552
headers:Object.assign({},DEFAULT_HEADERS,{
537553
Authorization:auth(options.clientId,options.clientSecret)
538554
}),
539-
body:{
540-
scope:sanitizeScope(options.scopes),
541-
grant_type:'client_credentials'
542-
}
555+
body:body
543556
},options))
544557
.then(function(data){
545558
returnself.client.createToken(data)
@@ -671,15 +684,20 @@ JwtBearerFlow.prototype.getToken = function (token, opts) {
671684
headers.Authorization=auth(options.clientId,options.clientSecret)
672685
}
673686

687+
constbody={
688+
grant_type:'urn:ietf:params:oauth:grant-type:jwt-bearer',
689+
assertion:token
690+
}
691+
692+
if(options.scopes!==undefined){
693+
body.scope=sanitizeScope(options.scopes)
694+
}
695+
674696
returnthis.client._request(requestOptions({
675697
url:options.accessTokenUri,
676698
method:'POST',
677699
headers:headers,
678-
body:{
679-
scope:sanitizeScope(options.scopes),
680-
grant_type:'urn:ietf:params:oauth:grant-type:jwt-bearer',
681-
assertion:token
682-
}
700+
body:body
683701
},options))
684702
.then(function(data){
685703
returnself.client.createToken(data)

‎test/code.js

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,56 @@ describe('code', function () {
2121
expect(githubAuth.code.getUri()).to.equal(
2222
config.authorizationUri+'?client_id=abc&'+
2323
'redirect_uri=http%3A%2F%2Fexample.com%2Fauth%2Fcallback&'+
24-
'scope=notifications&response_type=code&state='
24+
'response_type=code&state=&scope=notifications'
25+
)
26+
})
27+
context('when scopes are undefined',function(){
28+
it('should not include scope in the uri',function(){
29+
varauthWithoutScopes=newClientOAuth2({
30+
clientId:config.clientId,
31+
clientSecret:config.clientSecret,
32+
accessTokenUri:config.accessTokenUri,
33+
authorizationUri:config.authorizationUri,
34+
authorizationGrants:['code'],
35+
redirectUri:config.redirectUri
36+
})
37+
expect(authWithoutScopes.code.getUri()).to.equal(
38+
config.authorizationUri+'?client_id=abc&'+
39+
'redirect_uri=http%3A%2F%2Fexample.com%2Fauth%2Fcallback&'+
40+
'response_type=code&state='
41+
)
42+
})
43+
})
44+
it('should include empty scopes array as an empty string',function(){
45+
varauthWithEmptyScopes=newClientOAuth2({
46+
clientId:config.clientId,
47+
clientSecret:config.clientSecret,
48+
accessTokenUri:config.accessTokenUri,
49+
authorizationUri:config.authorizationUri,
50+
authorizationGrants:['code'],
51+
redirectUri:config.redirectUri,
52+
scopes:[]
53+
})
54+
expect(authWithEmptyScopes.code.getUri()).to.equal(
55+
config.authorizationUri+'?client_id=abc&'+
56+
'redirect_uri=http%3A%2F%2Fexample.com%2Fauth%2Fcallback&'+
57+
'response_type=code&state=&scope='
58+
)
59+
})
60+
it('should include empty scopes string as an empty string',function(){
61+
varauthWithEmptyScopes=newClientOAuth2({
62+
clientId:config.clientId,
63+
clientSecret:config.clientSecret,
64+
accessTokenUri:config.accessTokenUri,
65+
authorizationUri:config.authorizationUri,
66+
authorizationGrants:['code'],
67+
redirectUri:config.redirectUri,
68+
scopes:''
69+
})
70+
expect(authWithEmptyScopes.code.getUri()).to.equal(
71+
config.authorizationUri+'?client_id=abc&'+
72+
'redirect_uri=http%3A%2F%2Fexample.com%2Fauth%2Fcallback&'+
73+
'response_type=code&state=&scope='
2574
)
2675
})
2776
context('when authorizationUri contains query parameters',function(){
@@ -38,7 +87,7 @@ describe('code', function () {
3887
expect(authWithParams.code.getUri()).to.equal(
3988
config.authorizationUri+'?bar=qux&client_id=abc&'+
4089
'redirect_uri=http%3A%2F%2Fexample.com%2Fauth%2Fcallback&'+
41-
'scope=notifications&response_type=code&state='
90+
'response_type=code&state=&scope=notifications'
4291
)
4392
})
4493
})

‎test/credentials.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global describe, it */
1+
/* global describe, it, context */
22
varexpect=require('chai').expect
33
varconfig=require('./support/config')
44
varClientOAuth2=require('../')
@@ -19,8 +19,62 @@ describe('credentials', function () {
1919
expect(user).to.an.instanceOf(ClientOAuth2.Token)
2020
expect(user.accessToken).to.equal(config.accessToken)
2121
expect(user.tokenType).to.equal('bearer')
22+
expect(user.data.scope).to.equal('notifications')
2223
})
2324
})
25+
context('when scopes are undefined',function(){
26+
it('should not send scopes to an auth server',function(){
27+
varauthWithoutScopes=newClientOAuth2({
28+
clientId:config.clientId,
29+
clientSecret:config.clientSecret,
30+
accessTokenUri:config.accessTokenUri,
31+
authorizationGrants:['credentials']
32+
})
33+
returnauthWithoutScopes.credentials.getToken()
34+
.then(function(user){
35+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
36+
expect(user.accessToken).to.equal(config.accessToken)
37+
expect(user.tokenType).to.equal('bearer')
38+
expect(user.data.scope).to.equal(undefined)
39+
})
40+
})
41+
})
42+
context('when scopes is an empty array',function(){
43+
it('should send empty scope string to an auth server',function(){
44+
varauthWithoutScopes=newClientOAuth2({
45+
clientId:config.clientId,
46+
clientSecret:config.clientSecret,
47+
accessTokenUri:config.accessTokenUri,
48+
authorizationGrants:['credentials'],
49+
scopes:[]
50+
})
51+
returnauthWithoutScopes.credentials.getToken()
52+
.then(function(user){
53+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
54+
expect(user.accessToken).to.equal(config.accessToken)
55+
expect(user.tokenType).to.equal('bearer')
56+
expect(user.data.scope).to.equal('')
57+
})
58+
})
59+
})
60+
context('when scopes is an empty string',function(){
61+
it('should send empty scope string to an auth server',function(){
62+
varauthWithoutScopes=newClientOAuth2({
63+
clientId:config.clientId,
64+
clientSecret:config.clientSecret,
65+
accessTokenUri:config.accessTokenUri,
66+
authorizationGrants:['credentials'],
67+
scopes:''
68+
})
69+
returnauthWithoutScopes.credentials.getToken()
70+
.then(function(user){
71+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
72+
expect(user.accessToken).to.equal(config.accessToken)
73+
expect(user.tokenType).to.equal('bearer')
74+
expect(user.data.scope).to.equal('')
75+
})
76+
})
77+
})
2478

2579
describe('#sign',function(){
2680
it('should be able to sign a standard request object',function(){

‎test/jwtbearer.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global describe, it */
1+
/* global describe, it, context */
22
varexpect=require('chai').expect
33
varconfig=require('./support/config')
44
varClientOAuth2=require('../')
@@ -19,8 +19,62 @@ describe('jwt', function () {
1919
expect(user).to.an.instanceOf(ClientOAuth2.Token)
2020
expect(user.accessToken).to.equal(config.accessToken)
2121
expect(user.tokenType).to.equal('bearer')
22+
expect(user.data.scope).to.equal('notifications')
2223
})
2324
})
25+
context('when scopes are undefined',function(){
26+
it('should not send scopes to an auth server',function(){
27+
varscopelessAuth=newClientOAuth2({
28+
clientId:config.clientId,
29+
clientSecret:config.clientSecret,
30+
accessTokenUri:config.accessTokenUri,
31+
authorizationGrants:['jwt']
32+
})
33+
returnscopelessAuth.jwt.getToken(config.jwt)
34+
.then(function(user){
35+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
36+
expect(user.accessToken).to.equal(config.accessToken)
37+
expect(user.tokenType).to.equal('bearer')
38+
expect(user.data.scope).to.equal(undefined)
39+
})
40+
})
41+
})
42+
context('when scopes are an empty array',function(){
43+
it('should send empty scope string to an auth server',function(){
44+
varscopelessAuth=newClientOAuth2({
45+
clientId:config.clientId,
46+
clientSecret:config.clientSecret,
47+
accessTokenUri:config.accessTokenUri,
48+
authorizationGrants:['jwt'],
49+
scopes:[]
50+
})
51+
returnscopelessAuth.jwt.getToken(config.jwt)
52+
.then(function(user){
53+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
54+
expect(user.accessToken).to.equal(config.accessToken)
55+
expect(user.tokenType).to.equal('bearer')
56+
expect(user.data.scope).to.equal('')
57+
})
58+
})
59+
})
60+
context('when scopes are an empty array',function(){
61+
it('should send empty scope string to an auth server',function(){
62+
varscopelessAuth=newClientOAuth2({
63+
clientId:config.clientId,
64+
clientSecret:config.clientSecret,
65+
accessTokenUri:config.accessTokenUri,
66+
authorizationGrants:['jwt'],
67+
scopes:''
68+
})
69+
returnscopelessAuth.jwt.getToken(config.jwt)
70+
.then(function(user){
71+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
72+
expect(user.accessToken).to.equal(config.accessToken)
73+
expect(user.tokenType).to.equal('bearer')
74+
expect(user.data.scope).to.equal('')
75+
})
76+
})
77+
})
2478

2579
describe('#sign',function(){
2680
it('should be able to sign a standard request object',function(){

‎test/owner.js

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global describe, it */
1+
/* global describe, it, context */
22
varexpect=require('chai').expect
33
varconfig=require('./support/config')
44
varClientOAuth2=require('../')
@@ -9,7 +9,7 @@ describe('owner', function () {
99
clientSecret:config.clientSecret,
1010
accessTokenUri:config.accessTokenUri,
1111
authorizationGrants:['owner'],
12-
scope:'notifications'
12+
scopes:'notifications'
1313
})
1414

1515
describe('#getToken',function(){
@@ -19,8 +19,62 @@ describe('owner', function () {
1919
expect(user).to.an.instanceOf(ClientOAuth2.Token)
2020
expect(user.accessToken).to.equal(config.accessToken)
2121
expect(user.tokenType).to.equal('bearer')
22+
expect(user.data.scope).to.equal('notifications')
2223
})
2324
})
25+
context('when scopes are undefined',function(){
26+
it('should not send scope to an auth server',function(){
27+
varscopelessAuth=newClientOAuth2({
28+
clientId:config.clientId,
29+
clientSecret:config.clientSecret,
30+
accessTokenUri:config.accessTokenUri,
31+
authorizationGrants:['owner']
32+
})
33+
returnscopelessAuth.owner.getToken(config.username,config.password)
34+
.then(function(user){
35+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
36+
expect(user.accessToken).to.equal(config.accessToken)
37+
expect(user.tokenType).to.equal('bearer')
38+
expect(user.data.scope).to.equal(undefined)
39+
})
40+
})
41+
})
42+
context('when scopes are an empty array',function(){
43+
it('should send empty scope string to an auth server',function(){
44+
varscopelessAuth=newClientOAuth2({
45+
clientId:config.clientId,
46+
clientSecret:config.clientSecret,
47+
accessTokenUri:config.accessTokenUri,
48+
authorizationGrants:['owner'],
49+
scopes:[]
50+
})
51+
returnscopelessAuth.owner.getToken(config.username,config.password)
52+
.then(function(user){
53+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
54+
expect(user.accessToken).to.equal(config.accessToken)
55+
expect(user.tokenType).to.equal('bearer')
56+
expect(user.data.scope).to.equal('')
57+
})
58+
})
59+
})
60+
context('when scopes are an empty string',function(){
61+
it('should send empty scope string to an auth server',function(){
62+
varscopelessAuth=newClientOAuth2({
63+
clientId:config.clientId,
64+
clientSecret:config.clientSecret,
65+
accessTokenUri:config.accessTokenUri,
66+
authorizationGrants:['owner'],
67+
scopes:''
68+
})
69+
returnscopelessAuth.owner.getToken(config.username,config.password)
70+
.then(function(user){
71+
expect(user).to.an.instanceOf(ClientOAuth2.Token)
72+
expect(user.accessToken).to.equal(config.accessToken)
73+
expect(user.tokenType).to.equal('bearer')
74+
expect(user.data.scope).to.equal('')
75+
})
76+
})
77+
})
2478

2579
describe('#sign',function(){
2680
it('should be able to sign a standard request object',function(){

‎test/support/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ app.post(
5151
access_token:config.accessToken,
5252
refresh_token:config.refreshToken,
5353
token_type:'bearer',
54-
scope:'notifications'
54+
scope:req.body.scope
5555
})
5656
}
5757
)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp