Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgraded aws sdk to v3 #59

Merged
merged 1 commit into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Set up Node.js
uses: actions/[email protected]
with:
node-version: '14.x'
node-version: '20.x'

- name: Install dependencies
run: yarn
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Node.js
uses: actions/[email protected]
with:
node-version: 14
node-version: 20

- name: Install dependencies
run: yarn
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)

## [6.0.0] - 2022-02-22

### Changed

- **[Breaking change]** Upgraded aws-sdk to v3 which has `SecretsManager` and `KMS` replaced by `SecretsManagerClient` and `KMSClient` class.
The functionality and interface remains the same, the imports need to be changed.

## [5.4.0] - 2024-02-08

### Added
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lambda-essentials-ts",
"version": "5.4.0",
"version": "6.0.0",
"description": "A selection of the finest modules supporting authorization, API routing, error handling, logging and sending HTTP requests.",
"main": "lib/index.js",
"private": false,
Expand All @@ -26,7 +26,8 @@
},
"homepage": "https://github.com/Cimpress-MCP/lambda-essentials-ts#readme",
"dependencies": {
"aws-sdk": "^2.1287.0",
"@aws-sdk/client-kms": "^3.569.0",
"@aws-sdk/client-secrets-manager": "^3.569.0",
"axios": "~0.21.3",
"axios-cache-adapter": "~2.7.3",
"fast-safe-stringify": "~2.0.7",
Expand Down
17 changes: 8 additions & 9 deletions src/tokenProvider/kmsTokenProvider.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { KMS } from 'aws-sdk';
import TokenProvider, {
Auth0Secret,
TokenConfiguration,
TokenProviderOptions,
} from './tokenProvider';
import { DecryptCommand, KMSClient } from '@aws-sdk/client-kms';

export default class KmsTokenProvider extends TokenProvider {
private kmsClient: KMS;
private kmsClient: KMSClient;

private kmsConfiguration: KmsTokenConfiguration;

Expand All @@ -17,13 +17,12 @@ export default class KmsTokenProvider extends TokenProvider {
}

public async getClientSecret(): Promise<Auth0Secret | undefined> {
const secret = await this.kmsClient
.decrypt({
const data = await this.kmsClient.send(
new DecryptCommand({
CiphertextBlob: Buffer.from(this.kmsConfiguration.encryptedClientSecret, 'base64'),
})
.promise()
.then((data) => data.Plaintext?.toString());

}),
);
const secret = data.Plaintext?.toString();
if (!secret) {
throw new Error('Request error: failed to decrypt secret using KMS');
}
Expand All @@ -36,7 +35,7 @@ export interface KmsTokenProviderOptions extends TokenProviderOptions {
/**
* AWS KMS Client
*/
kmsClient: KMS;
kmsClient: KMSClient;
/**
* Configuration needed for the token
*/
Expand Down
14 changes: 8 additions & 6 deletions src/tokenProvider/secretsManagerTokenProvider.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { SecretsManager } from 'aws-sdk';
import TokenProvider, {
Auth0Secret,
TokenConfiguration,
TokenProviderOptions,
} from './tokenProvider';
import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager';

export default class SecretsManagerTokenProvider extends TokenProvider {
private secretsManagerClient: SecretsManager;
private secretsManagerClient: SecretsManagerClient;

private secretsManagerConfiguration: SecretsManagerTokenConfiguration;

Expand All @@ -17,9 +17,11 @@ export default class SecretsManagerTokenProvider extends TokenProvider {
}

public async getClientSecret(): Promise<Auth0Secret | undefined> {
const secret = await this.secretsManagerClient
.getSecretValue({ SecretId: this.secretsManagerConfiguration.clientSecretId })
.promise();
const secret = await this.secretsManagerClient.send(
new GetSecretValueCommand({
SecretId: this.secretsManagerConfiguration.clientSecretId,
}),
);

if (!secret?.SecretString) {
throw new Error('Request error: failed to retrieve secret from Secrets Manager');
Expand All @@ -33,7 +35,7 @@ export interface SecretsManagerTokenProviderOptions extends TokenProviderOptions
/**
* AWS Secrets Manager Client
*/
secretsManagerClient: SecretsManager;
secretsManagerClient: SecretsManagerClient;
/**
* Configuration needed for the token
*/
Expand Down
26 changes: 15 additions & 11 deletions tests/tokenProvider/kmsTokenProvider.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { KMS } from 'aws-sdk';
import { KmsTokenConfiguration, KmsTokenProvider } from '../../src';
import { Auth0Secret } from '../../src/tokenProvider/tokenProvider';
import { KMSClient } from '@aws-sdk/client-kms';

describe('KMS Token Provider', () => {
const tokenConfiguration: KmsTokenConfiguration = {
Expand All @@ -12,10 +12,10 @@ describe('KMS Token Provider', () => {

describe('getClientSecret', () => {
test('throws when secret was not decrypted', async () => {
const promisedDecryptedText = Promise.resolve({ data: { Plaintext: undefined } });
const promisedDecryptedText = { data: { Plaintext: undefined } };
const KMSMock = jest.fn().mockImplementation(
(): Partial<KMS> => ({
decrypt: jest.fn().mockReturnValue({ promise: () => promisedDecryptedText }),
(): Partial<KMSClient> => ({
send: jest.fn().mockResolvedValue(promisedDecryptedText),
}),
);

Expand All @@ -34,12 +34,12 @@ describe('KMS Token Provider', () => {
Auth0ClientID: 'test-client-id',
Auth0ClientSecret: 'test-secret',
};
const promisedDecryptedText = Promise.resolve({
const promisedDecryptedText = {
Plaintext: expectedSecret.Auth0ClientSecret,
});
};
const KMSMock = jest.fn().mockImplementation(
(): Partial<KMS> => ({
decrypt: jest.fn().mockReturnValue({ promise: () => promisedDecryptedText }),
(): Partial<KMSClient> => ({
send: jest.fn().mockResolvedValue(promisedDecryptedText),
}),
);

Expand All @@ -51,9 +51,13 @@ describe('KMS Token Provider', () => {

const actualSecret = await tokenProvider.getClientSecret();
expect(actualSecret).toEqual(expectedSecret);
expect(kms.decrypt).toHaveBeenCalledWith({
CiphertextBlob: Buffer.from(tokenConfiguration.encryptedClientSecret, 'base64'),
});
expect(kms.send).toHaveBeenCalledWith(
expect.objectContaining({
input: {
CiphertextBlob: Buffer.from(tokenConfiguration.encryptedClientSecret, 'base64'),
},
}),
);
});
});
});
22 changes: 12 additions & 10 deletions tests/tokenProvider/secretsManagerTokenProvider.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SecretsManager } from 'aws-sdk';
import { SecretsManagerTokenConfiguration, SecretsManagerTokenProvider } from '../../src';
import { Auth0Secret } from '../../src/tokenProvider/tokenProvider';
import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager';

describe('Secrets Manager Token Provider', () => {
const tokenConfiguration: SecretsManagerTokenConfiguration = {
Expand All @@ -11,10 +11,10 @@ describe('Secrets Manager Token Provider', () => {

describe('getClientSecret', () => {
test('throws when secret was not retrieved', async () => {
const promisedSecret = Promise.resolve({ SecretString: undefined });
const promisedSecret = { SecretString: undefined };
const SecretsManagerMock = jest.fn().mockImplementation(
(): Partial<SecretsManager> => ({
getSecretValue: jest.fn().mockReturnValue({ promise: () => promisedSecret }),
(): Partial<SecretsManagerClient> => ({
send: jest.fn().mockResolvedValueOnce(promisedSecret),
}),
);

Expand All @@ -33,10 +33,10 @@ describe('Secrets Manager Token Provider', () => {
Auth0ClientID: 'test-client-id',
Auth0ClientSecret: 'test-secret',
};
const promisedSecret = Promise.resolve({ SecretString: JSON.stringify(expectedSecret) });
const promisedSecret = { SecretString: JSON.stringify(expectedSecret) };
const SecretsManagerMock = jest.fn().mockImplementation(
(): Partial<SecretsManager> => ({
getSecretValue: jest.fn().mockReturnValue({ promise: () => promisedSecret }),
(): Partial<SecretsManagerClient> => ({
send: jest.fn().mockResolvedValueOnce(promisedSecret),
}),
);

Expand All @@ -48,9 +48,11 @@ describe('Secrets Manager Token Provider', () => {

const actualSecret = await tokenProvider.getClientSecret();
expect(actualSecret).toEqual(expectedSecret);
expect(secretsManager.getSecretValue).toHaveBeenCalledWith({
SecretId: tokenConfiguration.clientSecretId,
});
expect(secretsManager.send).toHaveBeenCalledWith(
expect.objectContaining({
input: { SecretId: tokenConfiguration.clientSecretId },
}),
);
});
});
});
Loading
Loading