Skip to content

Commit

Permalink
fix(lambda): lambda triggers called with clientMetadata/validationData
Browse files Browse the repository at this point in the history
All existing lambda invocations are now called with ClientMetadata and
ValidationData where appropriate.
  • Loading branch information
jagregory committed Nov 29, 2021
1 parent ccecf73 commit 2399c3e
Show file tree
Hide file tree
Showing 30 changed files with 926 additions and 417 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lib"
],
"scripts": {
"build": "rm -rf lib && tsc --emitDeclarationOnly --project tsconfig.build.json && esbuild $(find src -name '*.ts') --outdir=lib --platform=node --target=node14 --format=cjs && cp -r src/keys lib/keys",
"build": "rm -rf lib && tsc --emitDeclarationOnly --project tsconfig.build.json && esbuild $(find src -name '*.ts' ! -name '*.test.ts' ! -path '*/__tests__/*') --outdir=lib --platform=node --target=node14 --format=cjs && cp -r src/keys lib/keys",
"integration-test": "jest --config integration-tests/jest.config.js",
"integration-test:watch": "jest --config integration-tests/jest.config.js --watch",
"lint": "eslint src/**/*.ts && tsc --noEmit",
Expand Down Expand Up @@ -44,7 +44,7 @@
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"husky": "^4.2.5",
"jest": "^27.0.6",
"jest": "^27.3.1",
"jest-date-mock": "^1.0.8",
"lint-staged": "^10.1.3",
"markdown-toc": "^1.2.0",
Expand Down Expand Up @@ -83,7 +83,7 @@
"lint-staged": {
"*.ts": [
"eslint --fix",
"tsc --esModuleInterop --resolveJsonModule --noEmit",
"tsc --esModuleInterop --resolveJsonModule --noEmit ./setupTests.ts",
"prettier --write"
],
"README.md": "markdown-toc -i --bullets=-"
Expand Down
30 changes: 30 additions & 0 deletions setupTests.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
expect.extend({
jsonMatching(actual: any, expected: any) {
const pass = this.equals(JSON.parse(actual), expected);

expected.toString = function (this: any) {
return JSON.stringify(this);
}.bind(expected);

return {
pass,
message: () =>
`expected ${actual} to equal ${expected} when parsed as JSON`,
};
},
});

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace jest {
interface Expect {
jsonMatching(expected: any): any;
}
}
}

// "Payload": {"version":0,"callerContext":{"awsSdkVersion":"2.953.0","clientId":"clientId"},"region":"local","userPoolId":"userPoolId","triggerSource":"UserMigration_Authentication","request":{"userAttributes":{},"validationData":{},"password":"password"},"response":{},"userName":"username"}
// "Payload": {"version":0,"callerContext":{"awsSdkVersion":"2.953.0","clientId":"clientId"},"region":"local","userPoolId":"userPoolId","triggerSource":"UserMigration_Authentication","request":{"userAttributes":{},"validationData":{},"password":"password"},"response":{},"userName":"username"}

export {};

afterEach(() => {
jest.resetAllMocks();
});
53 changes: 44 additions & 9 deletions src/services/lambda.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ describe("Lambda function invoker", () => {
await expect(
lambda.invoke("UserMigration", {
clientId: "clientId",
clientMetadata: undefined,
password: "password",
triggerSource: "UserMigration_Authentication",
userAttributes: {},
username: "username",
userPoolId: "userPoolId",
userAttributes: {},
validationData: undefined,
})
).rejects.toEqual(new Error("UserMigration trigger not configured"));
});
Expand All @@ -67,11 +69,13 @@ describe("Lambda function invoker", () => {

const result = await lambda.invoke("UserMigration", {
clientId: "clientId",
clientMetadata: undefined,
password: "password",
triggerSource: "UserMigration_Authentication",
userAttributes: {},
username: "username",
userPoolId: "userPoolId",
userAttributes: {},
validationData: undefined,
});

expect(result).toEqual("value");
Expand All @@ -95,11 +99,13 @@ describe("Lambda function invoker", () => {

const result = await lambda.invoke("UserMigration", {
clientId: "clientId",
clientMetadata: undefined,
password: "password",
triggerSource: "UserMigration_Authentication",
userAttributes: {},
username: "username",
userPoolId: "userPoolId",
userAttributes: {},
validationData: undefined,
});

expect(result).toEqual("value");
Expand All @@ -125,26 +131,37 @@ describe("Lambda function invoker", () => {

await lambda.invoke("UserMigration", {
clientId: "clientId",
clientMetadata: {
client: "metadata",
},
password: "password",
triggerSource: "UserMigration_Authentication",
username: "username",
userPoolId: "userPoolId",
userAttributes: {},
validationData: {
validation: "data",
},
});

expect(mockLambdaClient.invoke).toHaveBeenCalledWith({
FunctionName: "MyLambdaName",
InvocationType: "RequestResponse",
Payload: JSON.stringify({
Payload: expect.jsonMatching({
version: 0,
callerContext: { awsSdkVersion: version, clientId: "clientId" },
region: "local",
userPoolId: "userPoolId",
triggerSource: "UserMigration_Authentication",
request: {
clientMetadata: {
client: "metadata",
},
userAttributes: {},
password: "password",
validationData: {},
validationData: {
validation: "data",
},
},
response: {},
userName: "username",
Expand Down Expand Up @@ -180,20 +197,30 @@ describe("Lambda function invoker", () => {
triggerSource: source,
username: "username",
userPoolId: "userPoolId",
userAttributes: {},
userAttributes: {
user: "attributes",
},
clientMetadata: {
client: "metadata",
},
});

expect(mockLambdaClient.invoke).toHaveBeenCalledWith({
FunctionName: "MyLambdaName",
InvocationType: "RequestResponse",
Payload: JSON.stringify({
Payload: expect.jsonMatching({
version: 0,
callerContext: { awsSdkVersion: version, clientId: "clientId" },
region: "local",
userPoolId: "userPoolId",
triggerSource: source,
request: {
userAttributes: {},
userAttributes: {
user: "attributes",
},
clientMetadata: {
client: "metadata",
},
},
response: {},
userName: "username",
Expand Down Expand Up @@ -229,26 +256,34 @@ describe("Lambda function invoker", () => {

await lambda.invoke("CustomMessage", {
clientId: "clientId",
clientMetadata: {
client: "metadata",
},
codeParameter: "{####}",
triggerSource: source,
userAttributes: {},
username: "username",
usernameParameter: "{username}",
userPoolId: "userPoolId",
});

expect(mockLambdaClient.invoke).toHaveBeenCalledWith({
FunctionName: "MyLambdaName",
InvocationType: "RequestResponse",
Payload: JSON.stringify({
Payload: expect.jsonMatching({
version: 0,
callerContext: { awsSdkVersion: version, clientId: "clientId" },
region: "local",
userPoolId: "userPoolId",
triggerSource: source,
userName: "username",
request: {
userAttributes: {},
usernameParameter: "{username}",
codeParameter: "{####}",
clientMetadata: {
client: "metadata",
},
},
response: {},
}),
Expand Down
88 changes: 47 additions & 41 deletions src/services/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,44 @@ import { UnexpectedLambdaExceptionError } from "../errors";
import { version as awsSdkVersion } from "aws-sdk/package.json";
import { Logger } from "../log";

interface CustomMessageEvent {
userPoolId: string;
interface EventCommonParameters {
clientId: string;
codeParameter: string;
usernameParameter: string;
userAttributes: Record<string, string>;
username: string;
userPoolId: string;
}

interface CustomMessageEvent extends EventCommonParameters {
clientMetadata: Record<string, string> | undefined;
codeParameter: string;
triggerSource:
| "CustomMessage_SignUp"
| "CustomMessage_AdminCreateUser"
| "CustomMessage_ResendCode"
| "CustomMessage_Authentication"
| "CustomMessage_ForgotPassword"
| "CustomMessage_ResendCode"
| "CustomMessage_SignUp"
| "CustomMessage_UpdateUserAttribute"
| "CustomMessage_VerifyUserAttribute"
| "CustomMessage_Authentication";
| "CustomMessage_VerifyUserAttribute";
usernameParameter: string;
}

interface UserMigrationEvent {
userPoolId: string;
clientId: string;
username: string;
interface UserMigrationEvent extends EventCommonParameters {
clientMetadata: Record<string, string> | undefined;
password: string;
userAttributes: Record<string, string>;
triggerSource: "UserMigration_Authentication";
validationData: Record<string, string> | undefined;
}

interface PostAuthenticationEvent {
userPoolId: string;
clientId: string;
username: string;
userAttributes: Record<string, string>;
interface PostAuthenticationEvent extends EventCommonParameters {
clientMetadata: Record<string, string> | undefined;
triggerSource: "PostAuthentication_Authentication";
}

interface PostConfirmationEvent {
userPoolId: string;
clientId: string;
username: string;
userAttributes: Record<string, string>;
interface PostConfirmationEvent extends EventCommonParameters {
triggerSource:
| "PostConfirmation_ConfirmSignUp"
| "PostConfirmation_ConfirmForgotPassword";
clientMetadata: Record<string, string> | undefined;
}

export type CognitoUserPoolResponse = CognitoUserPoolEvent["response"];
Expand Down Expand Up @@ -118,30 +115,39 @@ export class LambdaService implements Lambda {
region: "local", // TODO: pull from above,
userPoolId: event.userPoolId,
triggerSource: event.triggerSource,
userName: event.username,
request: {
userAttributes: event.userAttributes,
},
response: {},
};

if (event.triggerSource === "UserMigration_Authentication") {
lambdaEvent.request.password = event.password;
lambdaEvent.request.validationData = {};
} else if (
event.triggerSource === "CustomMessage_SignUp" ||
event.triggerSource === "CustomMessage_AdminCreateUser" ||
event.triggerSource === "CustomMessage_ResendCode" ||
event.triggerSource === "CustomMessage_ForgotPassword" ||
event.triggerSource === "CustomMessage_UpdateUserAttribute" ||
event.triggerSource === "CustomMessage_VerifyUserAttribute" ||
event.triggerSource === "CustomMessage_Authentication"
) {
lambdaEvent.request.usernameParameter = event.usernameParameter;
lambdaEvent.request.codeParameter = event.codeParameter;
}

if ("username" in event) {
lambdaEvent.userName = event.username;
switch (event.triggerSource) {
case "PostAuthentication_Authentication":
case "PostConfirmation_ConfirmForgotPassword":
case "PostConfirmation_ConfirmSignUp": {
lambdaEvent.request.clientMetadata = event.clientMetadata;
break;
}
case "UserMigration_Authentication": {
lambdaEvent.request.clientMetadata = event.clientMetadata;
lambdaEvent.request.password = event.password;
lambdaEvent.request.validationData = event.validationData;

break;
}
case "CustomMessage_SignUp":
case "CustomMessage_AdminCreateUser":
case "CustomMessage_ResendCode":
case "CustomMessage_ForgotPassword":
case "CustomMessage_UpdateUserAttribute":
case "CustomMessage_VerifyUserAttribute":
case "CustomMessage_Authentication": {
lambdaEvent.request.clientMetadata = event.clientMetadata;
lambdaEvent.request.codeParameter = event.codeParameter;
lambdaEvent.request.usernameParameter = event.usernameParameter;
break;
}
}

this.logger.debug(
Expand Down
Loading

0 comments on commit 2399c3e

Please sign in to comment.