Skip to content

Commit e6b9a15

Browse files
author
Thom Seddon
committed
Extend a53c893 by allowing token reissuing
Model can return an object to indicate a reissue, plain string (as in previous implementation) or null to revert to the default token generator
1 parent a53c893 commit e6b9a15

File tree

4 files changed

+73
-15
lines changed

4 files changed

+73
-15
lines changed

Readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ A model must provide the following methods:
118118
- `type` `String` Token type, one of 'accessToken' or 'refreshToken'
119119
- `callback` `Function` callback(error, token)
120120
- `error` `Mixed` Truthy to indicate an error
121-
- `token` `String` The access token
121+
- `token` `String|Object|Null` String accessToken to indicate success, Object to indicate reissue (i.e. will not be passed on save*Token()) or Null to revert to the default token generator
122122

123123
## Extension Grants
124124
You can support extension/custom grants by implementing the extendedGrant method as outlined above.
@@ -133,4 +133,4 @@ Created by Thom Seddon
133133

134134
## License
135135

136-
[Apache, Version 2.0](https://github.com/nightworld/node-oauth2-server/blob/master/LICENSE)
136+
[Apache, Version 2.0](https://github.com/nightworld/node-oauth2-server/blob/master/LICENSE)

lib/token.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ token.grantAccessToken = function (req, res, next) {
173173
var createRefreshToken = function (err, refreshToken) {
174174
if (err || !refreshToken) return next(err);
175175

176+
// Object indicates a reissue
177+
if (typeof refreshToken === 'object' && refreshToken.refresh_token) {
178+
req.oauth.accessToken.refresh_token = refreshToken.refresh_token;
179+
return token.issueToken.call(oauth, req, res, next);
180+
}
181+
176182
req.oauth.accessToken.refresh_token = refreshToken;
177183

178184
var expires = new Date(oauth.now);
@@ -186,9 +192,24 @@ token.grantAccessToken = function (req, res, next) {
186192
});
187193
};
188194

195+
var issueRefreshToken = function () {
196+
// Are we issuing refresh tokens?
197+
if (oauth.grants.indexOf('refresh_token') >= 0) {
198+
token.generateToken.call(oauth, 'refreshToken', req, createRefreshToken);
199+
} else {
200+
token.issueToken.call(oauth, req, res, next);
201+
}
202+
};
203+
189204
var createAccessToken = function (err, accessToken) {
190205
if (err || !accessToken) return next(err);
191206

207+
// Object idicates a reissue
208+
if (typeof accessToken === 'object' && accessToken.access_token) {
209+
req.oauth.accessToken = accessToken.access_token;
210+
return issueRefreshToken();
211+
}
212+
192213
req.oauth.accessToken = { access_token: accessToken };
193214

194215
var expires = new Date(oauth.now);
@@ -198,16 +219,11 @@ token.grantAccessToken = function (req, res, next) {
198219
req.user.id, expires, function (err) {
199220
if (err) return next(new OAuth2Error('server_error', false, err));
200221

201-
// Are we issuing refresh tokens?
202-
if (oauth.grants.indexOf('refresh_token') >= 0) {
203-
token.generateToken.call(oauth, 'refreshToken', createRefreshToken);
204-
} else {
205-
token.issueToken.call(oauth, req, res, next);
206-
}
222+
issueRefreshToken();
207223
});
208224
};
209225

210-
token.generateToken.call(oauth, 'accessToken', createAccessToken);
226+
token.generateToken.call(oauth, 'accessToken', req, createAccessToken);
211227
};
212228

213229
/**
@@ -233,12 +249,24 @@ token.issueToken = function (req, res, next) {
233249
/**
234250
* Convinience function for generating a token
235251
*
236-
* @param {Function} next Connect next
237-
* @return {String} Random 40 char token
252+
* @param {String} req Connect req
253+
* @param {Function} next Connect next
254+
* @param {Function} callback
255+
* @return {Void}
238256
*/
239-
token.generateToken = function (type, callback) {
240-
if (this.model.generateToken) return this.model.generateToken(type, callback);
257+
token.generateToken = function (type, req, callback) {
258+
if (this.model.generateToken) {
259+
this.model.generateToken(type, req, function (err, token) {
260+
if (err) return callback(new OAuth2Error('server_error'));
261+
if (!token) return token._generateToken(callback);
262+
callback(false, token);
263+
});
264+
} else {
265+
token._generateToken(callback);
266+
}
267+
};
241268

269+
token._generateToken= function (callback) {
242270
crypto.randomBytes(256, function (ex, buffer) {
243271
if (ex) return callback(new OAuth2Error('server_error'));
244272

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "node-oauth2-server",
33
"description": "Complete, compliant and well tested module for implementing an OAuth2 Server/Provider with express in node.js",
4-
"version": "1.2.0",
4+
"version": "1.2.1",
55
"keywords": [
66
"oauth",
77
"oauth2"

test/oauth2server.token.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ describe('OAuth2Server.token()', function() {
315315
getUser: function (uname, pword, callback) {
316316
callback(false, { id: 1 });
317317
},
318-
generateToken: function (type, callback) {
318+
generateToken: function (type, req, callback) {
319319
callback(false, 'thommy');
320320
},
321321
saveAccessToken: function (accessToken, clientId, userId, expires, callback) {
@@ -337,6 +337,36 @@ describe('OAuth2Server.token()', function() {
337337
.expect(/thommy/, 200, done);
338338

339339
});
340+
341+
it('should reissue if model returns object', function (done) {
342+
var app = bootstrap({
343+
model: {
344+
getClient: function (id, secret, callback) {
345+
callback(false, { client_id: id });
346+
},
347+
grantTypeAllowed: function (id, secret, callback) {
348+
callback(false, true);
349+
},
350+
getUser: function (uname, pword, callback) {
351+
callback(false, { id: 1 });
352+
},
353+
generateToken: function (type, req, callback) {
354+
callback(false, { access_token: 'thommy' });
355+
},
356+
saveAccessToken: function (accessToken, clientId, userId, expires, callback) {
357+
callback(new Error('Should not be saving'));
358+
}
359+
},
360+
grants: ['password']
361+
});
362+
363+
request(app)
364+
.post('/oauth/token')
365+
.set('Content-Type', 'application/x-www-form-urlencoded')
366+
.send(validBody)
367+
.expect(/thommy/, 200, done);
368+
369+
});
340370
});
341371

342372
describe('saving access token', function () {

0 commit comments

Comments
 (0)