Skip to content

Commit 0524218

Browse files
authored
Merge pull request #30 from solid/fix/refresh-tokens
Fixed not completing refresh tokens
2 parents 72e4cfa + 26120fb commit 0524218

File tree

3 files changed

+99
-9
lines changed

3 files changed

+99
-9
lines changed

src/AccessToken.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class AccessToken extends JWT {
140140
let responseTypes = request.responseTypes || []
141141
let refresh
142142

143-
if (code || responseTypes.includes('code')) {
143+
if (code || responseTypes.includes('code') || request.grantType === 'refresh_token') {
144144
refresh = random(16)
145145
}
146146

src/handlers/TokenRequest.js

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ class TokenRequest extends BaseRequest {
3838
.then(request.authenticateClient)
3939
.then(request.verifyAuthorizationCode)
4040
.then(request.grant)
41-
.catch(err => request.error(err))
41+
.catch(err => {
42+
console.error(err)
43+
request.error(err)
44+
})
4245
}
4346

4447
/**
@@ -497,8 +500,39 @@ class TokenRequest extends BaseRequest {
497500
* @returns {Promise<Object>} Resolves to response object
498501
*/
499502
refreshTokenGrant (request) {
500-
// TODO: I don't think this.tokenResponse is implemented..
501-
return AccessToken.refresh(request).then(this.tokenResponse)
503+
return Promise.resolve({})
504+
.then(() => this.verifyRefreshToken(request))
505+
.then(response => request.includeAccessToken(response))
506+
.then(response => {
507+
request.res.json(response)
508+
})
509+
}
510+
511+
/**
512+
* Verify the refresh token
513+
*/
514+
verifyRefreshToken(request) {
515+
const { params, provider } = request;
516+
const refreshToken = params['refresh_token']
517+
if (!refreshToken || typeof refreshToken !== 'string') {
518+
return request.badRequest({
519+
error: 'invalid_grant',
520+
error_description: 'Invalid refresh token'
521+
})
522+
}
523+
return provider.backend.get('refresh', refreshToken).then((refreshTokenInfo) => {
524+
if (!refreshTokenInfo) {
525+
console.log('in here')
526+
return request.badRequest({
527+
error: 'invalid_grant',
528+
error_description: 'Refresh token not found'
529+
})
530+
}
531+
request.subject = {
532+
_id: refreshTokenInfo.payload.sub
533+
}
534+
return {}
535+
})
502536
}
503537

504538
/**

test/handlers/TokenRequestSpec.js

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,11 +1360,6 @@ describe('TokenRequest', () => {
13601360
})
13611361
})
13621362

1363-
/**
1364-
* Include Refresh Token
1365-
*/
1366-
describe('includeRefreshToken', () => {})
1367-
13681363
/**
13691364
* Include ID Token
13701365
*/
@@ -1396,6 +1391,67 @@ describe('TokenRequest', () => {
13961391
})
13971392
})
13981393

1394+
describe('verifyRefreshToken', () => {
1395+
it('should be okay with an existing token', () => {
1396+
const params = {
1397+
grant_type: 'refresh_token',
1398+
refresh_token: 'some_token',
1399+
client_id: 'uuid',
1400+
client_secret: 's3cr3t'
1401+
}
1402+
const req = {
1403+
method: 'POST',
1404+
body: params
1405+
}
1406+
const res = {}
1407+
const provider = {
1408+
host: {},
1409+
grant_types_supported: ['refresh_token'],
1410+
backend: {
1411+
get: async () => { Promise.resolve({"header":{},"payload":{"sub":"https://jackson.localhost:8443/profile/card#me"}}) }
1412+
}
1413+
}
1414+
const request = new TokenRequest(req, res, provider)
1415+
request.authenticateClient(request)
1416+
request.verifyRefreshToken(request).then(() => {
1417+
expect(request.subject._id).to.equal("https://jackson.localhost:8443/profile/card#me")
1418+
})
1419+
});
1420+
1421+
it('should fail without a refresh token', () => {
1422+
sinon.stub(TokenRequest.prototype, 'badRequest')
1423+
const params = {
1424+
grant_type: 'refresh_token',
1425+
client_id: 'uuid',
1426+
client_secret: 's3cr3t'
1427+
}
1428+
const req = {
1429+
method: 'POST',
1430+
body: params
1431+
}
1432+
const res = {
1433+
json: sinon.stub(),
1434+
set: sinon.stub(),
1435+
status: sinon.stub(),
1436+
}
1437+
const provider = {
1438+
host: {},
1439+
grant_types_supported: ['refresh_token'],
1440+
backend: {
1441+
get: async () => {}
1442+
}
1443+
}
1444+
const request = new TokenRequest(req, res, provider)
1445+
request.authenticateClient(request)
1446+
request.verifyRefreshToken(request)
1447+
request.badRequest.should.have.been.calledWith({
1448+
error: 'invalid_grant',
1449+
error_description: 'Invalid refresh token'
1450+
})
1451+
TokenRequest.prototype.badRequest.restore()
1452+
});
1453+
});
1454+
13991455
/**
14001456
* Include Session State
14011457
* TODO: should this be on the base class?

0 commit comments

Comments
 (0)