Skip to content

Commit

Permalink
feat(lambda): preTokenGeneration trigger called when tokens generated
Browse files Browse the repository at this point in the history
  • Loading branch information
jagregory committed Dec 7, 2021
1 parent 87833e2 commit d04506e
Show file tree
Hide file tree
Showing 30 changed files with 963 additions and 468 deletions.
53 changes: 29 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,29 +174,33 @@ cognito-local how to connect to your local Lambda server:
#### Supported Lambda Triggers

| Trigger | Operation | Support |
| --------------------------- | --------------------------------- | ------- |
| CreateAuthChallenge | \* ||
| CustomEmailSender | \* ||
| CustomMessage | AdminCreateUser ||
| CustomMessage | Authentication ||
| CustomMessage | ForgotPassword ||
| CustomMessage | ResendCode ||
| CustomMessage | SignUp ||
| CustomMessage | UpdateUserAttribute ||
| CustomMessage | VerifyUserAttribute ||
| DefineAuthChallenge | \* ||
| PostAuthentication | PostAuthentication_Authentication ||
| PostConfirmation | ConfirmForgotPassword ||
| PostConfirmation | ConfirmSignUp ||
| PreAuthentication | \* ||
| PreSignUp | PreSignUp_AdminCreateUser ||
| PreSignUp | PreSignUp_ExternalProvider ||
| PreSignUp | PreSignUp_SignUp ||
| PreTokenGeneration | \* ||
| UserMigration | Authentication ||
| UserMigration | ForgotPassword ||
| VerifyAuthChallengeResponse | \* ||
| Trigger | Operation | Support |
| --------------------------- | ------------------------------------ | ------- |
| CreateAuthChallenge | \* ||
| CustomEmailSender | \* ||
| CustomMessage | AdminCreateUser ||
| CustomMessage | Authentication ||
| CustomMessage | ForgotPassword ||
| CustomMessage | ResendCode ||
| CustomMessage | SignUp ||
| CustomMessage | UpdateUserAttribute ||
| CustomMessage | VerifyUserAttribute ||
| DefineAuthChallenge | \* ||
| PostAuthentication | PostAuthentication_Authentication ||
| PostConfirmation | ConfirmForgotPassword ||
| PostConfirmation | ConfirmSignUp ||
| PreAuthentication | \* ||
| PreSignUp | PreSignUp_AdminCreateUser ||
| PreSignUp | PreSignUp_ExternalProvider ||
| PreSignUp | PreSignUp_SignUp ||
| PreTokenGeneration | TokenGeneration_AuthenticateDevice ||
| PreTokenGeneration | TokenGeneration_Authentication ||
| PreTokenGeneration | TokenGeneration_HostedAuth ||
| PreTokenGeneration | TokenGeneration_NewPasswordChallenge ||
| PreTokenGeneration | TokenGeneration_RefreshTokens ||
| UserMigration | Authentication ||
| UserMigration | ForgotPassword ||
| VerifyAuthChallengeResponse | \* ||

#### Known limitations

Expand Down Expand Up @@ -291,7 +295,7 @@ Before starting Cognito Local, create a config file if one doesn't already exist
You can edit that `.cognito/config.json` and add any of the following settings:

