Skip to content

Commit 9c4fe30

Browse files
committed
More forgiving timestamp validation
1 parent a5c5825 commit 9c4fe30

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

lambdas/api-handler/src/handlers/__tests__/post-mi.test.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,22 @@ describe('postMI API Handler', () => {
7272
});
7373

7474

75-
it.each([['not a date string'], ['2025-10-16T00:00:00'], ['2025-16-10T00:00:00Z']])
76-
('returns 400 Bad Request when the timestamp is not an ISO8601 instant', async (timestamp: string) => {
77-
const invalidRequest = JSON.parse(requestBody);
78-
invalidRequest['data']['attributes']['timestamp'] = timestamp;
75+
it.each([['not a date string', false], ['2025-10-16T00:00:00', false], ['2025-16-10T00:00:00Z', false],
76+
['2025-10-16T00:00:00Z', true], ['2025-10-16T00:00:00.000000Z', true]])
77+
('validates the timestamp', async (timestamp: string, valid: boolean) => {
78+
const modifiedRequest = JSON.parse(requestBody);
79+
modifiedRequest['data']['attributes']['timestamp'] = timestamp;
7980
const event = makeApiGwEvent({
8081
path: '/mi',
81-
body: JSON.stringify(invalidRequest),
82+
body: JSON.stringify(modifiedRequest),
8283
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId'}
8384
});
8485

8586
const postMI = createPostMIHandler(mockedDeps);
8687
const result = await postMI(event, mockDeep<Context>(), jest.fn());
8788

8889
expect(result).toEqual(expect.objectContaining({
89-
statusCode: 400
90+
statusCode: valid? 201: 400
9091
}));
9192
});
9293

lambdas/api-handler/src/handlers/post-mi.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ export function createPostMIHandler(deps: Deps): APIGatewayProxyHandler {
4747

4848
function validateIso8601Timestamp(timestamp: string) {
4949

50-
const date = new Date(timestamp);
51-
if (Number.isNaN(date.valueOf()) || date.toISOString() !== timestamp) {
50+
// If timestamp looks like a date, but is not valid (e.g. 2025-02-31T13:45:56Z), then new Date(timestamp).valueOf()
51+
// will return NaN
52+
if (! /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d+)?Z/.test(timestamp) || Number.isNaN(new Date(timestamp).valueOf())) {
5253
throw new ValidationError(ApiErrorDetail.InvalidRequestTimestamp);
5354
}
5455
}

0 commit comments

Comments
 (0)