Commit e1e43428 authored by Robert Knight's avatar Robert Knight

Simplify `state` string generation mocking

Now that we have good support for mocking imports in tests, we can use
that to mock `generateHexString` calls in `OAuthClient` rather than
needing to have a test seam in the class.

This improves test coverage slightly.
parent 8040bf0d
......@@ -3,7 +3,7 @@ import { generateHexString } from './random';
/**
* An object holding the details of an access token from the tokenUrl endpoint.
*
* @typedef {Object} TokenInfo
* @typedef TokenInfo
* @prop {string} accessToken - The access token itself.
* @prop {number} expiresAt - The date when the timestamp will expire.
* @prop {string} refreshToken - The refresh token that can be used to
......@@ -24,25 +24,14 @@ export class TokenError extends Error {
}
}
/**
* Generate a short random string suitable for use as the "state" param in
* authorization requests.
*
* See https://tools.ietf.org/html/rfc6749#section-4.1.1.
*/
function generateState() {
return generateHexString(16);
}
/**
* OAuthClient configuration.
*
* @typedef {Object} Config
* @property {string} clientId - OAuth client ID
* @property {string} tokenEndpoint - OAuth token exchange/refresh endpoint
* @property {string} authorizationEndpoint - OAuth authorization endpoint
* @property {string} revokeEndpoint - RFC 7009 token revocation endpoint
* @property {() => string} [generateState] - Authorization "state" parameter generator
* @typedef Config
* @prop {string} clientId - OAuth client ID
* @prop {string} tokenEndpoint - OAuth token exchange/refresh endpoint
* @prop {string} authorizationEndpoint - OAuth authorization endpoint
* @prop {string} revokeEndpoint - RFC 7009 token revocation endpoint
*/
/**
......@@ -60,9 +49,6 @@ export default class OAuthClient {
this.tokenEndpoint = config.tokenEndpoint;
this.authorizationEndpoint = config.authorizationEndpoint;
this.revokeEndpoint = config.revokeEndpoint;
// Test seam
this.generateState = config.generateState || generateState;
}
/**
......@@ -136,7 +122,9 @@ export default class OAuthClient {
authorize($window, authWindow) {
// Random state string used to check that auth messages came from the popup
// window that we opened.
const state = this.generateState();
//
// See https://tools.ietf.org/html/rfc6749#section-4.1.1.
const state = generateHexString(16);
// Promise which resolves or rejects when the user accepts or closes the
// auth popup.
......
import fetchMock from 'fetch-mock';
import sinon from 'sinon';
import { TokenError } from '../oauth-client';
import { $imports, TokenError } from '../oauth-client';
import OAuthClient from '../oauth-client';
import FakeWindow from '../../test/fake-window';
......@@ -31,7 +31,6 @@ describe('sidebar/util/oauth-client', () => {
authorizationEndpoint: 'https://annota.te/oauth/authorize',
tokenEndpoint: 'https://annota.te/api/token',
revokeEndpoint: 'https://annota.te/oauth/revoke',
generateState: () => 'notrandom',
};
beforeEach(() => {
......@@ -44,6 +43,7 @@ describe('sidebar/util/oauth-client', () => {
});
afterEach(() => {
$imports.$restore();
fetchMock.restore();
clock.restore();
});
......@@ -215,6 +215,12 @@ describe('sidebar/util/oauth-client', () => {
beforeEach(() => {
fakeWindow = new FakeWindow();
$imports.$mock({
'./random': {
generateHexString: () => 'notrandom',
},
});
});
function authorize() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment