Skip to content

Commit a0b64e9

Browse files
authored
Cognito Triggers - PreSignUp, PostConfirmation, PostAuthentication, CustomMessage (#57)
* More Cognito events - PostConfirmation - PostAuthentication - CustomMessage
1 parent eb88522 commit a0b64e9

File tree

2 files changed

+423
-27
lines changed

2 files changed

+423
-27
lines changed

Sources/AWSLambdaEvents/Cognito.swift

+214-22
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,149 @@ enum CognitoEventError: Error, Sendable {
1919
/// https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html
2020
public enum CognitoEvent: Equatable, Sendable {
2121
public struct CallerContext: Codable, Hashable, Sendable {
22-
let awsSdkVersion: String
23-
let clientId: String
22+
/// The version of the AWS SDK that generated the request.
23+
public let awsSdkVersion: String
24+
25+
/// The ID of the user pool app client.
26+
public let clientId: String
27+
}
28+
29+
/// 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
30+
public enum TriggerSource: String, Codable, Sendable {
31+
case preSignUp_SignUp = "PreSignUp_SignUp"
32+
case preSignUp_AdminCreateUser = "PreSignUp_AdminCreateUser"
33+
case preSignUp_ExternalProvider = "PreSignUp_ExternalProvider"
34+
35+
case postConfirmation_ConfirmSignUp = "PostConfirmation_ConfirmSignUp"
36+
case postConfirmation_ConfirmForgotPassword = "PostConfirmation_ConfirmForgotPassword"
37+
38+
case preAuthentication_Authentication = "PreAuthentication_Authentication"
39+
case postAuthentication_Authentication = "PostAuthentication_Authentication"
40+
41+
case customMessage_SignUp = "CustomMessage_SignUp"
42+
case customMessage_AdminCreateUser = "CustomMessage_AdminCreateUser"
43+
case customMessage_ResendCode = "CustomMessage_ResendCode"
44+
case customMessage_ForgotPassword = "CustomMessage_ForgotPassword"
45+
case customMessage_UpdateUserAttribute = "CustomMessage_UpdateUserAttribute"
46+
case customMessage_VerifyUserAttribute = "CustomMessage_VerifyUserAttribute"
47+
case customMessage_Authentication = "CustomMessage_Authentication"
48+
49+
case defineAuthChallenge_Authentication = "DefineAuthChallenge_Authentication"
50+
case createAuthChallenge_Authentication = "CreateAuthChallenge_Authentication"
51+
case verifyAuthChallengeResponse_Authentication = "VerifyAuthChallengeResponse_Authentication"
52+
53+
case tokenGeneration_HostedAuth = "TokenGeneration_HostedAuth"
54+
case tokenGeneration_Authentication = "TokenGeneration_Authentication"
55+
case tokenGeneration_NewPasswordChallenge = "TokenGeneration_NewPasswordChallenge"
56+
case tokenGeneration_AuthenticateDevice = "TokenGeneration_AuthenticateDevice"
57+
case tokenGeneration_RefreshTokens = "TokenGeneration_RefreshTokens"
58+
59+
case userMigration_Authentication = "UserMigration_Authentication"
60+
case userMigration_ForgotPassword = "UserMigration_ForgotPassword"
2461
}
2562

2663
public struct Parameters: Codable, Equatable, Sendable {
27-
let version: String
28-
let triggerSource: String
29-
let region: AWSRegion
30-
let userPoolId: String
31-
let userName: String
32-
let callerContext: CallerContext
64+
/// The version number of your Lambda function.
65+
public let version: String
66+
67+
/// The name of the event that triggered the Lambda function.
68+
///
69+
/// 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
70+
public let triggerSource: TriggerSource
71+
72+
/// The AWS Region as an AWSRegion instance.
73+
public let region: AWSRegion
74+
75+
/// The ID of the user pool.
76+
public let userPoolId: String
77+
78+
/// The current user's username.
79+
public let userName: String
80+
81+
/// Metadata about the request and the code environment.
82+
public let callerContext: CallerContext
3383
}
3484

35-
case preSignUpSignUp(Parameters, PreSignUp)
85+
case preSignUp(Parameters, PreSignUp)
3686

3787
public struct PreSignUp: Codable, Hashable, Sendable {
3888
/// One or more name-value pairs representing user attributes. The attribute names are the keys.
3989
public let userAttributes: [String: String]
90+
4091
/// One or more name-value pairs containing the validation data in the request to register a user.
4192
///
4293
/// 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.
4394
public let validationData: [String: String]?
95+
4496
/// 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.
4597
///
4698
/// You can pass this data to your Lambda function by using the ClientMetadata parameter in the following API actions: AdminCreateUser, AdminRespondToAuthChallenge, ForgotPassword, and SignUp.
4799
public let clientMetadata: [String: String]?
48100
}
49101

102+
case postConfirmation(Parameters, PostConfirmation)
103+
104+
public struct PostConfirmation: Codable, Equatable, Sendable {
105+
/// One or more key-value pairs representing user attributes.
106+
public let userAttributes: [String: String]
107+
108+
/// 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.
109+
///
110+
/// You can pass this data to your Lambda function by using the ClientMetadata parameter in the following API actions: AdminConfirmSignUp, ConfirmForgotPassword, ConfirmSignUp, and SignUp.
111+
public let clientMetadata: [String: String]?
112+
}
113+
114+
case postAuthentication(Parameters, PostAuthentication)
115+
116+
public struct PostAuthentication: Codable, Equatable, Sendable {
117+
/// 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.
118+
public let newDeviceUsed: Bool
119+
120+
/// One or more name-value pairs representing user attributes.
121+
public let userAttributes: [String: String]
122+
123+
/// 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.
124+
///
125+
/// To pass this data to your Lambda function, you can use the ClientMetadata parameter in the AdminRespondToAuthChallenge and RespondToAuthChallenge API actions.
126+
/// 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.
127+
public let clientMetadata: [String: String]?
128+
}
129+
130+
case customMessage(Parameters, CustomMessage)
131+
132+
public struct CustomMessage: Codable, Equatable, Sendable {
133+
/// A string for you to use as the placeholder for the verification code in the custom message.
134+
public let codeParameter: String?
135+
136+
/// The user name. Amazon Cognito includes this parameter in requests that result from admin-created users.
137+
public let usernameParameter: String?
138+
139+
/// One or more name-value pairs representing user attributes.
140+
public let userAttributes: [String: String]
141+
142+
/// 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.
143+
///
144+
/// 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:
145+
/// - AdminResetUserPassword
146+
/// - AdminRespondToAuthChallenge
147+
/// - AdminUpdateUserAttributes
148+
/// - ForgotPassword
149+
/// - GetUserAttributeVerificationCode
150+
/// - ResendConfirmationCode
151+
/// - SignUp
152+
/// - UpdateUserAttributes
153+
public let clientMetadata: [String: String]?
154+
}
155+
50156
public var commonParameters: Parameters {
51157
switch self {
52-
case .preSignUpSignUp(let params, _):
158+
case .preSignUp(let params, _):
159+
return params
160+
case .postConfirmation(let params, _):
161+
return params
162+
case .postAuthentication(let params, _):
163+
return params
164+
case .customMessage(let params, _):
53165
return params
54166
}
55167
}
@@ -71,7 +183,7 @@ extension CognitoEvent: Codable {
71183
let container = try decoder.container(keyedBy: CodingKeys.self)
72184

73185
let version = try container.decode(String.self, forKey: .version)
74-
let triggerSource = try container.decode(String.self, forKey: .triggerSource)
186+
let triggerSource = try container.decode(TriggerSource.self, forKey: .triggerSource)
75187
let region = try container.decode(AWSRegion.self, forKey: .region)
76188
let userPoolId = try container.decode(String.self, forKey: .userPoolId)
77189
let userName = try container.decode(String.self, forKey: .userName)
@@ -80,12 +192,24 @@ extension CognitoEvent: Codable {
80192
let params = CognitoEvent.Parameters(version: version, triggerSource: triggerSource, region: region, userPoolId: userPoolId, userName: userName, callerContext: callerContext)
81193

82194
switch triggerSource {
83-
case "PreSignUp_SignUp":
195+
case .preSignUp_SignUp, .preSignUp_ExternalProvider, .preSignUp_AdminCreateUser:
84196
let value = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request)
197+
self = .preSignUp(params, value)
198+
199+
case .postConfirmation_ConfirmSignUp, .postConfirmation_ConfirmForgotPassword:
200+
let value = try container.decode(CognitoEvent.PostConfirmation.self, forKey: .request)
201+
self = .postConfirmation(params, value)
202+
203+
case .postAuthentication_Authentication:
204+
let value = try container.decode(CognitoEvent.PostAuthentication.self, forKey: .request)
205+
self = .postAuthentication(params, value)
206+
207+
case .customMessage_SignUp, .customMessage_AdminCreateUser, .customMessage_ResendCode, .customMessage_ForgotPassword, .customMessage_UpdateUserAttribute, .customMessage_VerifyUserAttribute, .customMessage_Authentication:
208+
let value = try container.decode(CognitoEvent.CustomMessage.self, forKey: .request)
209+
self = .customMessage(params, value)
85210

86-
self = .preSignUpSignUp(params, value)
87211
default:
88-
throw CognitoEventError.unimplementedEvent(triggerSource)
212+
throw CognitoEventError.unimplementedEvent(triggerSource.rawValue)
89213
}
90214
}
91215

@@ -102,14 +226,25 @@ extension CognitoEvent: Codable {
102226
try container.encode(params.callerContext, forKey: .callerContext)
103227

104228
switch self {
105-
case .preSignUpSignUp(_, let value):
229+
case .preSignUp(_, let value):
230+
try container.encode(value, forKey: .response)
231+
case .postConfirmation(_, let value):
232+
try container.encode(value, forKey: .response)
233+
case .postAuthentication(_, let value):
234+
try container.encode(value, forKey: .response)
235+
case .customMessage(_, let value):
106236
try container.encode(value, forKey: .response)
107237
}
108238
}
109239
}
110240

111241
public enum CognitoEventResponse: Sendable {
112-
case preSignUpSignUp(CognitoEvent.Parameters, CognitoEvent.PreSignUp, PreSignUp)
242+
// Used for when there are no parameters expected in the response
243+
public struct EmptyResponse: Codable, Equatable, Sendable {
244+
public init() {}
245+
}
246+
247+
case preSignUp(CognitoEvent.Parameters, CognitoEvent.PreSignUp, PreSignUp)
113248

114249
public struct PreSignUp: Codable, Hashable, Sendable {
115250
public let autoConfirmUser: Bool
@@ -123,9 +258,38 @@ public enum CognitoEventResponse: Sendable {
123258
}
124259
}
125260

261+
case postConfirmation(CognitoEvent.Parameters, CognitoEvent.PostConfirmation, EmptyResponse)
262+
263+
case postAuthentication(CognitoEvent.Parameters, CognitoEvent.PostAuthentication, EmptyResponse)
264+
265+
case customMessage(CognitoEvent.Parameters, CognitoEvent.CustomMessage, CustomMessage)
266+
267+
public struct CustomMessage: Codable, Equatable, Sendable {
268+
public init(smsMessage: String? = nil, emailMessage: String? = nil, emailSubject: String? = nil) {
269+
self.smsMessage = smsMessage
270+
self.emailMessage = emailMessage
271+
self.emailSubject = emailSubject
272+
}
273+
274+
/// The custom SMS message to be sent to your users. Must include the codeParameter value that you received in the request.
275+
public let smsMessage: String?
276+
277+
/// 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 {####}.
278+
public let emailMessage: String?
279+
280+
/// The subject line for the custom message
281+
public let emailSubject: String?
282+
}
283+
126284
public var commonParameters: CognitoEvent.Parameters {
127285
switch self {
128-
case .preSignUpSignUp(let params, _, _):
286+
case .preSignUp(let params, _, _):
287+
return params
288+
case .postConfirmation(let params, _, _):
289+
return params
290+
case .postAuthentication(let params, _, _):
291+
return params
292+
case .customMessage(let params, _, _):
129293
return params
130294
}
131295
}
@@ -147,7 +311,7 @@ extension CognitoEventResponse: Codable {
147311
let container = try decoder.container(keyedBy: CodingKeys.self)
148312

149313
let version = try container.decode(String.self, forKey: .version)
150-
let triggerSource = try container.decode(String.self, forKey: .triggerSource)
314+
let triggerSource = try container.decode(CognitoEvent.TriggerSource.self, forKey: .triggerSource)
151315
let region = try container.decode(AWSRegion.self, forKey: .region)
152316
let userPoolId = try container.decode(String.self, forKey: .userPoolId)
153317
let userName = try container.decode(String.self, forKey: .userName)
@@ -156,13 +320,32 @@ extension CognitoEventResponse: Codable {
156320
let params = CognitoEvent.Parameters(version: version, triggerSource: triggerSource, region: region, userPoolId: userPoolId, userName: userName, callerContext: callerContext)
157321

158322
switch triggerSource {
159-
case "PreSignUp_SignUp":
323+
case .preSignUp_SignUp, .preSignUp_AdminCreateUser, .preSignUp_ExternalProvider:
160324
let request = try container.decode(CognitoEvent.PreSignUp.self, forKey: .request)
161325
let response = try container.decode(CognitoEventResponse.PreSignUp.self, forKey: .response)
162326

163-
self = .preSignUpSignUp(params, request, response)
327+
self = .preSignUp(params, request, response)
328+
329+
case .postConfirmation_ConfirmSignUp, .postConfirmation_ConfirmForgotPassword:
330+
let request = try container.decode(CognitoEvent.PostConfirmation.self, forKey: .request)
331+
let response = try container.decode(CognitoEventResponse.EmptyResponse.self, forKey: .response)
332+
333+
self = .postConfirmation(params, request, response)
334+
335+
case .postAuthentication_Authentication:
336+
let request = try container.decode(CognitoEvent.PostAuthentication.self, forKey: .request)
337+
let response = try container.decode(CognitoEventResponse.EmptyResponse.self, forKey: .response)
338+
339+
self = .postAuthentication(params, request, response)
340+
341+
case .customMessage_SignUp, .customMessage_AdminCreateUser, .customMessage_ResendCode, .customMessage_ForgotPassword, .customMessage_UpdateUserAttribute, .customMessage_VerifyUserAttribute, .customMessage_Authentication:
342+
let request = try container.decode(CognitoEvent.CustomMessage.self, forKey: .request)
343+
let response = try container.decode(CognitoEventResponse.CustomMessage.self, forKey: .response)
344+
345+
self = .customMessage(params, request, response)
346+
164347
default:
165-
throw CognitoEventError.unimplementedEvent(triggerSource)
348+
throw CognitoEventError.unimplementedEvent(triggerSource.rawValue)
166349
}
167350
}
168351

@@ -179,7 +362,16 @@ extension CognitoEventResponse: Codable {
179362
try container.encode(params.callerContext, forKey: .callerContext)
180363

181364
switch self {
182-
case .preSignUpSignUp(_, let request, let response):
365+
case .preSignUp(_, let request, let response):
366+
try container.encode(request, forKey: .request)
367+
try container.encode(response, forKey: .response)
368+
case .postConfirmation(_, let request, let response):
369+
try container.encode(request, forKey: .request)
370+
try container.encode(response, forKey: .response)
371+
case .postAuthentication(_, let request, let response):
372+
try container.encode(request, forKey: .request)
373+
try container.encode(response, forKey: .response)
374+
case .customMessage(_, let request, let response):
183375
try container.encode(request, forKey: .request)
184376
try container.encode(response, forKey: .response)
185377
}

0 commit comments

Comments
 (0)