Skip to content

Commit

Permalink
chore: kickoff release
Browse files Browse the repository at this point in the history
  • Loading branch information
ruisebas authored Aug 28, 2023
2 parents 5196927 + 447f529 commit 1f3d7ec
Show file tree
Hide file tree
Showing 103 changed files with 7,666 additions and 191 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ GraphQLModelBasedTests-amplifyconfiguration.json
GraphQLWithIAMIntegrationTests-amplifyconfiguration.json
GraphQLWithIAMIntegrationTests-credentials.json

AWSDataStoreCategoryPluginIntegrationTests-amplifyconfiguration.json
AWSDataStoreCategoryPluginIntegrationTests-amplifyconfiguration.json
*.code-workspace
12 changes: 12 additions & 0 deletions Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,16 @@ extension AuthCategory: AuthCategoryBehavior {
) async throws {
try await plugin.confirmResetPassword(for: username, with: newPassword, confirmationCode: confirmationCode, options: options)
}

public func setUpTOTP() async throws -> TOTPSetupDetails {
try await plugin.setUpTOTP()
}

public func verifyTOTPSetup(
code: String,
options: VerifyTOTPSetupRequest.Options? = nil
) async throws {
try await plugin.verifyTOTPSetup(code: code, options: options)
}

}
21 changes: 21 additions & 0 deletions Amplify/Categories/Auth/AuthCategoryBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,25 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi
/// - options: Parameters specific to plugin behavior
func confirmResetPassword(for username: String, with newPassword: String, confirmationCode: String, options: AuthConfirmResetPasswordRequest.Options?) async throws

/// Initiates TOTP Setup
///
/// Invoke this operation to setup TOTP for the user while signed in.
/// Calling this method will initiate TOTP setup process and returns a shared secret that can be used to generate QR code.
/// The setup details also contains a URI generator helper that can be used to retireve a TOTP Setup URI.
///
func setUpTOTP() async throws -> TOTPSetupDetails

/// Verifies TOTP Setup
///
/// Invoke this operation to verify TOTP setup for the user while signed in.
/// Calling this method with the verification code from the associated Authenticator app will complete the TOTP setup process.
///
/// - Parameters:
/// - code: verification code from the associated Authenticator app
/// - options: Parameters specific to plugin behavior
func verifyTOTPSetup(
code: String,
options: VerifyTOTPSetupRequest.Options?
) async throws

}
16 changes: 16 additions & 0 deletions Amplify/Categories/Auth/Models/AuthSignInStep.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// SPDX-License-Identifier: Apache-2.0
//

/// Set of allowed MFA types that would be used for continuing sign in during MFA selection step
public typealias AllowedMFATypes = Set<MFAType>

