diff --git a/src/validators/http.test.ts b/src/validators/http.test.ts index 0444986..fa746d1 100644 --- a/src/validators/http.test.ts +++ b/src/validators/http.test.ts @@ -346,6 +346,7 @@ describe('HTTP Request CAT Validator with auto renew', () => { type: 'automatic', 'header-name': 'cta-common-access-token', 'cookie-name': 'cta-common-access-token', + 'cookie-params': ['Secure', 'HttpOnly', 'Domain=.eyevinn.technology'], code: 301, expadd: 120, deadline: 60 @@ -374,6 +375,28 @@ describe('HTTP Request CAT Validator with auto renew', () => { ], issuer: 'eyevinn' }); + const now = Math.floor(Date.now() / 1000); + base64encoded = await generator.generate( + { + iss: 'eyevinn', + exp: now + 60, + catr: CommonAccessTokenRenewal.fromDict({ + type: 'header', + 'header-name': 'cta-common-access-token', + 'cookie-name': 'cta-common-access-token', + 'header-params': ['Secure', 'HttpOnly', 'Domain=.eyevinn.technology'], + code: 301, + expadd: 120, + deadline: 60 + }).payload + }, + { + type: 'mac', + alg: 'HS256', + kid: 'Symmetric256', + generateCwtId: true + } + ); const request = createRequest({ method: 'GET', headers: { @@ -383,6 +406,9 @@ describe('HTTP Request CAT Validator with auto renew', () => { const response = createResponse(); const result = await httpValidator.validateHttpRequest(request, response); expect(result.status).toBe(200); + expect(response.getHeader('cta-common-access-token')).toMatch( + /^(\S+); Secure; HttpOnly; Domain=.eyevinn.technology/ + ); expect(response.getHeader('cta-common-access-token')).toBeDefined(); const renewDisabled = new HttpValidator({ @@ -404,6 +430,75 @@ describe('HTTP Request CAT Validator with auto renew', () => { expect(response2.getHeader('cta-common-access-token')).toBeUndefined(); }); + test('can autorenew and set cookie when autorenew is enabled', async () => { + // Validate and auto renew + const httpValidator = new HttpValidator({ + keys: [ + { + kid: 'Symmetric256', + key: Buffer.from( + '403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388', + 'hex' + ) + } + ], + issuer: 'eyevinn' + }); + const now = Math.floor(Date.now() / 1000); + base64encoded = await generator.generateFromJson( + { + iss: 'eyevinn', + exp: now + 60, + catr: { + type: 'cookie', + 'header-name': 'cta-common-access-token', + 'cookie-name': 'cta-common-access-token', + 'cookie-params': ['Secure', 'HttpOnly', 'Domain=.eyevinn.technology'], + code: 301, + expadd: 120, + deadline: 60 + } + }, + { + type: 'mac', + alg: 'HS256', + kid: 'Symmetric256', + generateCwtId: true + } + ); + const request = createRequest({ + method: 'GET', + headers: { + 'CTA-Common-Access-Token': base64encoded + } + }); + const response = createResponse(); + const result = await httpValidator.validateHttpRequest(request, response); + expect(result.status).toBe(200); + expect(response.getHeader('set-cookie')).toBeDefined(); + expect(response.getHeader('set-cookie')).toMatch( + /^cta-common-access-token=(\S+); Secure; HttpOnly; Domain=.eyevinn.technology/ + ); + + const renewDisabled = new HttpValidator({ + keys: [ + { + kid: 'Symmetric256', + key: Buffer.from( + '403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388', + 'hex' + ) + } + ], + issuer: 'eyevinn', + autoRenewEnabled: false + }); + const response2 = createResponse(); + const result2 = await renewDisabled.validateHttpRequest(request, response2); + expect(result2.status).toBe(200); + expect(response2.getHeader('cta-common-access-token')).toBeUndefined(); + }); + test('can autorenew when autorenew is enabled and only when token is about to expire', async () => { base64encoded = await generator.generate( { @@ -413,6 +508,7 @@ describe('HTTP Request CAT Validator with auto renew', () => { type: 'automatic', 'header-name': 'cta-common-access-token', 'cookie-name': 'cta-common-access-token', + 'cookie-params': ['Secure', 'HttpOnly', 'Domain=.a2d.tv'], code: 302, expadd: 120, deadline: 60 diff --git a/src/validators/http.ts b/src/validators/http.ts index ce7d670..2e161ec 100644 --- a/src/validators/http.ts +++ b/src/validators/http.ts @@ -21,6 +21,7 @@ import { ICTIStore } from '../stores/interface'; import { ITokenLogger } from '../loggers/interface'; import { CatIfDictValue } from '../catif'; import { toBase64NoPadding } from '../util'; +import { Log } from '../log'; interface HttpValidatorKey { kid: string; @@ -459,7 +460,13 @@ export class HttpValidator { response.setHeader( catr['header-name'] || headerName, renewedToken + - (catr['header-params'] ? `;${catr['header-params']}` : '') + (catr['header-params'] + ? `; ${ + Array.isArray(catr['header-params']) + ? catr['header-params'].join('; ') + : catr['header-params'] + }` + : '') ); } else if ( catr.type === 'cookie' || @@ -468,8 +475,12 @@ export class HttpValidator { const cookieName = catr['cookie-name'] || 'cta-common-access-token'; response.setHeader( 'Set-Cookie', - `${cookieName}=${renewedToken}${ - catr['cookie-params'] ? '; ' + catr['cookie-params'] : '' + `${cookieName}=${renewedToken}; ${ + catr['cookie-params'] + ? '; ' + Array.isArray(catr['cookie-params']) + ? catr['cookie-params'].join('; ') + : catr['cookie-params'] + : '' }` ); } else if (