Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/stage-3-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ jobs:
- name: "Checkout code"
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: "Build docs"
uses: NHSDigital/nhs-notify-shared-modules/.github/actions/build-docs@3.0.0
uses: NHSDigital/nhs-notify-shared-modules/.github/actions/build-docs@3.1.6
with:
version: "${{ inputs.version }}"
4 changes: 2 additions & 2 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ GEM
ast (2.4.3)
base64 (0.3.0)
bigdecimal (4.1.2)
cgi (0.5.0)
cgi (0.5.1)
colorator (1.1.0)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
Expand All @@ -28,7 +28,7 @@ GEM
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
erb (4.0.4)
erb (4.0.4.1)
cgi (>= 0.3.3)
eventmachine (1.2.7)
ffi (1.17.2-aarch64-linux-gnu)
Expand Down
3 changes: 1 addition & 2 deletions lambdas/key-generation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
"dependencies": {
"date-fns": "^4.1.0",
"esbuild": "^0.25.9",
"node-jose": "^2.2.0",
"jose": "^5.10.0",
"utils": "*"
},
"devDependencies": {
"@tsconfig/node22": "^22.0.2",
"@types/aws-lambda": "^8.10.148",
"@types/jest": "^29.5.14",
"@types/node": "^24.0.10",
"@types/node-jose": "^1.1.13",
"jest": "^29.7.0",
"jest-mock-extended": "^3.0.7",
"typescript": "^5.8.2"
Expand Down
35 changes: 18 additions & 17 deletions lambdas/key-generation/src/__tests__/refresh-keystores.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { JWK } from 'node-jose';
import {
Key,
createKeyStore,
deleteKey,
generateNewKey,
logger,
Expand All @@ -10,7 +11,6 @@ import {
import { cleanAndRefreshKeystores } from 'refresh-keystores';
import { loadConfig } from 'config';

jest.mock('node-jose');
jest.mock('utils', () => {
const originalModule = jest.requireActual('utils');

Expand All @@ -19,6 +19,7 @@ jest.mock('utils', () => {
parameterStore: {
getAllParameters: jest.fn(),
},
createKeyStore: jest.fn(),
deleteKey: jest.fn(),
generateNewKey: jest.fn(),
uploadPublicKeystoreToS3: jest.fn(),
Expand All @@ -30,10 +31,10 @@ jest.mock('config');
const setupMocks = (preExistingKeys?: string[]) => {
const mockKeyStore = {
add: jest.fn(),
all: jest.fn().mockReturnValue(['']),
all: jest.fn().mockReturnValue([{ toJSON: () => ({ kid: 'mock-kid' }) }]),
};

(JWK.createKeyStore as jest.Mock).mockImplementation(() => mockKeyStore);
(createKeyStore as jest.Mock).mockImplementation(() => mockKeyStore);

(loadConfig as jest.Mock).mockReturnValue({
environment: 'env',
Expand Down Expand Up @@ -94,7 +95,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: true,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2021-02-24'),
});

Expand Down Expand Up @@ -127,7 +128,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: false,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2021-02-24'),
});

Expand Down Expand Up @@ -160,7 +161,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: true,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2021-02-23'),
});

Expand Down Expand Up @@ -195,7 +196,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: true,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2024-07-27'),
});

Expand Down Expand Up @@ -236,7 +237,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: true,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2024-06-30'),
});

Expand Down Expand Up @@ -279,12 +280,12 @@ describe('cleanAndRefreshKeystores', () => {
mockValidatePrivateKey
.mockResolvedValueOnce({
valid: false,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2024-07-30'),
})
.mockResolvedValueOnce({
valid: true,
keyJwk: {} as JWK.Key,
keyJwk: {} as unknown as Key,
keyDate: new Date('2024-08-27'),
});

Expand Down Expand Up @@ -332,7 +333,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: true,
keyJwk: { kid: 'key-1' } as JWK.Key,
keyJwk: { kid: 'key-1' } as unknown as Key,
keyDate: new Date('2024-09-01'), // 24 days old < 28 days threshold
});

Expand Down Expand Up @@ -361,12 +362,12 @@ describe('cleanAndRefreshKeystores', () => {
mockValidatePrivateKey
.mockResolvedValueOnce({
valid: true,
keyJwk: { kid: 'key1' } as JWK.Key,
keyJwk: { kid: 'key1' } as unknown as Key,
keyDate: new Date('2024-07-15'), // newer key first
})
.mockResolvedValueOnce({
valid: true,
keyJwk: { kid: 'key2' } as JWK.Key,
keyJwk: { kid: 'key2' } as unknown as Key,
keyDate: new Date('2024-06-01'), // older key second — should not update youngestKeyDate
});

Expand All @@ -390,12 +391,12 @@ describe('cleanAndRefreshKeystores', () => {
mockValidatePrivateKey
.mockResolvedValueOnce({
valid: true,
keyJwk: { kid: 'key1' } as JWK.Key,
keyJwk: { kid: 'key1' } as unknown as Key,
keyDate: new Date('2024-06-01'),
})
.mockResolvedValueOnce({
valid: true,
keyJwk: { kid: 'key2' } as JWK.Key,
keyJwk: { kid: 'key2' } as unknown as Key,
keyDate: new Date('2024-07-15'), // later
});

Expand All @@ -415,7 +416,7 @@ describe('cleanAndRefreshKeystores', () => {

mockValidatePrivateKey.mockResolvedValue({
valid: false,
keyJwk: { kid: 'ignored' } as JWK.Key,
keyJwk: { kid: 'ignored' } as unknown as Key,
keyDate: new Date('2000-01-01'),
});

Expand Down
6 changes: 3 additions & 3 deletions lambdas/key-generation/src/refresh-keystores.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { JWK } from 'node-jose';
import { isBefore, subDays } from 'date-fns';
import {
NonNullSSMParam,
createKeyStore,
deleteKey,
generateNewKey,
logger,
Expand All @@ -23,7 +23,7 @@ const deleteInvalidKeysAndCreateKeystore = async ({
now,
ssmPath,
}: DeleteInvalidKeysAndCreateKeystoreParams) => {
const keystore = JWK.createKeyStore();
const keystore = createKeyStore();
let youngestKeyDate: Date | null = null;

const allParams = await parameterStore.getAllParameters(ssmPath);
Expand Down Expand Up @@ -104,6 +104,6 @@ export const cleanAndRefreshKeystores = async ({
logger.info({
description: `Email auth keygen refresh complete: current key IDs: ${keystore
.all()
.map((key) => key.kid)}`,
.map((key) => key.toJSON().kid)}`,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { randomUUID } from 'node:crypto';

jest.mock('node:crypto', () => ({
...jest.requireActual('node:crypto'),
randomUUID: jest.fn(),
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const logger = mock<Logger>();
const eventPublisher = mock<EventPublisher>();

jest.mock('node:crypto', () => ({
...jest.requireActual('node:crypto'),
randomUUID: jest.fn(),
}));

Expand Down
Loading
Loading