From 4abe326743823e652d33e00e89a39630ce1af0ef Mon Sep 17 00:00:00 2001 From: Rune Botten Date: Wed, 7 Jan 2026 13:02:03 -0800 Subject: [PATCH 1/3] fix(refresh-token): validate scope before revoking token #390 --- lib/grant-types/refresh-token-grant-type.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/grant-types/refresh-token-grant-type.js b/lib/grant-types/refresh-token-grant-type.js index 45237dbc..c66fee28 100644 --- a/lib/grant-types/refresh-token-grant-type.js +++ b/lib/grant-types/refresh-token-grant-type.js @@ -54,10 +54,12 @@ class RefreshTokenGrantType extends AbstractGrantType { let token; token = await this.getRefreshToken(request, client); - token = await this.revokeToken(token); + // Validate scope before revoking token to prevent destroying tokens on scope validation errors const scope = this.getScope(request, token); + token = await this.revokeToken(token); + return this.saveToken(token.user, client, scope); } From e971cfbd6b89b0de5a23ebcae081da75c53d7754 Mon Sep 17 00:00:00 2001 From: Rune Botten Date: Wed, 7 Jan 2026 14:47:25 -0800 Subject: [PATCH 2/3] test(refresh-token): add test for extra scope validation #390 --- .../refresh-token-grant-type_test.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/integration/grant-types/refresh-token-grant-type_test.js b/test/integration/grant-types/refresh-token-grant-type_test.js index 0619fefd..597e47b0 100644 --- a/test/integration/grant-types/refresh-token-grant-type_test.js +++ b/test/integration/grant-types/refresh-token-grant-type_test.js @@ -7,6 +7,7 @@ const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error'); const InvalidGrantError = require('../../../lib/errors/invalid-grant-error'); const InvalidRequestError = require('../../../lib/errors/invalid-request-error'); +const InvalidScopeError = require('../../../lib/errors/invalid-scope-error'); const RefreshTokenGrantType = require('../../../lib/grant-types/refresh-token-grant-type'); const Request = require('../../../lib/request'); const ServerError = require('../../../lib/errors/server-error'); @@ -182,6 +183,34 @@ describe('RefreshTokenGrantType integration', function() { grantType.handle(request, client).should.be.an.instanceOf(Promise); }); + + it('should throw an error if extra `scope` is requested', async function() { + const client = { id: 123 }; + const token = { + accessToken: 'foo', + client: { id: 123 }, + user: { name: 'foo' }, + refreshTokenExpiresAt: new Date(new Date() * 2) + }; + const model = { + getRefreshToken: async function() { + return token; + }, + revokeToken: () => should.fail(), + saveToken: () => should.fail() + }; + const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model }); + const request = new Request({ body: { refresh_token: 'foobar', scope: 'read' }, headers: {}, method: {}, query: {} }); + + try { + await grantType.handle(request, client); + + should.fail(); + } catch (e) { + e.should.be.an.instanceOf(InvalidScopeError); + e.message.should.equal('Invalid scope: Unable to add extra scopes'); + } + }); }); describe('getRefreshToken()', function() { From 0565522a7567094a96aceb9c9a27f0cb73338fc8 Mon Sep 17 00:00:00 2001 From: jankapunkt Date: Mon, 12 Jan 2026 12:40:34 +0100 Subject: [PATCH 3/3] release 5.2.2-rc.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4eddd526..1953980a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@node-oauth/oauth2-server", - "version": "5.2.0", + "version": "5.2.2-rc.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@node-oauth/oauth2-server", - "version": "5.2.0", + "version": "5.2.2-rc.0", "license": "MIT", "dependencies": { "@node-oauth/formats": "1.0.0", diff --git a/package.json b/package.json index 3e773f5f..6ad85d9c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@node-oauth/oauth2-server", "description": "Complete, framework-agnostic, compliant and well tested module for implementing an OAuth2 Server in node.js", - "version": "5.2.0", + "version": "5.2.2-rc.0", "keywords": [ "oauth", "oauth2"