Skip to content

Commit 26bc06e

Browse files
authored
isHttpHook: Support Koa ctx.req (#30)
1 parent e7bcb51 commit 26bc06e

File tree

5 files changed

+536
-8
lines changed

5 files changed

+536
-8
lines changed

.changeset/stale-zebras-pull.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@seek/aws-codedeploy-hooks': patch
3+
---
4+
5+
isHttpHook: Support Koa `ctx.req`

packages/hooks/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828
"dependencies": {},
2929
"devDependencies": {
3030
"@aws-sdk/client-lambda": "3.485.0",
31-
"@types/aws-lambda": "^8.10.130"
31+
"@types/aws-lambda": "^8.10.130",
32+
"@types/koa": "^2.13.6",
33+
"@types/supertest": "^6.0.2",
34+
"koa": "^2.15.0",
35+
"supertest": "^6.3.4"
3236
},
3337
"engines": {
3438
"node": ">=18.12"

packages/hooks/src/http.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
1+
import Koa from 'koa';
2+
import { agent } from 'supertest';
3+
14
import { isHttpHook } from './http';
25

36
describe('isHttpHook', () => {
47
it('is compatible with Request', () =>
58
expect(isHttpHook(new Request('https://example.com'))).toBeDefined());
69

10+
it('is compatible with Koa', () => {
11+
const app = new Koa().use((ctx) => {
12+
ctx.body = [
13+
isHttpHook(ctx.req),
14+
isHttpHook(ctx.request),
15+
isHttpHook(ctx.request.req),
16+
];
17+
});
18+
19+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
20+
return agent(app.callback())
21+
.get('/')
22+
.set('User-Agent', 'gantry-codedeploy-hook-BeforeAllowTraffic-dev/1.2.3')
23+
.expect(200, [true, true, true]);
24+
});
25+
726
it('recognises the Gantry hook', () =>
827
expect(
928
isHttpHook(
@@ -26,6 +45,19 @@ describe('isHttpHook', () => {
2645
),
2746
).toBe(true));
2847

48+
it('recognises one of multiple user agents', () =>
49+
expect(
50+
isHttpHook({
51+
headers: {
52+
'user-agent': [
53+
'rogue-agent',
54+
'aws-codedeploy-hook-BeforeAllowTraffic/123',
55+
'secret-agent',
56+
],
57+
},
58+
}),
59+
).toBe(true));
60+
2961
it('ignores a different user agent', () =>
3062
expect(
3163
isHttpHook(
@@ -37,6 +69,15 @@ describe('isHttpHook', () => {
3769
),
3870
).toBe(false));
3971

72+
it('ignores multiple different user agents', () =>
73+
expect(
74+
isHttpHook({
75+
headers: {
76+
'user-agent': ['Mozilla/5.0', 'Mozilla/6.0'],
77+
},
78+
}),
79+
).toBe(false));
80+
4081
it.each(['Mozilla/5.0', null, undefined, true])(
4182
'ignores a missing user agent',
4283
() => expect(isHttpHook(new Request('https://example.com'))).toBe(false),

packages/hooks/src/http.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import { GANTRY_HOOK_PREFIX, USER_AGENT_PREFIX } from './constants';
22

3+
type HeadersClass = { get: (name: string) => string | null };
4+
5+
type HeadersRecord = Record<string, null | string | string[] | undefined>;
6+
37
type HttpRequest = {
4-
headers: {
5-
get: (name: string) => string | null;
6-
};
8+
headers: HeadersClass | HeadersRecord;
79
};
810

11+
const isHeadersClass = (
12+
headers: HttpRequest['headers'],
13+
): headers is HeadersClass => typeof headers.get === 'function';
14+
915
/**
1016
* Whether the HTTP request originated from AWS CodeDeploy Hooks.
1117
*
@@ -34,10 +40,15 @@ type HttpRequest = {
3440
* Compatible with Gantry v2.3.7 and newer.
3541
*/
3642
export const isHttpHook = (req: HttpRequest): boolean => {
37-
const userAgent = req.headers.get('user-agent');
43+
const raw = isHeadersClass(req.headers)
44+
? req.headers.get('user-agent')
45+
: req.headers['user-agent'];
46+
47+
const userAgents: string[] = raw ? [raw].flat() : [];
3848

39-
return Boolean(
40-
userAgent?.startsWith(GANTRY_HOOK_PREFIX) ||
41-
userAgent?.startsWith(USER_AGENT_PREFIX),
49+
return userAgents.some(
50+
(userAgent) =>
51+
userAgent.startsWith(GANTRY_HOOK_PREFIX) ||
52+
userAgent.startsWith(USER_AGENT_PREFIX),
4253
);
4354
};

0 commit comments

Comments
 (0)