Skip to content

Commit

Permalink
fix: support httpAgent in JwksFetcher (#2689)
Browse files Browse the repository at this point in the history
Co-authored-by: Lahiru Maramba <[email protected]>
  • Loading branch information
hermanho and lahirumaramba authored Sep 4, 2024
1 parent 3e06bab commit 2fb4a27
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/app-check/token-verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class AppCheckTokenVerifier {
private readonly signatureVerifier: SignatureVerifier;

constructor(private readonly app: App) {
this.signatureVerifier = PublicKeySignatureVerifier.withJwksUrl(JWKS_URL);
this.signatureVerifier = PublicKeySignatureVerifier.withJwksUrl(JWKS_URL, app.options.httpAgent);
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/utils/jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@ export class JwksFetcher implements KeyFetcher {
private publicKeysExpireAt = 0;
private client: jwks.JwksClient;

constructor(jwksUrl: string) {
constructor(jwksUrl: string, httpAgent?: Agent) {
if (!validator.isURL(jwksUrl)) {
throw new Error('The provided JWKS URL is not a valid URL.');
}

this.client = jwks({
jwksUri: jwksUrl,
cache: false, // disable jwks-rsa LRU cache as the keys are always cached for 6 hours.
requestAgent: httpAgent,
});
}

Expand Down Expand Up @@ -190,8 +191,8 @@ export class PublicKeySignatureVerifier implements SignatureVerifier {
return new PublicKeySignatureVerifier(new UrlKeyFetcher(clientCertUrl, httpAgent));
}

public static withJwksUrl(jwksUrl: string): PublicKeySignatureVerifier {
return new PublicKeySignatureVerifier(new JwksFetcher(jwksUrl));
public static withJwksUrl(jwksUrl: string, httpAgent?: Agent): PublicKeySignatureVerifier {
return new PublicKeySignatureVerifier(new JwksFetcher(jwksUrl, httpAgent));
}

public verify(token: string): Promise<void> {
Expand Down
20 changes: 20 additions & 0 deletions test/unit/app-check/token-verifier.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as chai from 'chai';
import * as sinon from 'sinon';
import * as mocks from '../../resources/mocks';
import * as nock from 'nock';
import { Agent } from 'http';

import { AppCheckTokenVerifier } from '../../../src/app-check/token-verifier';
import { JwtError, JwtErrorCode, PublicKeySignatureVerifier } from '../../../src/utils/jwt';
Expand Down Expand Up @@ -55,6 +56,25 @@ describe('AppCheckTokenVerifier', () => {
}
});

describe('Constructor', () => {
it('AppOptions.httpAgent should be passed to PublicKeySignatureVerifier.withJwksUrl', () => {
const mockAppWithAgent = mocks.appWithOptions({
httpAgent: new Agent()
});
const agentForApp = mockAppWithAgent.options.httpAgent;
const verifierSpy = sinon.spy(PublicKeySignatureVerifier, 'withJwksUrl');

expect(verifierSpy.args).to.be.empty;

new AppCheckTokenVerifier(
mockAppWithAgent
);

expect(verifierSpy.args[0][1]).to.equal(agentForApp);
verifierSpy.restore();
});
});

describe('verifyJWT()', () => {
let mockedRequests: nock.Scope[] = [];
let stubs: sinon.SinonStub[] = [];
Expand Down
11 changes: 11 additions & 0 deletions test/unit/utils/jwt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'use strict';

// Use untyped import syntax for Node built-ins
import http = require('http');
import https = require('https');

import * as _ from 'lodash';
Expand Down Expand Up @@ -380,6 +381,16 @@ describe('PublicKeySignatureVerifier', () => {
expect(verifier).to.be.an.instanceOf(PublicKeySignatureVerifier);
expect((verifier as any).keyFetcher).to.be.an.instanceOf(JwksFetcher);
});

it('should return a PublicKeySignatureVerifier instance with a JwksFetcher when a ' +
'valid jwks url and httpAgent is provided', () => {
const mockHttpAgent = sinon.createStubInstance(http.Agent);
const verifier = PublicKeySignatureVerifier.withJwksUrl('https://www.example.com/publicKeys', mockHttpAgent);
expect(verifier).to.be.an.instanceOf(PublicKeySignatureVerifier);
expect((verifier as any).keyFetcher).to.be.an.instanceOf(JwksFetcher);
expect((verifier as any).keyFetcher.client.options.requestAgent).to.be.an.instanceOf(http.Agent);
expect((verifier as any).keyFetcher.client.options.requestAgent).to.eq(mockHttpAgent);
});
});

describe('verify', () => {
Expand Down

0 comments on commit 2fb4a27

Please sign in to comment.