/// Auth SignIn flow steps
///
///
Expand All @@ -23,6 +26,19 @@ public enum AuthSignInStep {
///
case confirmSignInWithNewPassword(AdditionalInfo?)

/// Auth step is TOTP multi factor authentication.
///
/// Confirmation code for the MFA will be retrieved from the associated Authenticator app
case confirmSignInWithTOTPCode

/// Auth step is for continuing sign in by setting up TOTP multi factor authentication.
///
case continueSignInWithTOTPSetup(TOTPSetupDetails)

/// Auth step is for continuing sign in by selecting multi factor authentication type
///
case continueSignInWithMFASelection(AllowedMFATypes)

/// Auth step required the user to change their password.
///
case resetPassword(AdditionalInfo?)
Expand Down
15 changes: 15 additions & 0 deletions Amplify/Categories/Auth/Models/MFAType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

public enum MFAType: String {

/// Short Messaging Service linked with a phone number
case sms

/// Time-based One Time Password linked with an authenticator app
case totp
}
42 changes: 42 additions & 0 deletions Amplify/Categories/Auth/Models/TOTPSetupDetails.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Foundation

public struct TOTPSetupDetails {

/// Secret code returned by the service to help setting up TOTP
public let sharedSecret: String

/// username that will be used to construct the URI
public let username: String

public init(sharedSecret: String, username: String) {
self.sharedSecret = sharedSecret
self.username = username
}
/// Returns a TOTP setup URI that can help the customers avoid barcode scanning and use native password manager to handle TOTP association
/// Example: On iOS and MacOS, URI will redirect to associated Password Manager for the platform
///
/// throws AuthError.validation if a `URL` cannot be formed with the supplied parameters
/// (for example, if the parameter string contains characters that are illegal in a URL, or is an empty string).
public func getSetupURI(
appName: String,
accountName: String? = nil) throws -> URL {
guard let URL = URL(
string: "otpauth://totp/\(appName):\(accountName ?? username)?secret=\(sharedSecret)&issuer=\(appName)") else {

throw AuthError.validation(
"appName or accountName",
"Invalid Parameters. Cannot form URL from the supplied appName or accountName",
"Please make sure that the supplied parameters don't contain any characters that are illegal in a URL or is an empty String",
nil)
}
return URL
}

}
40 changes: 40 additions & 0 deletions Amplify/Categories/Auth/Request/VerifyTOTPSetupRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Foundation

/// Request to verify TOTP setup
public struct VerifyTOTPSetupRequest: AmplifyOperationRequest {

/// Code from the associated Authenticator app that will be used for verification
public var code: String

/// Extra request options defined in `VerifyTOTPSetupRequest.Options`
public var options: Options

public init(
code: String,
options: Options) {
self.code = code
self.options = options
}
}

public extension VerifyTOTPSetupRequest {

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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Amplify
import AWSCognitoIdentity
import AWSCognitoIdentityProvider
import AWSPluginsCore

import ClientRuntime

extension AWSCognitoAuthPlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,6 @@ import AWSCognitoIdentityProvider

public extension AWSCognitoAuthPlugin {

func federateToIdentityPool(
withProviderToken: String,
for provider: AuthProvider,
options: AuthFederateToIdentityPoolRequest.Options? = nil
) async throws -> FederateToIdentityPoolResult {

let options = options ?? AuthFederateToIdentityPoolRequest.Options()
let request = AuthFederateToIdentityPoolRequest(token: withProviderToken, provider: provider, options: options)
let task = AWSAuthFederateToIdentityPoolTask(request, authStateMachine: authStateMachine)
return try await task.value

}

func clearFederationToIdentityPool(options: AuthClearFederationToIdentityPoolRequest.Options? = nil) async throws {
let options = options ?? AuthClearFederationToIdentityPoolRequest.Options()
let request = AuthClearFederationToIdentityPoolRequest(options: options)
let task = AWSAuthClearFederationToIdentityPoolTask(request, authStateMachine: authStateMachine)
try await task.value
}

func getEscapeHatch() -> AWSCognitoAuthService {
var service: AWSCognitoAuthService?
switch authConfiguration {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
import AWSCognitoIdentity
import AWSCognitoIdentityProvider

public extension AWSCognitoAuthPlugin {

func federateToIdentityPool(
withProviderToken: String,
for provider: AuthProvider,
options: AuthFederateToIdentityPoolRequest.Options? = nil
) async throws -> FederateToIdentityPoolResult {

let options = options ?? AuthFederateToIdentityPoolRequest.Options()
let request = AuthFederateToIdentityPoolRequest(token: withProviderToken, provider: provider, options: options)
let task = AWSAuthFederateToIdentityPoolTask(request, authStateMachine: authStateMachine)
return try await task.value

}

func clearFederationToIdentityPool(
options: AuthClearFederationToIdentityPoolRequest.Options? = nil
) async throws {
let options = options ?? AuthClearFederationToIdentityPoolRequest.Options()
let request = AuthClearFederationToIdentityPoolRequest(options: options)
let task = AWSAuthClearFederationToIdentityPoolTask(request, authStateMachine: authStateMachine)
try await task.value
}

func fetchMFAPreference() async throws -> UserMFAPreference {
let task = FetchMFAPreferenceTask(
authStateMachine: authStateMachine,
userPoolFactory: authEnvironment.cognitoUserPoolFactory)
return try await task.value
}

func updateMFAPreference(
sms: MFAPreference?,
totp: MFAPreference?
) async throws {
let task = UpdateMFAPreferenceTask(
smsPreference: sms,
totpPreference: totp,
authStateMachine: authStateMachine,
userPoolFactory: authEnvironment.cognitoUserPoolFactory)
return try await task.value
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ protocol AWSCognitoAuthPluginBehavior: AuthCategoryPlugin {
///
/// - Parameters:
/// - options: Parameters specific to plugin behavior.
func clearFederationToIdentityPool(options: AuthClearFederationToIdentityPoolRequest.Options?) async throws
func clearFederationToIdentityPool(
options: AuthClearFederationToIdentityPoolRequest.Options?
) async throws

/// Fetches users MFA preferences
///
func fetchMFAPreference() async throws -> UserMFAPreference

/// Updates users MFA preferences
///
/// - Parameters:
/// - sms: The preference that needs to be updated for SMS
/// - totp: The preference that needs to be updated for TOTP
func updateMFAPreference(
sms: MFAPreference?,
totp: MFAPreference?
) async throws
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,12 @@ struct InitiateAuthDeviceSRP: Action {
func parseResponse(
_ response: SignInResponseBehavior,
with stateData: SRPStateData) -> StateMachineEvent {

if let challengeName = response.challengeName {
switch challengeName {
case .devicePasswordVerifier:
return SignInEvent(eventType: .respondDevicePasswordVerifier(stateData, response))
default:
let message = "Unsupported challenge response during DeviceSRPAuth \(challengeName)"
let error = SignInError.unknown(message: message)
return SignInEvent(eventType: .throwAuthError(error))
}
} else {
let message = "Response did not contain challenge info"
let error = SignInError.invalidServiceResponse(message: message)
guard case .devicePasswordVerifier = response.challengeName else {
let message = "Unsupported challenge response during DeviceSRPAuth \(response.challengeName ?? .sdkUnknown("Response did not contain challenge info"))"
let error = SignInError.unknown(message: message)
return SignInEvent(eventType: .throwAuthError(error))
}
return SignInEvent(eventType: .respondDevicePasswordVerifier(stateData, response))
}

}
Expand Down
Loading

0 comments on commit 1f3d7ec

Please sign in to comment.