From 6d7dcee01d3d9e79c5793040dff16efc513ad17b Mon Sep 17 00:00:00 2001 From: Jason Fry Date: Tue, 4 Jun 2024 09:32:29 +0100 Subject: [PATCH 1/6] More Cognito events - PostConfirmation - PostAuthentication - CustomMessage --- Sources/AWSLambdaEvents/Cognito.swift | 177 ++++++++++++++- Tests/AWSLambdaEventsTests/CognitoTests.swift | 208 +++++++++++++++++- 2 files changed, 375 insertions(+), 10 deletions(-) diff --git a/Sources/AWSLambdaEvents/Cognito.swift b/Sources/AWSLambdaEvents/Cognito.swift index 44916a5..cc076b2 100644 --- a/Sources/AWSLambdaEvents/Cognito.swift +++ b/Sources/AWSLambdaEvents/Cognito.swift @@ -23,9 +23,36 @@ public enum CognitoEvent: Equatable, Sendable { let clientId: String } + public enum TriggerSource: String, Codable, Sendable { + case preSignUp_SignUp = "PreSignUp_SignUp" + case preSignUp_ExternalProvider = "PreSignUp_ExternalProvider" + case postConfirmation_ConfirmSignUp = "PostConfirmation_ConfirmSignUp" + case preAuthentication_Authentication = "PreAuthentication_Authentication" + case postAuthentication_Authentication = "PostAuthentication_Authentication" + case customMessage_SignUp = "CustomMessage_SignUp" + case customMessage_AdminCreateUser = "CustomMessage_AdminCreateUser" + case customMessage_ResendCode = "CustomMessage_ResendCode" + case customMessage_ForgotPassword = "CustomMessage_ForgotPassword" + case customMessage_UpdateUserAttribute = "CustomMessage_UpdateUserAttribute" + case customMessage_VerifyUserAttribute = "CustomMessage_VerifyUserAttribute" + case customMessage_Authentication = "CustomMessage_Authentication" + case defineAuthChallenge_Authentication = "DefineAuthChallenge_Authentication" + case createAuthChallenge_Authentication = "CreateAuthChallenge_Authentication" + case verifyAuthChallengeResponse_Authentication = "VerifyAuthChallengeResponse_Authentication" + case preSignUp_AdminCreateUser = "PreSignUp_AdminCreateUser" + case postConfirmation_ConfirmForgotPassword = "PostConfirmation_ConfirmForgotPassword" + case tokenGeneration_HostedAuth = "TokenGeneration_HostedAuth" + case tokenGeneration_Authentication = "TokenGeneration_Authentication" + case tokenGeneration_NewPasswordChallenge = "TokenGeneration_NewPasswordChallenge" + case tokenGeneration_AuthenticateDevice = "TokenGeneration_AuthenticateDevice" + case tokenGeneration_RefreshTokens = "TokenGeneration_RefreshTokens" + case userMigration_Authentication = "UserMigration_Authentication" + case userMigration_ForgotPassword = "UserMigration_ForgotPassword" + } + public struct Parameters: Codable, Equatable, Sendable { let version: String - let triggerSource: String + let triggerSource: TriggerSource let region: AWSRegion let userPoolId: String let userName: String @@ -37,20 +64,82 @@ public enum CognitoEvent: Equatable, Sendable { public struct PreSignUp: Codable, Hashable, Sendable { /// One or more name-value pairs representing user attributes. The attribute names are the keys. public let userAttributes: [String: String] + /// One or more name-value pairs containing the validation data in the request to register a user. /// /// The validation data is set and then passed from the client in the request to register a user. You can pass this data to your Lambda function by using the ClientMetadata parameter in the InitiateAuth and AdminInitiateAuth API actions. public let validationData: [String: String]? + /// One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the pre sign-up trigger. /// /// You can pass this data to your Lambda function by using the ClientMetadata parameter in the following API actions: AdminCreateUser, AdminRespondToAuthChallenge, ForgotPassword, and SignUp. public let clientMetadata: [String: String]? } + case postConfirmation(Parameters, PostConfirmation) + + public struct PostConfirmation: Codable, Equatable, Sendable { + /// One or more key-value pairs representing user attributes. + public let userAttributes: [String: String] + + /// One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the post confirmation trigger. + /// + /// You can pass this data to your Lambda function by using the ClientMetadata parameter in the following API actions: AdminConfirmSignUp, ConfirmForgotPassword, ConfirmSignUp, and SignUp. + public let clientMetadata: [String: String]? + } + + case postAuthentication(Parameters, PostAuthentication) + + public struct PostAuthentication: Codable, Equatable, Sendable { + /// This flag indicates if the user has signed in on a new device. Amazon Cognito only sets this flag if the remembered devices value of the user pool is Always or User Opt-In. + public let newDeviceUsed: Bool + + /// One or more name-value pairs representing user attributes. + public let userAttributes: [String: String] + + /// One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the post authentication trigger. + /// + /// To pass this data to your Lambda function, you can use the ClientMetadata parameter in the AdminRespondToAuthChallenge and RespondToAuthChallenge API actions. + /// Amazon Cognito doesn't include data from the ClientMetadata parameter in AdminInitiateAuth and InitiateAuth API operations in the request that it passes to the post authentication function. + public let clientMetadata: [String: String]? + } + + case customMessage(Parameters, CustomMessage) + + public struct CustomMessage: Codable, Equatable, Sendable { + /// A string for you to use as the placeholder for the verification code in the custom message. + public let codeParameter: String? + + /// The user name. Amazon Cognito includes this parameter in requests that result from admin-created users. + public let usernameParameter: String? + + /// One or more name-value pairs representing user attributes. + public let userAttributes: [String: String] + + /// One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the custom message trigger. + /// + /// The request that invokes a custom message function doesn't include data passed in the ClientMetadata parameter in AdminInitiateAuth and InitiateAuth API operations. To pass this data to your Lambda function, you can use the ClientMetadata parameter in the following API actions: + /// - AdminResetUserPassword + /// - AdminRespondToAuthChallenge + /// - AdminUpdateUserAttributes + /// - ForgotPassword + /// - GetUserAttributeVerificationCode + /// - ResendConfirmationCode + /// - SignUp + /// - UpdateUserAttributes + public let clientMetadata: [String: String]? + } + public var commonParameters: Parameters { switch self { case .preSignUpSignUp(let params, _): return params + case .postConfirmation(let params, _): + return params + case .postAuthentication(let params, _): + return params + case .customMessage(let params, _): + return params } } } @@ -71,7 +160,7 @@ extension CognitoEvent: Codable { let container = try decoder.container(keyedBy: CodingKeys.self) let version = try container.decode(String.self, forKey: .version) - let triggerSource = try container.decode(String.self, forKey: .triggerSource) + let triggerSource = try container.decode(TriggerSource.self, forKey: .triggerSource) let region = try container.decode(AWSRegion.self, forKey: .region) let userPoolId = try container.decode(String.self, forKey: .userPoolId) let userName = try container.decode(String.self, forKey: .userName) @@ -80,12 +169,24 @@ extension CognitoEvent: Codable { let params = CognitoEvent.Parameters(version: version, triggerSource: triggerSource, region: region, userPoolId: userPoolId, userName: userName, callerContext: callerContext) switch triggerSource { - case "PreSignUp_SignUp": + case .preSignUp_SignUp: let value = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request) - self = .preSignUpSignUp(params, value) + + case .postConfirmation_ConfirmSignUp, .postConfirmation_ConfirmForgotPassword: + let value = try container.decode(CognitoEvent.PostConfirmation.self, forKey: .request) + self = .postConfirmation(params, value) + + case .postAuthentication_Authentication: + let value = try container.decode(CognitoEvent.PostAuthentication.self, forKey: .request) + self = .postAuthentication(params, value) + + case .customMessage_SignUp, .customMessage_AdminCreateUser, .customMessage_ResendCode, .customMessage_ForgotPassword, .customMessage_UpdateUserAttribute, .customMessage_VerifyUserAttribute, .customMessage_Authentication: + let value = try container.decode(CognitoEvent.CustomMessage.self, forKey: .request) + self = .customMessage(params, value) + default: - throw CognitoEventError.unimplementedEvent(triggerSource) + throw CognitoEventError.unimplementedEvent(triggerSource.rawValue) } } @@ -104,11 +205,20 @@ extension CognitoEvent: Codable { switch self { case .preSignUpSignUp(_, let value): try container.encode(value, forKey: .response) + case .postConfirmation(_, let value): + try container.encode(value, forKey: .response) + case .postAuthentication(_, let value): + try container.encode(value, forKey: .response) + case .customMessage(_, let value): + try container.encode(value, forKey: .response) } } } public enum CognitoEventResponse: Sendable { + // Used for when there are no parameters expected in the response + public struct EmptyResponse: Codable, Equatable, Sendable {} + case preSignUpSignUp(CognitoEvent.Parameters, CognitoEvent.PreSignUp, PreSignUp) public struct PreSignUp: Codable, Hashable, Sendable { @@ -123,10 +233,33 @@ public enum CognitoEventResponse: Sendable { } } + case postConfirmation(CognitoEvent.Parameters, CognitoEvent.PostConfirmation, EmptyResponse) + + case postAuthentication(CognitoEvent.Parameters, CognitoEvent.PostAuthentication, EmptyResponse) + + case customMessage(CognitoEvent.Parameters, CognitoEvent.CustomMessage, CustomMessage) + + public struct CustomMessage: Codable, Equatable, Sendable { + /// The custom SMS message to be sent to your users. Must include the codeParameter value that you received in the request. + public let smsMessage: String? + + /// The custom email message to send to your users. You can use HTML formatting in the emailMessage parameter. Must include the codeParameter value that you received in the request as the variable {####}. + public let emailMessage: String? + + /// The subject line for the custom message + public let emailSubject: String? + } + public var commonParameters: CognitoEvent.Parameters { switch self { case .preSignUpSignUp(let params, _, _): return params + case .postConfirmation(let params, _, _): + return params + case .postAuthentication(let params, _, _): + return params + case .customMessage(let params, _, _): + return params } } } @@ -147,7 +280,7 @@ extension CognitoEventResponse: Codable { let container = try decoder.container(keyedBy: CodingKeys.self) let version = try container.decode(String.self, forKey: .version) - let triggerSource = try container.decode(String.self, forKey: .triggerSource) + let triggerSource = try container.decode(CognitoEvent.TriggerSource.self, forKey: .triggerSource) let region = try container.decode(AWSRegion.self, forKey: .region) let userPoolId = try container.decode(String.self, forKey: .userPoolId) let userName = try container.decode(String.self, forKey: .userName) @@ -156,13 +289,32 @@ extension CognitoEventResponse: Codable { let params = CognitoEvent.Parameters(version: version, triggerSource: triggerSource, region: region, userPoolId: userPoolId, userName: userName, callerContext: callerContext) switch triggerSource { - case "PreSignUp_SignUp": + case .preSignUp_SignUp: let request = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request) let response = try container.decode(CognitoEventResponse.PreSignUp.self, forKey: .response) self = .preSignUpSignUp(params, request, response) + + case .postConfirmation_ConfirmSignUp, .postConfirmation_ConfirmForgotPassword: + let request = try container.decode(CognitoEvent.PostConfirmation.self, forKey: .request) + let response = try container.decode(CognitoEventResponse.EmptyResponse.self, forKey: .response) + + self = .postConfirmation(params, request, response) + + case .postAuthentication_Authentication: + let request = try container.decode(CognitoEvent.PostAuthentication.self, forKey: .request) + let response = try container.decode(CognitoEventResponse.EmptyResponse.self, forKey: .response) + + self = .postAuthentication(params, request, response) + + case .customMessage_SignUp, .customMessage_AdminCreateUser, .customMessage_ResendCode, .customMessage_ForgotPassword, .customMessage_UpdateUserAttribute, .customMessage_VerifyUserAttribute, .customMessage_Authentication: + let request = try container.decode(CognitoEvent.CustomMessage.self, forKey: .request) + let response = try container.decode(CognitoEventResponse.CustomMessage.self, forKey: .response) + + self = .customMessage(params, request, response) + default: - throw CognitoEventError.unimplementedEvent(triggerSource) + throw CognitoEventError.unimplementedEvent(triggerSource.rawValue) } } @@ -182,6 +334,15 @@ extension CognitoEventResponse: Codable { case .preSignUpSignUp(_, let request, let response): try container.encode(request, forKey: .request) try container.encode(response, forKey: .response) + case .postConfirmation(_, let request, let response): + try container.encode(request, forKey: .request) + try container.encode(response, forKey: .response) + case .postAuthentication(_, let request, let response): + try container.encode(request, forKey: .request) + try container.encode(response, forKey: .response) + case .customMessage(_, let request, let response): + try container.encode(request, forKey: .request) + try container.encode(response, forKey: .response) } } } diff --git a/Tests/AWSLambdaEventsTests/CognitoTests.swift b/Tests/AWSLambdaEventsTests/CognitoTests.swift index deb3ab5..6bfe2ce 100644 --- a/Tests/AWSLambdaEventsTests/CognitoTests.swift +++ b/Tests/AWSLambdaEventsTests/CognitoTests.swift @@ -50,7 +50,7 @@ final class CognitoTests: XCTestCase { return } - XCTAssertEqual(params.triggerSource, "PreSignUp_SignUp") + XCTAssertEqual(params.triggerSource, .preSignUp_SignUp) let signUp = CognitoEvent.PreSignUp(userAttributes: ["string": "string"], validationData: ["string": "string"], @@ -60,7 +60,7 @@ final class CognitoTests: XCTestCase { func testPreSignUpResponse() throws { let params = CognitoEvent.Parameters(version: "1", - triggerSource: "PreSignUp_SignUp", + triggerSource: .preSignUp_SignUp, region: .us_east_1, userPoolId: "abc", userName: "blob", @@ -88,4 +88,208 @@ final class CognitoTests: XCTestCase { XCTAssertEqual(decodedRequest, request) XCTAssertEqual(decodedResponse, signUpResponse) } + + func testPostConfirmationRequest() throws { + let json = """ + { + "version": "1", + "triggerSource": "PostConfirmation_ConfirmSignUp", + "region": "us-east-1", + "userPoolId": "abc", + "userName": "blob", + "callerContext": { + "awsSdkVersion": "1", + "clientId": "abc", + }, + "request": { + "userAttributes": { + "string": "string" + }, + "clientMetadata": { + "string": "string" + } + }, + "response": {} + } + """ + let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) + + guard case .postConfirmation(let params, let request) = event else { + XCTFail() + return + } + + XCTAssertEqual(params.triggerSource, .postConfirmation_ConfirmSignUp) + + let postConfirmation = CognitoEvent.PostConfirmation(userAttributes: ["string": "string"], + clientMetadata: ["string": "string"]) + XCTAssertEqual(request, postConfirmation) + } + + func testPostConfirmationResponse() throws { + let params = CognitoEvent.Parameters(version: "1", + triggerSource: .postConfirmation_ConfirmSignUp, + region: .us_east_1, + userPoolId: "abc", + userName: "blob", + callerContext: .init(awsSdkVersion: "1", clientId: "abc")) + let request = CognitoEvent.PostConfirmation(userAttributes: ["string": "string"], + clientMetadata: ["string": "string"]) + + let postConfirmationResponse = CognitoEventResponse.EmptyResponse() + + let response = CognitoEventResponse.postConfirmation(params, request, postConfirmationResponse) + + let data = try JSONEncoder().encode(response) + + let decodedResponse = try JSONDecoder().decode(CognitoEventResponse.self, from: data) + + guard case .postConfirmation(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { + XCTFail() + return + } + + XCTAssertEqual(decodedParams, params) + XCTAssertEqual(decodedRequest, request) + XCTAssertEqual(decodedResponse, postConfirmationResponse) + } + + func testPostAuthenticationRequest() throws { + let json = """ + { + "version": "1", + "triggerSource": "PostAuthentication_Authentication", + "region": "us-east-1", + "userPoolId": "abc", + "userName": "blob", + "callerContext": { + "awsSdkVersion": "1", + "clientId": "abc", + }, + "request": { + "newDeviceUsed": false, + "userAttributes": { + "string": "string" + }, + "clientMetadata": { + "string": "string" + } + }, + "response": {} + } + """ + let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) + + guard case .postAuthentication(let params, let request) = event else { + XCTFail() + return + } + + XCTAssertEqual(params.triggerSource, .postAuthentication_Authentication) + + let postAuthentication = CognitoEvent.PostAuthentication(newDeviceUsed: false, + userAttributes: ["string": "string"], + clientMetadata: ["string": "string"]) + XCTAssertEqual(request, postAuthentication) + } + + func testPostAuthenticationResponse() throws { + let params = CognitoEvent.Parameters(version: "1", + triggerSource: .postAuthentication_Authentication, + region: .us_east_1, + userPoolId: "abc", + userName: "blob", + callerContext: .init(awsSdkVersion: "1", clientId: "abc")) + let request = CognitoEvent.PostAuthentication(newDeviceUsed: false, + userAttributes: ["string": "string"], + clientMetadata: ["string": "string"]) + + let postAuthenticationResponse = CognitoEventResponse.EmptyResponse() + + let response = CognitoEventResponse.postAuthentication(params, request, postAuthenticationResponse) + + let data = try JSONEncoder().encode(response) + + let decodedResponse = try JSONDecoder().decode(CognitoEventResponse.self, from: data) + + guard case .postAuthentication(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { + XCTFail() + return + } + + XCTAssertEqual(decodedParams, params) + XCTAssertEqual(decodedRequest, request) + XCTAssertEqual(decodedResponse, postAuthenticationResponse) + } + + func testCustomMessageRequest() throws { + let json = """ + { + "version": "1", + "triggerSource": "CustomMessage_AdminCreateUser", + "region": "us-east-1", + "userPoolId": "abc", + "userName": "blob", + "callerContext": { + "awsSdkVersion": "1", + "clientId": "abc", + }, + "request": { + "codeParameter": "######", + "usernameParameter": "user123", + "userAttributes": { + "string": "string" + }, + "clientMetadata": { + "string": "string" + } + }, + "response": {} + } + """ + let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) + + guard case .customMessage(let params, let request) = event else { + XCTFail() + return + } + + XCTAssertEqual(params.triggerSource, .customMessage_AdminCreateUser) + + let postAuthentication = CognitoEvent.CustomMessage(codeParameter: "######", + usernameParameter: "user123", + userAttributes: ["string": "string"], + clientMetadata: ["string": "string"]) + XCTAssertEqual(request, postAuthentication) + } + + func testCustomMessageResponse() throws { + let params = CognitoEvent.Parameters(version: "1", + triggerSource: .customMessage_AdminCreateUser, + region: .us_east_1, + userPoolId: "abc", + userName: "blob", + callerContext: .init(awsSdkVersion: "1", clientId: "abc")) + let request = CognitoEvent.CustomMessage(codeParameter: "######", + usernameParameter: "user123", + userAttributes: ["string": "string"], + clientMetadata: ["string": "string"]) + + let customMessageResponse = CognitoEventResponse.CustomMessage(smsMessage: nil, emailMessage: "Your code is ######", emailSubject: "Sign up code") + + let response = CognitoEventResponse.customMessage(params, request, customMessageResponse) + + let data = try JSONEncoder().encode(response) + + let decodedResponse = try JSONDecoder().decode(CognitoEventResponse.self, from: data) + + guard case .customMessage(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { + XCTFail() + return + } + + XCTAssertEqual(decodedParams, params) + XCTAssertEqual(decodedRequest, request) + XCTAssertEqual(decodedResponse, customMessageResponse) + } } From d6bfc2c9cbc4a85bc98f12dbeb6384c953bdd2da Mon Sep 17 00:00:00 2001 From: Jason Fry Date: Tue, 4 Jun 2024 10:49:12 +0100 Subject: [PATCH 2/6] public constructors for cognito responses --- Sources/AWSLambdaEvents/Cognito.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sources/AWSLambdaEvents/Cognito.swift b/Sources/AWSLambdaEvents/Cognito.swift index cc076b2..618e792 100644 --- a/Sources/AWSLambdaEvents/Cognito.swift +++ b/Sources/AWSLambdaEvents/Cognito.swift @@ -217,7 +217,9 @@ extension CognitoEvent: Codable { public enum CognitoEventResponse: Sendable { // Used for when there are no parameters expected in the response - public struct EmptyResponse: Codable, Equatable, Sendable {} + public struct EmptyResponse: Codable, Equatable, Sendable { + public init() {} + } case preSignUpSignUp(CognitoEvent.Parameters, CognitoEvent.PreSignUp, PreSignUp) @@ -240,6 +242,12 @@ public enum CognitoEventResponse: Sendable { case customMessage(CognitoEvent.Parameters, CognitoEvent.CustomMessage, CustomMessage) public struct CustomMessage: Codable, Equatable, Sendable { + public init(smsMessage: String? = nil, emailMessage: String? = nil, emailSubject: String? = nil) { + self.smsMessage = smsMessage + self.emailMessage = emailMessage + self.emailSubject = emailSubject + } + /// The custom SMS message to be sent to your users. Must include the codeParameter value that you received in the request. public let smsMessage: String? From aad1db7fc1577778a9aec4d777859fac0243aa34 Mon Sep 17 00:00:00 2001 From: Jason Fry Date: Thu, 6 Jun 2024 11:50:59 +0100 Subject: [PATCH 3/6] Cognito common params are now public so they can actually be read --- Sources/AWSLambdaEvents/Cognito.swift | 32 ++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/Sources/AWSLambdaEvents/Cognito.swift b/Sources/AWSLambdaEvents/Cognito.swift index 618e792..95587ca 100644 --- a/Sources/AWSLambdaEvents/Cognito.swift +++ b/Sources/AWSLambdaEvents/Cognito.swift @@ -19,8 +19,11 @@ enum CognitoEventError: Error, Sendable { /// https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html public enum CognitoEvent: Equatable, Sendable { public struct CallerContext: Codable, Hashable, Sendable { - let awsSdkVersion: String - let clientId: String + /// The version of the AWS SDK that generated the request. + public let awsSdkVersion: String + + /// The ID of the user pool app client. + public let clientId: String } public enum TriggerSource: String, Codable, Sendable { @@ -51,12 +54,25 @@ public enum CognitoEvent: Equatable, Sendable { } public struct Parameters: Codable, Equatable, Sendable { - let version: String - let triggerSource: TriggerSource - let region: AWSRegion - let userPoolId: String - let userName: String - let callerContext: CallerContext + /// The version number of your Lambda function. + public let version: String + + /// The name of the event that triggered the Lambda function. + /// + /// For a description of each triggerSource see Connecting Lambda triggers to user pool functional operations. https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-identity-pools-working-with-aws-lambda-trigger-sources + public let triggerSource: TriggerSource + + /// The AWS Region as an AWSRegion instance. + public let region: AWSRegion + + /// The ID of the user pool. + public let userPoolId: String + + /// The current user's username. + public let userName: String + + /// Metadata about the request and the code environment. + public let callerContext: CallerContext } case preSignUpSignUp(Parameters, PreSignUp) From 918ffa32a83aa272fa73f4222ff540a8f4d81a08 Mon Sep 17 00:00:00 2001 From: Jason Fry Date: Thu, 6 Jun 2024 13:46:17 +0100 Subject: [PATCH 4/6] Decode all PreSignUp triggered messags --- Sources/AWSLambdaEvents/Cognito.swift | 22 ++++++++++++------- Tests/AWSLambdaEventsTests/CognitoTests.swift | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Sources/AWSLambdaEvents/Cognito.swift b/Sources/AWSLambdaEvents/Cognito.swift index 95587ca..93c8846 100644 --- a/Sources/AWSLambdaEvents/Cognito.swift +++ b/Sources/AWSLambdaEvents/Cognito.swift @@ -28,10 +28,15 @@ public enum CognitoEvent: Equatable, Sendable { public enum TriggerSource: String, Codable, Sendable { case preSignUp_SignUp = "PreSignUp_SignUp" + case preSignUp_AdminCreateUser = "PreSignUp_AdminCreateUser" case preSignUp_ExternalProvider = "PreSignUp_ExternalProvider" + case postConfirmation_ConfirmSignUp = "PostConfirmation_ConfirmSignUp" + case postConfirmation_ConfirmForgotPassword = "PostConfirmation_ConfirmForgotPassword" + case preAuthentication_Authentication = "PreAuthentication_Authentication" case postAuthentication_Authentication = "PostAuthentication_Authentication" + case customMessage_SignUp = "CustomMessage_SignUp" case customMessage_AdminCreateUser = "CustomMessage_AdminCreateUser" case customMessage_ResendCode = "CustomMessage_ResendCode" @@ -39,16 +44,17 @@ public enum CognitoEvent: Equatable, Sendable { case customMessage_UpdateUserAttribute = "CustomMessage_UpdateUserAttribute" case customMessage_VerifyUserAttribute = "CustomMessage_VerifyUserAttribute" case customMessage_Authentication = "CustomMessage_Authentication" + case defineAuthChallenge_Authentication = "DefineAuthChallenge_Authentication" case createAuthChallenge_Authentication = "CreateAuthChallenge_Authentication" case verifyAuthChallengeResponse_Authentication = "VerifyAuthChallengeResponse_Authentication" - case preSignUp_AdminCreateUser = "PreSignUp_AdminCreateUser" - case postConfirmation_ConfirmForgotPassword = "PostConfirmation_ConfirmForgotPassword" + case tokenGeneration_HostedAuth = "TokenGeneration_HostedAuth" case tokenGeneration_Authentication = "TokenGeneration_Authentication" case tokenGeneration_NewPasswordChallenge = "TokenGeneration_NewPasswordChallenge" case tokenGeneration_AuthenticateDevice = "TokenGeneration_AuthenticateDevice" case tokenGeneration_RefreshTokens = "TokenGeneration_RefreshTokens" + case userMigration_Authentication = "UserMigration_Authentication" case userMigration_ForgotPassword = "UserMigration_ForgotPassword" } @@ -185,7 +191,7 @@ extension CognitoEvent: Codable { let params = CognitoEvent.Parameters(version: version, triggerSource: triggerSource, region: region, userPoolId: userPoolId, userName: userName, callerContext: callerContext) switch triggerSource { - case .preSignUp_SignUp: + case .preSignUp_SignUp, .preSignUp_ExternalProvider, .preSignUp_AdminCreateUser: let value = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request) self = .preSignUpSignUp(params, value) @@ -237,7 +243,7 @@ public enum CognitoEventResponse: Sendable { public init() {} } - case preSignUpSignUp(CognitoEvent.Parameters, CognitoEvent.PreSignUp, PreSignUp) + case preSignUp(CognitoEvent.Parameters, CognitoEvent.PreSignUp, PreSignUp) public struct PreSignUp: Codable, Hashable, Sendable { public let autoConfirmUser: Bool @@ -276,7 +282,7 @@ public enum CognitoEventResponse: Sendable { public var commonParameters: CognitoEvent.Parameters { switch self { - case .preSignUpSignUp(let params, _, _): + case .preSignUp(let params, _, _): return params case .postConfirmation(let params, _, _): return params @@ -313,11 +319,11 @@ extension CognitoEventResponse: Codable { let params = CognitoEvent.Parameters(version: version, triggerSource: triggerSource, region: region, userPoolId: userPoolId, userName: userName, callerContext: callerContext) switch triggerSource { - case .preSignUp_SignUp: + case .preSignUp_SignUp, .preSignUp_AdminCreateUser, .preSignUp_ExternalProvider: let request = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request) let response = try container.decode(CognitoEventResponse.PreSignUp.self, forKey: .response) - self = .preSignUpSignUp(params, request, response) + self = .preSignUp(params, request, response) case .postConfirmation_ConfirmSignUp, .postConfirmation_ConfirmForgotPassword: let request = try container.decode(CognitoEvent.PostConfirmation.self, forKey: .request) @@ -355,7 +361,7 @@ extension CognitoEventResponse: Codable { try container.encode(params.callerContext, forKey: .callerContext) switch self { - case .preSignUpSignUp(_, let request, let response): + case .preSignUp(_, let request, let response): try container.encode(request, forKey: .request) try container.encode(response, forKey: .response) case .postConfirmation(_, let request, let response): diff --git a/Tests/AWSLambdaEventsTests/CognitoTests.swift b/Tests/AWSLambdaEventsTests/CognitoTests.swift index 6bfe2ce..8cf4696 100644 --- a/Tests/AWSLambdaEventsTests/CognitoTests.swift +++ b/Tests/AWSLambdaEventsTests/CognitoTests.swift @@ -73,13 +73,13 @@ final class CognitoTests: XCTestCase { autoVerifyPhone: true, autoVerifyEmail: true) - let response = CognitoEventResponse.preSignUpSignUp(params, request, signUpResponse) + let response = CognitoEventResponse.preSignUp(params, request, signUpResponse) let data = try JSONEncoder().encode(response) let decodedResponse = try JSONDecoder().decode(CognitoEventResponse.self, from: data) - guard case .preSignUpSignUp(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { + guard case .preSignUp(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { XCTFail() return } From 34ff407753069fabb308c4656829889c48081e15 Mon Sep 17 00:00:00 2001 From: Jason Fry Date: Thu, 6 Jun 2024 13:50:54 +0100 Subject: [PATCH 5/6] Finish PreSignUpSignUp renaming --- Sources/AWSLambdaEvents/Cognito.swift | 8 ++++---- Tests/AWSLambdaEventsTests/CognitoTests.swift | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/AWSLambdaEvents/Cognito.swift b/Sources/AWSLambdaEvents/Cognito.swift index 93c8846..b179766 100644 --- a/Sources/AWSLambdaEvents/Cognito.swift +++ b/Sources/AWSLambdaEvents/Cognito.swift @@ -81,7 +81,7 @@ public enum CognitoEvent: Equatable, Sendable { public let callerContext: CallerContext } - case preSignUpSignUp(Parameters, PreSignUp) + case preSignUp(Parameters, PreSignUp) public struct PreSignUp: Codable, Hashable, Sendable { /// One or more name-value pairs representing user attributes. The attribute names are the keys. @@ -154,7 +154,7 @@ public enum CognitoEvent: Equatable, Sendable { public var commonParameters: Parameters { switch self { - case .preSignUpSignUp(let params, _): + case .preSignUp(let params, _): return params case .postConfirmation(let params, _): return params @@ -193,7 +193,7 @@ extension CognitoEvent: Codable { switch triggerSource { case .preSignUp_SignUp, .preSignUp_ExternalProvider, .preSignUp_AdminCreateUser: let value = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request) - self = .preSignUpSignUp(params, value) + self = .preSignUp(params, value) case .postConfirmation_ConfirmSignUp, .postConfirmation_ConfirmForgotPassword: let value = try container.decode(CognitoEvent.PostConfirmation.self, forKey: .request) @@ -225,7 +225,7 @@ extension CognitoEvent: Codable { try container.encode(params.callerContext, forKey: .callerContext) switch self { - case .preSignUpSignUp(_, let value): + case .preSignUp(_, let value): try container.encode(value, forKey: .response) case .postConfirmation(_, let value): try container.encode(value, forKey: .response) diff --git a/Tests/AWSLambdaEventsTests/CognitoTests.swift b/Tests/AWSLambdaEventsTests/CognitoTests.swift index 8cf4696..3d5bd4a 100644 --- a/Tests/AWSLambdaEventsTests/CognitoTests.swift +++ b/Tests/AWSLambdaEventsTests/CognitoTests.swift @@ -45,7 +45,7 @@ final class CognitoTests: XCTestCase { """ let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) - guard case .preSignUpSignUp(let params, let request) = event else { + guard case .preSignUp(let params, let request) = event else { XCTFail() return } From e98d17f1dde2f48aae66a5e42edd075666a47e9d Mon Sep 17 00:00:00 2001 From: Jason Fry Date: Mon, 10 Jun 2024 13:02:11 +0100 Subject: [PATCH 6/6] Trigger source docs link --- Sources/AWSLambdaEvents/Cognito.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/AWSLambdaEvents/Cognito.swift b/Sources/AWSLambdaEvents/Cognito.swift index b179766..379aff1 100644 --- a/Sources/AWSLambdaEvents/Cognito.swift +++ b/Sources/AWSLambdaEvents/Cognito.swift @@ -26,6 +26,7 @@ public enum CognitoEvent: Equatable, Sendable { public let clientId: String } + /// https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-identity-pools-working-with-aws-lambda-trigger-sources public enum TriggerSource: String, Codable, Sendable { case preSignUp_SignUp = "PreSignUp_SignUp" case preSignUp_AdminCreateUser = "PreSignUp_AdminCreateUser"