diff --git a/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift b/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift index 5c467f4fa1..5c3fc21076 100644 --- a/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift @@ -27,10 +27,19 @@ extension AuthCategory: AuthCategoryUserBehavior { try await plugin.update(userAttributes: userAttributes, options: options) } - public func resendConfirmationCode(forUserAttributeKey userAttributeKey: AuthUserAttributeKey, - options: AuthAttributeResendConfirmationCodeRequest.Options? = nil) async throws -> AuthCodeDeliveryDetails { + @available(*, deprecated, renamed: "sendVerificationCode(forUserAttributeKey:options:)") + public func resendConfirmationCode( + forUserAttributeKey userAttributeKey: AuthUserAttributeKey, + options: AuthAttributeResendConfirmationCodeRequest.Options? = nil + ) async throws -> AuthCodeDeliveryDetails { try await plugin.resendConfirmationCode(forUserAttributeKey: userAttributeKey, options: options) + } + public func sendVerificationCode( + forUserAttributeKey userAttributeKey: AuthUserAttributeKey, + options: AuthSendUserAttributeVerificationCodeRequest.Options? = nil + ) async throws -> AuthCodeDeliveryDetails { + try await plugin.sendVerificationCode(forUserAttributeKey: userAttributeKey, options: options) } public func confirm(userAttribute: AuthUserAttributeKey, diff --git a/Amplify/Categories/Auth/AuthCategoryUserBehavior.swift b/Amplify/Categories/Auth/AuthCategoryUserBehavior.swift index 45e622b9c5..f3917109c7 100644 --- a/Amplify/Categories/Auth/AuthCategoryUserBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategoryUserBehavior.swift @@ -39,8 +39,21 @@ public protocol AuthCategoryUserBehavior: AnyObject { /// - Parameters: /// - userAttributeKey: Attribute to be verified /// - options: Parameters specific to plugin behavior - func resendConfirmationCode(forUserAttributeKey userAttributeKey: AuthUserAttributeKey, - options: AuthAttributeResendConfirmationCodeRequest.Options?) async throws -> AuthCodeDeliveryDetails + @available(*, deprecated, renamed: "sendVerificationCode(forUserAttributeKey:options:)") + func resendConfirmationCode( + forUserAttributeKey userAttributeKey: AuthUserAttributeKey, + options: AuthAttributeResendConfirmationCodeRequest.Options? + ) async throws -> AuthCodeDeliveryDetails + + /// Sends the verification code required to verify an attribute + /// + /// - Parameters: + /// - userAttributeKey: Attribute to be verified + /// - options: Parameters specific to plugin behavior + func sendVerificationCode( + forUserAttributeKey userAttributeKey: AuthUserAttributeKey, + options: AuthSendUserAttributeVerificationCodeRequest.Options? + ) async throws -> AuthCodeDeliveryDetails /// Confirm an attribute using confirmation code /// diff --git a/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift b/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift new file mode 100644 index 0000000000..ec5f0a4683 --- /dev/null +++ b/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift @@ -0,0 +1,41 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation + +// swiftlint:disable type_name + +/// Request for sending verification code that was generated for update attribute +public struct AuthSendUserAttributeVerificationCodeRequest: AmplifyOperationRequest { + + /// Attribute key for which the confirmation code was sent + public let attributeKey: AuthUserAttributeKey + + /// Extra request options defined in `AuthSendUserAttributeVerificationCodeRequest.Options` + public var options: Options + + public init(attributeKey: AuthUserAttributeKey, + options: Options) { + self.attributeKey = attributeKey + self.options = options + } +} + +public extension AuthSendUserAttributeVerificationCodeRequest { + + struct Options { + + /// Extra plugin specific options, only used in special circumstances when the existing options do not provide + /// a way to utilize the underlying auth plugin functionality. See plugin documentation for expected + /// key/values + public let pluginOptions: Any? + + public init(pluginOptions: Any? = nil) { + self.pluginOptions = pluginOptions + } + } +} diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+UserBehavior.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+UserBehavior.swift index c8355d5c7c..9d2608bf16 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+UserBehavior.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+UserBehavior.swift @@ -41,8 +41,11 @@ public extension AWSCognitoAuthPlugin { } as! [AuthUserAttributeKey: AuthUpdateAttributeResult] } - func resendConfirmationCode(forUserAttributeKey userAttributeKey: AuthUserAttributeKey, - options: AuthAttributeResendConfirmationCodeRequest.Options? = nil) async throws -> AuthCodeDeliveryDetails { + @available(*, deprecated, renamed: "sendVerificationCode(forUserAttributeKey:options:)") + func resendConfirmationCode( + forUserAttributeKey userAttributeKey: AuthUserAttributeKey, + options: AuthAttributeResendConfirmationCodeRequest.Options? = nil + ) async throws -> AuthCodeDeliveryDetails { let options = options ?? AuthAttributeResendConfirmationCodeRequest.Options() let request = AuthAttributeResendConfirmationCodeRequest( @@ -53,6 +56,22 @@ public extension AWSCognitoAuthPlugin { } as! AuthCodeDeliveryDetails } + func sendVerificationCode( + forUserAttributeKey userAttributeKey: + AuthUserAttributeKey, + options: AuthSendUserAttributeVerificationCodeRequest.Options? = nil + ) async throws -> AuthCodeDeliveryDetails { + let options = options ?? AuthSendUserAttributeVerificationCodeRequest.Options() + let request = AuthSendUserAttributeVerificationCodeRequest( + attributeKey: userAttributeKey, options: options) + let task = AWSAuthSendUserAttributeVerificationCodeTask( + request, authStateMachine: authStateMachine, + userPoolFactory: authEnvironment.cognitoUserPoolFactory) + return try await taskQueue.sync { + return try await task.value + } as! AuthCodeDeliveryDetails + } + func confirm(userAttribute: AuthUserAttributeKey, confirmationCode: String, options: AuthConfirmUserAttributeRequest.Options? = nil) async throws { let options = options ?? AuthConfirmUserAttributeRequest.Options() let request = AuthConfirmUserAttributeRequest( diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSAttributeResendConfirmationCodeOptions.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSAttributeResendConfirmationCodeOptions.swift index 64b339ef47..de38707691 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSAttributeResendConfirmationCodeOptions.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSAttributeResendConfirmationCodeOptions.swift @@ -7,6 +7,7 @@ import Foundation +@available(*, deprecated, renamed: "AWSSendUserAttributeVerificationCodeOptions") public struct AWSAttributeResendConfirmationCodeOptions { /// A map of custom key-value pairs that you can provide as input for any custom workflows that this action triggers. diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSSendUserAttributeVerificationCodeOptions.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSSendUserAttributeVerificationCodeOptions.swift new file mode 100644 index 0000000000..81c7af6907 --- /dev/null +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSSendUserAttributeVerificationCodeOptions.swift @@ -0,0 +1,25 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation + +public struct AWSSendUserAttributeVerificationCodeOptions { + + /// A map of custom key-value pairs that you can provide as input for any custom workflows that this action triggers. + /// + /// When you use the ResendConfirmationCode API action, Amazon Cognito invokes the function that is assigned to the custom message trigger. + /// When Amazon Cognito invokes this function, it passes a JSON payload, which the function receives as input. + /// This payload contains a clientMetadata attribute, which provides the data that you assigned to the ClientMetadata parameter in your GetUserAttributeVerificationCode request. + /// In your function code in AWS Lambda, you can process the clientMetadata value to enhance your workflow for your specific needs. + /// + /// For more information, see Customizing user pool Workflows with Lambda Triggers in the Amazon Cognito Developer Guide. + public let metadata: [String: String]? + + public init(metadata: [String: String]? = nil) { + self.metadata = metadata + } +} diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/Protocols/UserTasks/AuthSendUserAttributeVerificationCodeTask.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/Protocols/UserTasks/AuthSendUserAttributeVerificationCodeTask.swift new file mode 100644 index 0000000000..2399826053 --- /dev/null +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/Protocols/UserTasks/AuthSendUserAttributeVerificationCodeTask.swift @@ -0,0 +1,16 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Amplify + +protocol AuthSendUserAttributeVerificationCodeTask: AmplifyAuthTask where Request == AuthSendUserAttributeVerificationCodeRequest, Success == AuthCodeDeliveryDetails, Failure == AuthError {} + +public extension HubPayload.EventName.Auth { + + /// eventName for HubPayloads emitted by this operation + static let sendUserAttributeVerificationCodeAPI = "Auth.sendUserAttributeVerificationCodeAPI" +} diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/UserTasks/AWSAuthSendUserAttributeVerificationCodeTask.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/UserTasks/AWSAuthSendUserAttributeVerificationCodeTask.swift new file mode 100644 index 0000000000..5dc3962038 --- /dev/null +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/UserTasks/AWSAuthSendUserAttributeVerificationCodeTask.swift @@ -0,0 +1,67 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation +import Amplify +import AWSPluginsCore +import AWSCognitoIdentityProvider + +class AWSAuthSendUserAttributeVerificationCodeTask: AuthSendUserAttributeVerificationCodeTask { + typealias CognitoUserPoolFactory = () throws -> CognitoUserPoolBehavior + + private let request: AuthSendUserAttributeVerificationCodeRequest + private let authStateMachine: AuthStateMachine + private let userPoolFactory: CognitoUserPoolFactory + private let taskHelper: AWSAuthTaskHelper + + var eventName: HubPayloadEventName { + HubPayload.EventName.Auth.sendUserAttributeVerificationCodeAPI + } + + init(_ request: AuthSendUserAttributeVerificationCodeRequest, + authStateMachine: AuthStateMachine, + userPoolFactory: @escaping CognitoUserPoolFactory) { + self.request = request + self.authStateMachine = authStateMachine + self.userPoolFactory = userPoolFactory + self.taskHelper = AWSAuthTaskHelper(authStateMachine: authStateMachine) + } + + func execute() async throws -> AuthCodeDeliveryDetails { + do { + await taskHelper.didStateMachineConfigured() + let accessToken = try await taskHelper.getAccessToken() + let devices = try await initiateGettingVerificationCode(with: accessToken) + return devices + } catch let error as AuthErrorConvertible { + throw error.authError + } catch { + throw AuthError.configuration( + "Unable to execute auth task", + AuthPluginErrorConstants.configurationError, + error + ) + } + } + + func initiateGettingVerificationCode(with accessToken: String) async throws -> AuthCodeDeliveryDetails { + let userPoolService = try userPoolFactory() + let clientMetaData = (request.options.pluginOptions as? AWSSendUserAttributeVerificationCodeOptions)?.metadata ?? [:] + + let input = GetUserAttributeVerificationCodeInput( + accessToken: accessToken, + attributeName: request.attributeKey.rawValue, + clientMetadata: clientMetaData) + + let result = try await userPoolService.getUserAttributeVerificationCode(input: input) + guard let deliveryDetails = result.codeDeliveryDetails?.toAuthCodeDeliveryDetails() else { + let authError = AuthError.unknown("Unable to get Auth code delivery details", nil) + throw authError + } + return deliveryDetails + } +} diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/AWSCognitoAuthUserBehaviorTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/AWSCognitoAuthUserBehaviorTests.swift index f5110aca6a..3c3eebe100 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/AWSCognitoAuthUserBehaviorTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/AWSCognitoAuthUserBehaviorTests.swift @@ -136,15 +136,15 @@ class AWSCognitoAuthUserBehaviorTests: BasePluginTest { _ = try await plugin.update(userAttributes: [emailAttribute, phoneAttribute]) } - /// Test resendConfirmationCode(for:) operation can be invoked + /// Test sendVerificationCode(for:) operation can be invoked /// /// - Given: Given a configured auth plugin /// - When: - /// - I call resendConfirmationCode(for:) operation + /// - I call sendVerificationCode(for:) operation /// - Then: /// - I should get a valid task completion /// - func testResendConfirmationCodeAttributeRequest() async throws { + func testSendVerificationCodeAttributeRequest() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in GetUserAttributeVerificationCodeOutput( codeDeliveryDetails: .init( @@ -152,20 +152,20 @@ class AWSCognitoAuthUserBehaviorTests: BasePluginTest { deliveryMedium: .email, destination: "destination")) }) - let pluginOptions = AWSAttributeResendConfirmationCodeOptions(metadata: ["key": "value"]) - let options = AuthAttributeResendConfirmationCodeRequest.Options(pluginOptions: pluginOptions) - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email, options: options) + let pluginOptions = AWSSendUserAttributeVerificationCodeOptions(metadata: ["key": "value"]) + let options = AuthSendUserAttributeVerificationCodeRequest.Options(pluginOptions: pluginOptions) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email, options: options) } - /// Test resendConfirmationCode(for:) operation can be invoked with plugin options + /// Test sendVerificationCode(for:) operation can be invoked with plugin options /// /// - Given: Given a configured auth plugin /// - When: - /// - I call resendConfirmationCode(for:) operation + /// - I call sendVerificationCode(for:) operation /// - Then: /// - I should get a valid task completion /// - func testResendConfirmationCodeWithPluginOptions() async throws { + func testSendVerificationCodeWithPluginOptions() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { request in XCTAssertNotNil(request.clientMetadata) @@ -176,20 +176,20 @@ class AWSCognitoAuthUserBehaviorTests: BasePluginTest { deliveryMedium: .email, destination: "destination")) }) - let pluginOptions = AWSAttributeResendConfirmationCodeOptions(metadata: ["key": "value"]) - let options = AuthAttributeResendConfirmationCodeRequest.Options(pluginOptions: pluginOptions) - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email, options: options) + let pluginOptions = AWSSendUserAttributeVerificationCodeOptions(metadata: ["key": "value"]) + let options = AuthSendUserAttributeVerificationCodeRequest.Options(pluginOptions: pluginOptions) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email, options: options) } - /// Test resendConfirmationCode(for:) operation can be invoked without options + /// Test sendVerificationCode(for:) operation can be invoked without options /// /// - Given: Given a configured auth plugin /// - When: - /// - I call resendConfirmationCode(for:) operation + /// - I call sendVerificationCode(for:) operation /// - Then: /// - I should get a valid task completion /// - func testResendConfirmationCodeAttributeRequestWithoutOptions() async throws { + func testSendVerificationCodeAttributeRequestWithoutOptions() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in GetUserAttributeVerificationCodeOutput( codeDeliveryDetails: .init( @@ -197,7 +197,7 @@ class AWSCognitoAuthUserBehaviorTests: BasePluginTest { deliveryMedium: .email, destination: "destination")) }) - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) } /// Test confirm(userAttribute: ) operation can be invoked diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/UserBehaviorResendCodeTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/SendUserAttributeVerificationCodeTests.swift similarity index 75% rename from AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/UserBehaviorResendCodeTests.swift rename to AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/SendUserAttributeVerificationCodeTests.swift index 89b542d82a..cf2a4239d9 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/UserBehaviorResendCodeTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/UserBehaviourTests/SendUserAttributeVerificationCodeTests.swift @@ -13,17 +13,17 @@ import XCTest import AWSCognitoIdentityProvider import ClientRuntime -class UserBehaviorResendCodeTests: BasePluginTest { +class SendUserAttributeVerificationCodeTests: BasePluginTest { - /// Test a successful resendConfirmationCode call with .done as next step + /// Test a successful sendVerificationCode call with .done as next step /// /// - Given: an auth plugin with mocked service. Mocked service calls should mock a successful response /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a successful result with .email as the attribute's destination /// - func testSuccessfulResendConfirmationCode() async throws { + func testSuccessfulSendVerificationCode() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in GetUserAttributeVerificationCodeOutput( @@ -33,28 +33,28 @@ class UserBehaviorResendCodeTests: BasePluginTest { destination: "destination")) }) - let attribute = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + let attribute = try await plugin.sendVerificationCode(forUserAttributeKey: .email) guard case .email = attribute.destination else { XCTFail("Result should be .email for attributeKey") return } } - /// Test a resendConfirmationCode call with invalid result + /// Test a sendVerificationCode call with invalid result /// /// - Given: an auth plugin with mocked service. Mocked service calls should mock a invalid response /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get an .unknown error /// - func testResendConfirmationCodeWithInvalidResult() async throws { + func testSendVerificationCodeWithInvalidResult() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in GetUserAttributeVerificationCodeOutput() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.unknown = error else { @@ -64,16 +64,16 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with CodeMismatchException response from service + /// Test a sendVerificationCode call with CodeMismatchException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// CodeMismatchException response /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .codeMismatch as underlyingError /// - func testResendConfirmationCodeWithCodeMismatchException() async throws { + func testSendVerificationCodeWithCodeMismatchException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw try await AWSCognitoIdentityProvider.CodeDeliveryFailureException( @@ -84,7 +84,7 @@ class UserBehaviorResendCodeTests: BasePluginTest { ) }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -98,21 +98,21 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with InternalErrorException response from service + /// Test a sendVerificationCode call with InternalErrorException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a InternalErrorException response /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get an .unknown error /// - func testResendConfirmationCodeWithInternalErrorException() async throws { + func testSendVerificationCodeWithInternalErrorException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.InternalErrorException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.unknown = error else { @@ -122,23 +122,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with InvalidParameterException response from service + /// Test a sendVerificationCode call with InvalidParameterException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// InvalidParameterException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .invalidParameter as underlyingError /// - func testResendConfirmationCodeWithInvalidParameterException() async throws { + func testSendVerificationCodeWithInvalidParameterException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.InvalidParameterException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -152,24 +152,24 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with LimitExceededException response from service + /// Test a sendVerificationCode call with LimitExceededException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// LimitExceededException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .limitExceeded as underlyingError /// - func testResendConfirmationCodeWithLimitExceededException() async throws { + func testSendVerificationCodeWithLimitExceededException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.LimitExceededException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -183,23 +183,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with NotAuthorizedException response from service + /// Test a sendVerificationCode call with NotAuthorizedException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// NotAuthorizedException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .notAuthorized error /// - func testResendConfirmationCodeWithNotAuthorizedException() async throws { + func testSendVerificationCodeWithNotAuthorizedException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.NotAuthorizedException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.notAuthorized = error else { @@ -209,23 +209,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with PasswordResetRequiredException response from service + /// Test a sendVerificationCode call with PasswordResetRequiredException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// PasswordResetRequiredException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .passwordResetRequired as underlyingError /// - func testResendConfirmationCodeWithPasswordResetRequiredException() async throws { + func testSendVerificationCodeWithPasswordResetRequiredException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.PasswordResetRequiredException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -239,23 +239,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with ResourceNotFoundException response from service + /// Test a sendVerificationCode call with ResourceNotFoundException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// ResourceNotFoundException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .resourceNotFound as underlyingError /// - func testResendConfirmationCodeWithResourceNotFoundException() async throws { + func testSendVerificationCodeWithResourceNotFoundException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.ResourceNotFoundException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -269,23 +269,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with TooManyRequestsException response from service + /// Test a sendVerificationCode call with TooManyRequestsException response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// TooManyRequestsException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .requestLimitExceeded as underlyingError /// - func testResendConfirmationCodeWithTooManyRequestsException() async throws { + func testSendVerificationCodeWithTooManyRequestsException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.TooManyRequestsException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -299,23 +299,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with UserNotFound response from service + /// Test a sendVerificationCode call with UserNotFound response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// UserNotConfirmedException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .userNotConfirmed as underlyingError /// - func testResendConfirmationCodeWithUserNotConfirmedException() async throws { + func testSendVerificationCodeWithUserNotConfirmedException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.UserNotConfirmedException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { @@ -329,23 +329,23 @@ class UserBehaviorResendCodeTests: BasePluginTest { } } - /// Test a resendConfirmationCode call with UserNotFound response from service + /// Test a sendVerificationCode call with UserNotFound response from service /// /// - Given: an auth plugin with mocked service. Mocked service should mock a /// UserNotFoundException response /// /// - When: - /// - I invoke resendConfirmationCode + /// - I invoke sendVerificationCode /// - Then: /// - I should get a .service error with .userNotFound as underlyingError /// - func testResendConfirmationCodeWithUserNotFoundException() async throws { + func testSendVerificationCodeWithUserNotFoundException() async throws { mockIdentityProvider = MockIdentityProvider(mockGetUserAttributeVerificationCodeOutput: { _ in throw AWSCognitoIdentityProvider.UserNotFoundException() }) do { - _ = try await plugin.resendConfirmationCode(forUserAttributeKey: .email) + _ = try await plugin.sendVerificationCode(forUserAttributeKey: .email) XCTFail("Should return an error if the result from service is invalid") } catch { guard case AuthError.service(_, _, let underlyingError) = error else { diff --git a/AmplifyPlugins/Auth/Tests/AuthHostApp/AuthIntegrationTests/AuthUserAttributesTests/AuthUserAttributesTests.swift b/AmplifyPlugins/Auth/Tests/AuthHostApp/AuthIntegrationTests/AuthUserAttributesTests/AuthUserAttributesTests.swift index f8695e2000..78f9b2a099 100644 --- a/AmplifyPlugins/Auth/Tests/AuthHostApp/AuthIntegrationTests/AuthUserAttributesTests/AuthUserAttributesTests.swift +++ b/AmplifyPlugins/Auth/Tests/AuthHostApp/AuthIntegrationTests/AuthUserAttributesTests/AuthUserAttributesTests.swift @@ -171,11 +171,11 @@ class AuthUserAttributesTests: AWSAuthBaseTest { /// /// - Given: A confirmed user, with email added to the user's attributes (sending first confirmation code) /// - When: - /// - I invoke Amplify.Auth.resendConfirmationCode for email + /// - I invoke Amplify.Auth.sendVerificationCode for email /// - Then: /// - The request should be successful and the email specified should receive a second confirmation code /// - func testSuccessfulResendConfirmationCodeWithUpdatedEmail() async throws { + func testSuccessfulSendVerificationCodeWithUpdatedEmail() async throws { let username = "integTest\(UUID().uuidString)" let password = "P123@\(UUID().uuidString)" let updatedEmail = "\(username)@amazon.com" @@ -186,9 +186,9 @@ class AuthUserAttributesTests: AWSAuthBaseTest { XCTAssertTrue(didSucceed, "SignIn operation failed") _ = try await Amplify.Auth.update(userAttribute: AuthUserAttribute(.email, value: updatedEmail)) - let pluginOptions = AWSAttributeResendConfirmationCodeOptions(metadata: ["mydata": "myvalue"]) - let options = AuthAttributeResendConfirmationCodeRequest.Options(pluginOptions: pluginOptions) - _ = try await Amplify.Auth.resendConfirmationCode(forUserAttributeKey: .email, options: options) + let pluginOptions = AWSSendUserAttributeVerificationCodeOptions(metadata: ["mydata": "myvalue"]) + let options = AuthSendUserAttributeVerificationCodeRequest.Options(pluginOptions: pluginOptions) + _ = try await Amplify.Auth.sendVerificationCode(forUserAttributeKey: .email, options: options) } /// Test resending code for the user's updated email attribute. @@ -199,11 +199,11 @@ class AuthUserAttributesTests: AWSAuthBaseTest { /// /// - Given: A confirmed user, with email added to the user's attributes (sending first confirmation code) /// - When: - /// - I invoke Amplify.Auth.resendConfirmationCode for email + /// - I invoke Amplify.Auth.sendVerificationCode for email /// - Then: /// - The request should be successful and the email specified should receive a second confirmation code /// - func testSuccessfulResendConfirmationCode() async throws { + func testSuccessfulSendVerificationCode() async throws { let username = "integTest\(UUID().uuidString)" let password = "P123@\(UUID().uuidString)" @@ -212,9 +212,9 @@ class AuthUserAttributesTests: AWSAuthBaseTest { email: defaultTestEmail) XCTAssertTrue(didSucceed, "SignIn operation failed") - let pluginOptions = AWSAttributeResendConfirmationCodeOptions(metadata: ["mydata": "myvalue"]) - let options = AuthAttributeResendConfirmationCodeRequest.Options(pluginOptions: pluginOptions) - _ = try await Amplify.Auth.resendConfirmationCode(forUserAttributeKey: .email, options: options) + let pluginOptions = AWSSendUserAttributeVerificationCodeOptions(metadata: ["mydata": "myvalue"]) + let options = AuthSendUserAttributeVerificationCodeRequest.Options(pluginOptions: pluginOptions) + _ = try await Amplify.Auth.sendVerificationCode(forUserAttributeKey: .email, options: options) } /// Test changing/updating users password. diff --git a/AmplifyPlugins/Predictions/Tests/PredictionsHostApp/AWSPredictionsPluginIntegrationTests/IdentifyBasicIntegrationTests.swift b/AmplifyPlugins/Predictions/Tests/PredictionsHostApp/AWSPredictionsPluginIntegrationTests/IdentifyBasicIntegrationTests.swift index 3628f3680c..3b8762e00d 100644 --- a/AmplifyPlugins/Predictions/Tests/PredictionsHostApp/AWSPredictionsPluginIntegrationTests/IdentifyBasicIntegrationTests.swift +++ b/AmplifyPlugins/Predictions/Tests/PredictionsHostApp/AWSPredictionsPluginIntegrationTests/IdentifyBasicIntegrationTests.swift @@ -207,8 +207,6 @@ class IdentifyBasicIntegrationTests: AWSPredictionsPluginTestBase { XCTAssertFalse(result.tables.isEmpty) XCTAssertEqual(result.tables.count, 1) XCTAssertFalse(result.keyValues.isEmpty) - XCTAssertEqual(result.keyValues.count, 4) - } /// Given: diff --git a/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift b/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift index 2a7bd7f1fd..94e44aa795 100644 --- a/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift +++ b/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift @@ -96,7 +96,13 @@ class MockAuthCategoryPlugin: MessageReporter, AuthCategoryPlugin { public func resendConfirmationCode(forUserAttributeKey userAttributeKey: AuthUserAttributeKey, options: AuthAttributeResendConfirmationCodeRequest.Options? = nil) async throws -> AuthCodeDeliveryDetails { fatalError() + } + public func sendVerificationCode( + forUserAttributeKey userAttributeKey: AuthUserAttributeKey, + options: AuthSendUserAttributeVerificationCodeRequest.Options? = nil) + async throws -> AuthCodeDeliveryDetails { + fatalError() } public func setUpTOTP() async throws -> TOTPSetupDetails {