| Setting | Type | Default | Description |
| ------------------------------------------ | ---------- | ----------------------- | ----------------------------------------------------------- |
|--------------------------------------------| ---------- | ----------------------- |-------------------------------------------------------------|
| `LambdaClient` | `object` | | Any setting you would pass to the AWS.Lambda Node.js client |
| `LambdaClient.credentials.accessKeyId` | `string` | `local` | |
| `LambdaClient.credentials.secretAccessKey` | `string` | `local` | |
Expand All @@ -303,6 +307,7 @@ You can edit that `.cognito/config.json` and add any of the following settings:
| `TriggerFunctions.PostAuthentication` | `string` | | PostAuthentication local lambda function name |
| `TriggerFunctions.PostConfirmation` | `string` | | PostConfirmation local lambda function name |
| `TriggerFunctions.PreSignUp` | `string` | | PostConfirmation local lambda function name |
| `TriggerFunctions.PreTokenGeneration` | `string` | | PreTokenGeneration local lambda function name |
| `TriggerFunctions.UserMigration` | `string` | | PreSignUp local lambda function name |
| `UserPoolDefaults` | `object` | | Default behaviour to use for the User Pool |
| `UserPoolDefaults.MfaConfiguration` | `string` | | MFA type |
Expand Down
10 changes: 8 additions & 2 deletions integration-tests/aws-sdk/adminInitiateAuth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ describe(
.adminCreateUser({
DesiredDeliveryMediums: ["EMAIL"],
TemporaryPassword: "def",
UserAttributes: [{ Name: "email", Value: "[email protected]" }],
UserAttributes: [
{ Name: "email", Value: "[email protected]" },
{ Name: "email_verified", Value: "true" },
],
Username: "abc",
UserPoolId: "test",
})
Expand Down Expand Up @@ -128,7 +131,10 @@ describe(
.adminCreateUser({
DesiredDeliveryMediums: ["EMAIL"],
TemporaryPassword: "def",
UserAttributes: [{ Name: "email", Value: "[email protected]" }],
UserAttributes: [
{ Name: "email", Value: "[email protected]" },
{ Name: "email_verified", Value: "true" },
],
Username: "abc",
UserPoolId: "test",
})
Expand Down
6 changes: 6 additions & 0 deletions integration-tests/aws-sdk/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { CognitoServiceFactoryImpl } from "../../src/services/cognitoService";
import { NoOpCache } from "../../src/services/dataStore/cache";
import { StormDBDataStoreFactory } from "../../src/services/dataStore/stormDb";
import { otp } from "../../src/services/otp";
import { JwtTokenGenerator } from "../../src/services/tokenGenerator";
import { UserPoolServiceFactoryImpl } from "../../src/services/userPoolService";
import { Router } from "../../src/targets/router";

Expand Down Expand Up @@ -64,6 +65,11 @@ export const withCognitoSdk =
messages: new MessagesService(triggers),
otp,
triggers,
tokenGenerator: new JwtTokenGenerator(
clock,
triggers,
DefaultConfig.TokenConfig
),
});
const server = createServer(router, ctx.logger);
httpServer = await server.start({
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
"prettier": "^2.5.0",
"semantic-release": "^17.4.4",
"supertest": "^4.0.2",
"ts-node": "^10.1.0",
"typescript": "^3.8.3"
"ts-node": "^10.4.0",
"typescript": "^4.5.2"
},
"dependencies": {
"aws-sdk": "^2.953.0",
Expand Down
5 changes: 5 additions & 0 deletions src/__tests__/mockTokenGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { TokenGenerator } from "../services/tokenGenerator";

export const newMockTokenGenerator = (): jest.Mocked<TokenGenerator> => ({
generate: jest.fn(),
});
1 change: 1 addition & 0 deletions src/__tests__/mockTriggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export const newMockTriggers = (): jest.Mocked<Triggers> => ({
postAuthentication: jest.fn(),
postConfirmation: jest.fn(),
preSignUp: jest.fn(),
preTokenGeneration: jest.fn(),
userMigration: jest.fn(),
});
2 changes: 1 addition & 1 deletion src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Context } from "../services/context";
import { DataStoreFactory } from "../services/dataStore/factory";
import { FunctionConfig } from "../services/lambda";
import { UserPool } from "../services/userPoolService";
import { TokenConfig } from "../services/tokens";
import { TokenConfig } from "../services/tokenGenerator";
import mergeWith from "lodash.mergewith";

export type UserPoolDefaults = Omit<
Expand Down
6 changes: 6 additions & 0 deletions src/server/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { StormDBDataStoreFactory } from "../services/dataStore/stormDb";
import { ConsoleMessageSender } from "../services/messageDelivery/consoleMessageSender";
import { MessageDeliveryService } from "../services/messageDelivery/messageDelivery";
import { otp } from "../services/otp";
import { JwtTokenGenerator } from "../services/tokenGenerator";
import { UserPoolServiceFactoryImpl } from "../services/userPoolService";
import { Router } from "../targets/router";
import { loadConfig } from "./config";
Expand Down Expand Up @@ -68,6 +69,11 @@ export const createDefaultServer = async (
messageDelivery: new MessageDeliveryService(new ConsoleMessageSender()),
messages: new MessagesService(triggers),
otp,
tokenGenerator: new JwtTokenGenerator(
clock,
triggers,
config.TokenConfig
),
triggers,
}),
logger,
Expand Down
2 changes: 2 additions & 0 deletions src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Config } from "../server/config";
import { Clock } from "./clock";
import { Messages } from "./messages";
import { TokenGenerator } from "./tokenGenerator";
import { Triggers } from "./triggers";
import { MessageDelivery } from "./messageDelivery/messageDelivery";
import { CognitoService } from "./cognitoService";
Expand All @@ -20,5 +21,6 @@ export interface Services {
messageDelivery: MessageDelivery;
messages: Messages;
otp: () => string;
tokenGenerator: TokenGenerator;
triggers: Triggers;
}
61 changes: 61 additions & 0 deletions src/services/lambda.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,67 @@ describe("Lambda function invoker", () => {
});
});

describe.each`
trigger | source
${"TokenGeneration"} | ${"TokenGeneration_AuthenticateDevice"}
${"TokenGeneration"} | ${"TokenGeneration_Authentication"}
${"TokenGeneration"} | ${"TokenGeneration_HostedAuth"}
${"TokenGeneration"} | ${"TokenGeneration_NewPasswordChallenge"}
${"TokenGeneration"} | ${"TokenGeneration_RefreshTokens"}
`("$source", ({ trigger, source }) => {
it("invokes the lambda", async () => {
const response = Promise.resolve({
StatusCode: 200,
Payload: '{ "some": "json" }',
});
mockLambdaClient.invoke.mockReturnValue({
promise: () => response,
} as any);
const lambda = new LambdaService(
{
[trigger]: "MyLambdaName",
},
mockLambdaClient
);

await lambda.invoke(TestContext, trigger, {
clientId: "clientId",
triggerSource: source,
username: "username",
userPoolId: "userPoolId",
userAttributes: {
user: "attributes",
},
clientMetadata: {
client: "metadata",
},
});

expect(mockLambdaClient.invoke).toHaveBeenCalledWith({
FunctionName: "MyLambdaName",
InvocationType: "RequestResponse",
Payload: expect.jsonMatching({
version: "0",
callerContext: { awsSdkVersion: version, clientId: "clientId" },
region: "local",
userPoolId: "userPoolId",
triggerSource: source,
request: {
userAttributes: {
user: "attributes",
},
clientMetadata: {
client: "metadata",
},
groupConfiguration: {},
},
response: { claimsOverrideDetails: {} },
userName: "username",
}),
});
});
});

describe.each([
"CustomMessage_SignUp",
"CustomMessage_AdminCreateUser",
Expand Down
Loading

0 comments on commit d04506e

Please sign in to comment.