diff --git a/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift b/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift index dfd92b9e92..5218766229 100644 --- a/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift @@ -85,5 +85,22 @@ extension AuthCategory: AuthCategoryBehavior { ) async throws { try await plugin.verifyTOTPSetup(code: code, options: options) } - + + // MARK: - Passwordless Auth + + public func signInWithMagicLink( + username: String, + flow: AuthPasswordlessFlow, + redirectURL: String, + options: AuthSignInRequest.Options? + ) async throws -> AuthSignInResult { + try await plugin.signInWithMagicLink(username: username, flow: flow, redirectURL: redirectURL, options: options) + } + + public func confirmSignInWithMagicLink( + challengeResponse: String, + options: AuthConfirmSignInRequest.Options? + ) async throws -> AuthSignInResult { + try await plugin.confirmSignInWithMagicLink(challengeResponse: challengeResponse, options: options) + } } diff --git a/Amplify/Categories/Auth/AuthCategoryBehavior.swift b/Amplify/Categories/Auth/AuthCategoryBehavior.swift index dd42213863..0c8f9211ac 100644 --- a/Amplify/Categories/Auth/AuthCategoryBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategoryBehavior.swift @@ -145,4 +145,34 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi options: VerifyTOTPSetupRequest.Options? ) async throws + // MARK: - Passwordless Auth + + /// Initiates Sign in with Magiclink + /// + /// Invoke this operation to start sign in with Magic Link flow + /// + /// - Parameters: + /// - username: username used for sign in + /// - flow: `AuthPasswordlessFlow` type - can be `.signUpAndSignIn` or `.signIn` + /// - redirectURL: URL format to be used for the Magic Link + /// - options: Parameters specific to plugin behavior + func signInWithMagicLink( + username: String, + flow: AuthPasswordlessFlow, + redirectURL: String, + options: AuthSignInRequest.Options? + ) async throws -> AuthSignInResult + + /// Confirms Sign in with Magiclink flow + /// + /// Invoke this operation to confirm sign in with Magic Link flow and sign in the user + /// + /// - Parameters: + /// - challengeResponse: challengeResponse contained in the Magic Link received by the user + /// - options: Parameters specific to plugin behavior + func confirmSignInWithMagicLink( + challengeResponse: String, + options: AuthConfirmSignInRequest.Options? + ) async throws -> AuthSignInResult + } diff --git a/Amplify/Categories/Auth/Models/AuthPasswordlessDeliveryDestination.swift b/Amplify/Categories/Auth/Models/AuthPasswordlessDeliveryDestination.swift new file mode 100644 index 0000000000..d3ef3c7ca6 --- /dev/null +++ b/Amplify/Categories/Auth/Models/AuthPasswordlessDeliveryDestination.swift @@ -0,0 +1,15 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation + +/// Delivery destination for the Auth Passwordless flows +/// +public enum AuthPasswordlessDeliveryDestination { + case phone + case email +} diff --git a/Amplify/Categories/Auth/Models/AuthPasswordlessFlow.swift b/Amplify/Categories/Auth/Models/AuthPasswordlessFlow.swift new file mode 100644 index 0000000000..84da7ebc5a --- /dev/null +++ b/Amplify/Categories/Auth/Models/AuthPasswordlessFlow.swift @@ -0,0 +1,20 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation + +/// Auth Passwordless flow types +/// +/// `.signUpAndSignIn` will create a new user and initiate signing in the user +/// `.signIn` will initiate signing in an existing user +public enum AuthPasswordlessFlow { + case signUpAndSignIn( + userAttributes: [String: String]?, + clientMetadata: [String: String]? + ) + case signIn(clientMetadata: [String: String]?) +} diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+ClientBehavior.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+ClientBehavior.swift index 0dc729a532..d17015d744 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+ClientBehavior.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+ClientBehavior.swift @@ -193,4 +193,20 @@ extension AWSCognitoAuthPlugin: AuthCategoryBehavior { return try await task.value } } + + public func signInWithMagicLink( + username: String, + flow: AuthPasswordlessFlow, + redirectURL: String, + options: AuthSignInRequest.Options? + ) async throws -> AuthSignInResult { + throw AuthError.unknown("Not Implemented") + } + + public func confirmSignInWithMagicLink( + challengeResponse: String, + options: AuthConfirmSignInRequest.Options? + ) async throws -> AuthSignInResult { + throw AuthError.unknown("Not Implemented") + } } diff --git a/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift b/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift index 94e44aa795..14dd4b53c0 100644 --- a/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift +++ b/AmplifyTestCommon/Mocks/MockAuthCategoryPlugin.swift @@ -115,6 +115,14 @@ class MockAuthCategoryPlugin: MessageReporter, AuthCategoryPlugin { ) async throws { fatalError() } + + func signInWithMagicLink(username: String, flow: AuthPasswordlessFlow, redirectURL: String, options: AuthSignInRequest.Options?) async throws -> AuthSignInResult { + fatalError() + } + + func confirmSignInWithMagicLink(challengeResponse: String, options: AuthConfirmSignInRequest.Options?) async throws -> AuthSignInResult { + fatalError() + } public func confirm(userAttribute: AuthUserAttributeKey, confirmationCode: String,