Skip to content
Open
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
15 changes: 15 additions & 0 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/provider/credentials-handler.lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function handler(event: OnEventRequest): Promise<OnEventResponse |
const secretId = event.ResourceProperties.SecretId;
const userNameSecretKey = event.ResourceProperties.UserNameSecretKey;
const passwordSecretKey = event.ResourceProperties.PasswordSecretKey;
const region = process.env.AWS_DEFAULT_REGION as string;
const region = process.env.SES_REGION as string;
const iam = new AWS.IAM();
const secretsManager = new AWS.SecretsManager();

Expand Down
18 changes: 15 additions & 3 deletions src/provider/credentials-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,35 @@ import { Provider } from "aws-cdk-lib/custom-resources";
import { Construct } from "constructs";
import { CredentialsHandlerFunction } from "./credentials-handler-function";

/**
* Props for CredentialsHandlerFunction
*/
export interface CredentialsProviderProps {
/**
* The region of SES endpoint to use. Defaults to stack region.
*/
region: string;
}

export class CredentialsProvider extends Construct {
/**
* Retrieve CredentialsProvider as stack singleton resource.
*
* https://github.com/aws/aws-cdk/issues/5023
*/
public static getOrCreate(scope: Construct): CredentialsProvider {
public static getOrCreate(scope: Construct, props: CredentialsProviderProps): CredentialsProvider {
const stack = Stack.of(scope);
const id = "cdk-ses-smtp-credentials.CredentialsProvider";
const existing = stack.node.tryFindChild(id);
return (existing as CredentialsProvider) || new CredentialsProvider(stack, id);
return (existing as CredentialsProvider) || new CredentialsProvider(stack, id, { region: props.region });
}

public readonly serviceToken: string;

private userArns: string[] = [];
private secretArns: string[] = [];

constructor(scope: Construct, id: string) {
constructor(scope: Construct, id: string, props: CredentialsProviderProps) {
super(scope, id);

// https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html
Expand All @@ -50,6 +60,8 @@ export class CredentialsProvider extends Construct {
],
logRetention: RetentionDays.ONE_MONTH,
});
// register ses-region for auto-generated lambda function
onEvent.addEnvironment("SES_REGION", props.region, { removeInEdge: true });

const provider = new Provider(this, "ses-smtp-credentials-provider", {
onEventHandler: onEvent,
Expand Down
8 changes: 6 additions & 2 deletions src/ses-smtp-credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { CredentialsProvider } from "./provider/credentials-provider";
import { SMTP_REGIONS } from "./provider/ses-smtp-regions";

export interface SesSmtpCredentialsProps {
/**
* The region of SES endpoint to use. Defaults to stack region.
*/
readonly region?: string;
/**
* The user for which to create an AWS Access Key and to generate the smtp password. If omitted a user will be created.
*/
Expand Down Expand Up @@ -62,7 +66,7 @@ export class SesSmtpCredentials extends Construct {
public constructor(scope: Construct, id: string, props: SesSmtpCredentialsProps) {
super(scope, id);

const region = Stack.of(this).region;
const region = props.region ?? Stack.of(this).region;
if (!SMTP_REGIONS.includes(region)) {
Annotations.of(this).addWarning(
`AWS SES Smtp Endpoint is not available in region ${region}\n see https://docs.aws.amazon.com/general/latest/gr/ses.html`,
Expand Down Expand Up @@ -93,7 +97,7 @@ export class SesSmtpCredentials extends Construct {
description: `SES Smtp Credentials (username, password) for ${user.userName}`,
});

const provider = CredentialsProvider.getOrCreate(this);
const provider = CredentialsProvider.getOrCreate(this, { region: region });
provider.grant(user, this.secret);

const customResource = new CustomResource(this, "Lambda", {
Expand Down
5 changes: 4 additions & 1 deletion test/__snapshots__/integ.default.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/provider/credentials-handler-function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as sinon from "sinon";
describe("provider.credentials-handler.lambda", () => {
jest.setTimeout(60_000);
console.log = jest.fn();
process.env.AWS_DEFAULT_REGION = "us-east-1";
process.env.SES_REGION = "us-east-1";

let handler: (event: OnEventRequest) => Promise<OnEventResponse | undefined>;
beforeEach(async () => {
Expand Down
4 changes: 2 additions & 2 deletions test/provider/credentials-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("CredentialsProvider", () => {
const user = new User(stack, "User");
const secret = new Secret(stack, "Secret");

const provider = CredentialsProvider.getOrCreate(stack);
const provider = CredentialsProvider.getOrCreate(stack, { region: "us-east-1" });
provider.grant(user, secret);

// When
Expand All @@ -28,7 +28,7 @@ describe("CredentialsProvider", () => {
const user = new User(stack, "User");
const secret = new Secret(stack, "Secret");

const provider = CredentialsProvider.getOrCreate(stack);
const provider = CredentialsProvider.getOrCreate(stack, { region: "us-east-1" });
provider.grant(user, secret);

// When
Expand Down
Loading