Skip to content

Commit 4cc1db9

Browse files
authored
feat: return claim on http validation (#8)
1 parent 017444b commit 4cc1db9

4 files changed

Lines changed: 78 additions & 9 deletions

File tree

src/cat.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ const CWT_TAG = 61;
8585
export type CommonAccessTokenClaims = {
8686
[key: string]: string | number | Map<number, any>;
8787
};
88+
export type CommonAccessTokenDict = {
89+
[key: string]: string | number | { [key: string]: any };
90+
};
8891
export type CommonAccessTokenValue =
8992
| string
9093
| number
@@ -272,14 +275,20 @@ export class CommonAccessToken {
272275
return this.payload.get(theKey);
273276
}
274277

275-
get claims() {
276-
const result: { [key: string]: string | number } = {};
278+
get claims(): CommonAccessTokenDict {
279+
const result: CommonAccessTokenDict = {};
277280
this.payload.forEach((value, param) => {
278281
const key = labelsToClaim[param] ? labelsToClaim[param] : param;
279-
const theValue = claimTransformReverse[key]
280-
? claimTransformReverse[key](value as Buffer)
281-
: (value as string | number);
282-
result[key] = theValue;
282+
if (key === 'catu') {
283+
result[key] = CommonAccessTokenUri.fromMap(
284+
value as Map<number, any>
285+
).toDict();
286+
} else {
287+
const theValue = claimTransformReverse[key]
288+
? claimTransformReverse[key](value as Buffer)
289+
: (value as string | number);
290+
result[key] = theValue;
291+
}
283292
});
284293
return result;
285294
}

src/catu.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,19 @@ export class CommonAccessTokenUri {
228228
return true;
229229
}
230230

231+
toDict() {
232+
const result: { [key: string]: any } = {};
233+
this.catuMap.forEach((uriPartMap, uriPart) => {
234+
const part = labelsToUriPart[uriPart];
235+
const match: { [key: string]: any } = {};
236+
uriPartMap.forEach((value, matchType) => {
237+
match[labelsToMatch[matchType]] = value;
238+
});
239+
result[part] = match;
240+
});
241+
return result;
242+
}
243+
231244
get payload() {
232245
return this.catuMap;
233246
}

src/validators/http.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,49 @@ describe('HTTP Request CAT Validator', () => {
267267
});
268268
expect(result.status).toBe(200);
269269
});
270+
271+
test('can get parsed claims from token', async () => {
272+
const token =
273+
'2D3RhEOhAQW5AAFhNExTeW1tZXRyaWMyNTZYO9kBA6IBZ2V5ZXZpbm4ZATjZAQOjANkBA6EAZWh0dHBzA9kBA6EBaC9jb250ZW50CNkBA6EAZS5tM3U4WCCD42NQN46M44nvyg4eD4tKUo2+spMlXhtOHW3IiUFiXg==';
274+
const httpValidator = new HttpValidator({
275+
keys: [
276+
{
277+
kid: 'Symmetric256',
278+
key: Buffer.from(
279+
'403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388',
280+
'hex'
281+
)
282+
}
283+
],
284+
issuer: 'eyevinn'
285+
});
286+
const result = await httpValidator.validateCloudFrontRequest({
287+
clientIp: 'dummy',
288+
method: 'GET',
289+
uri: '/content/path/file.m3u8',
290+
querystring: '',
291+
headers: {
292+
'cta-common-access-token': [
293+
{
294+
value: token
295+
}
296+
],
297+
host: [
298+
{
299+
key: 'Host',
300+
value: 'example.com'
301+
}
302+
]
303+
}
304+
});
305+
expect(result.status).toBe(200);
306+
expect(result.claims).toEqual({
307+
iss: 'eyevinn',
308+
catu: {
309+
scheme: { 'exact-match': 'https' },
310+
path: { 'prefix-match': '/content' },
311+
extension: { 'exact-match': '.m3u8' }
312+
}
313+
});
314+
});
270315
});

src/validators/http.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
UriNotAllowedError
99
} from '../errors';
1010
import { CloudFrontRequest } from 'aws-lambda';
11+
import { CommonAccessTokenDict } from '../cat';
1112

1213
interface HttpValidatorKey {
1314
kid: string;
@@ -24,6 +25,7 @@ export interface HttpValidatorOptions {
2425
export interface HttpResponse {
2526
status: number;
2627
message?: string;
28+
claims?: CommonAccessTokenDict;
2729
}
2830

2931
export class NoTokenFoundError extends Error {
@@ -53,7 +55,7 @@ export class NoTokenFoundError extends Error {
5355
* request,
5456
* 'Symmetric256'
5557
* );
56-
* // { status: 200, message: 'info' }
58+
* // { status: 200, message: 'info', claims: { iss: 'eyevinn' } }
5759
*/
5860
export class HttpValidator {
5961
private keys: { [key: string]: Buffer } = {};
@@ -109,12 +111,12 @@ export class HttpValidator {
109111
? request.headers['cta-common-access-token'][0]
110112
: request.headers['cta-common-access-token'];
111113
try {
112-
await validator.validate(token, 'mac', {
114+
const cat = await validator.validate(token, 'mac', {
113115
issuer: this.opts.issuer,
114116
audience: this.opts.audience,
115117
url
116118
});
117-
return { status: 200 };
119+
return { status: 200, claims: cat?.claims };
118120
} catch (err) {
119121
if (
120122
err instanceof InvalidIssuerError ||

0 commit comments

Comments
 (0)