Skip to content

Commit

Permalink
Merge pull request #12 from acasella/master
Browse files Browse the repository at this point in the history
Implement token revocation
  • Loading branch information
poveden authored Jun 3, 2019
2 parents a1148cd + 7fd9ea8 commit 9357f4e
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [1.3.0](https://github.com/axa-group/oauth2-mock-server/compare/v1.2.0...v1.3.0) — 2019-06-03

### Added

- Add revocation endpoint

## [1.2.0](https://github.com/axa-group/oauth2-mock-server/compare/v1.1.0...v1.2.0) — 2019-03-19

### Added
Expand Down
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ It also provides a convenient way, through event emitters, to programatically cu
- The JWT access token
- The token endpoint response body and status
- The userinfo endpoint response body and status
- The revoke endpoint response body and status

This is particularly useful when expecting the oidc service to behave in a specific way on one single test.

Expand All @@ -108,6 +109,13 @@ service.issuer.once('beforeSigning', (token) => {
const timestamp = Math.floor(Date.now() / 1000);
token.payload.exp = timestamp + 400;
});

//Simulates a custom token revocation body
service.once('beforeRevoke', (revokeResponse) => {
revokeResponse.body = {
result: 'revoked'
};
});
```

## Supported endpoints
Expand All @@ -130,15 +138,19 @@ Issues access tokens. Currently, this endpoint is limited to:
- Authorization code grant
- Refresh token grant

### GET /authorize
### GET `/authorize`

It simulates the user authentication. It will automatically redirect to the callback endpoint sent as parameter.
It currently supports only 'code' response_type.

### GET /userinfo
### GET `/userinfo`

It provides extra userinfo claims.

### POST `/revoke`

It simulates a token revocation. This endpoint should always return 200 as stated by [RFC 7009](https://tools.ietf.org/html/rfc7009#section-2.2).

## Command-Line Interface

The server can be run from the command line. Run `oauth2-mock-server --help` for details on its utilization.
Expand Down
13 changes: 13 additions & 0 deletions lib/oauth2-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const TOKEN_ENDPOINT_PATH = '/token';
const JWKS_URI_PATH = '/jwks';
const AUTHORIZE_PATH = '/authorize';
const USERINFO_PATH = '/userinfo';
const REVOKE_PATH = '/revoke';

const issuer = Symbol('issuer');
const requestHandler = Symbol('requestHandler');
Expand All @@ -41,6 +42,7 @@ const jwksHandler = Symbol('jwksHandler');
const tokenHandler = Symbol('tokenHandler');
const authorizeHandler = Symbol('authorizeHandler');
const userInfoHandler = Symbol('userInfoHandler');
const revokeHandler = Symbol('revokeHandler');

/**
* Provides a request handler for an OAuth 2 server.
Expand Down Expand Up @@ -97,6 +99,7 @@ class OAuth2Service extends EventEmitter {
this[tokenHandler].bind(this));
app.get(AUTHORIZE_PATH, OAuth2Service[authorizeHandler]);
app.get(USERINFO_PATH, this[userInfoHandler].bind(this));
app.post(REVOKE_PATH, this[revokeHandler].bind(this));

return app;
}
Expand All @@ -114,6 +117,7 @@ class OAuth2Service extends EventEmitter {
token_endpoint_auth_signing_alg_values_supported: ['RS256'],
response_modes_supported: ['query'],
id_token_signing_alg_values_supported: ['RS256'],
revocation_endpoint: `${this.issuer.url}${REVOKE_PATH}`,
};

return res.json(openidConfig);
Expand Down Expand Up @@ -224,5 +228,14 @@ class OAuth2Service extends EventEmitter {
this.emit('beforeUserinfo', userInfoResponse);
res.status(userInfoResponse.statusCode).json(userInfoResponse.body);
}

[revokeHandler](req, res) {
const revokeResponse = {
body: null,
statusCode: 200,
};
this.emit('beforeRevoke', revokeResponse);
return res.status(revokeResponse.statusCode).json(revokeResponse.body);
}
}
module.exports = OAuth2Service;
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "oauth2-mock-server",
"version": "1.2.0",
"version": "1.3.0",
"description": "OAuth 2 mock server",
"author": {
"name": "Jorge Poveda",
Expand Down
35 changes: 35 additions & 0 deletions test/oauth2-service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('OAuth 2 service', () => {
token_endpoint_auth_signing_alg_values_supported: ['RS256'],
response_modes_supported: ['query'],
id_token_signing_alg_values_supported: ['RS256'],
revocation_endpoint: `${url}/revoke`,
});
});

Expand Down Expand Up @@ -267,6 +268,40 @@ describe('OAuth 2 service', () => {
error_message: 'token is expired',
});
});

it('should expose the revoke endpoint', async () => {
const res = await request(service.requestHandler)
.post('/revoke')
.type('form')
.set('authorization', `Basic ${Buffer.from('dummy_client_id:dummy_client_secret').toString('base64')}`)
.send({
token: 'authorization_code',
token_type_hint: 'refresh_token',
})
.expect(200);

expect(res.body).toEqual(null);
});

it('should allow customizing the revoke response through a beforeRevoke event', async () => {
service.once('beforeRevoke', (revokeResponse) => {
/* eslint-disable no-param-reassign */
revokeResponse.body = '';
revokeResponse.statusCode = 204;
/* eslint-enable no-param-reassign */
});
const res = await request(service.requestHandler)
.post('/revoke')
.type('form')
.set('authorization', `Basic ${Buffer.from('dummy_client_id:dummy_client_secret').toString('base64')}`)
.send({
token: 'authorization_code',
token_type_hint: 'refresh_token',
})
.expect(204);

expect(res.text).toBeFalsy();
});
});

function tokenRequest(app) {
Expand Down

0 comments on commit 9357f4e

Please sign in to comment.