Skip to content

Commit 1f3d7ec

Browse files
authored
chore: kickoff release
2 parents 5196927 + 447f529 commit 1f3d7ec

File tree

103 files changed

+7666
-191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+7666
-191
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,5 @@ GraphQLModelBasedTests-amplifyconfiguration.json
8686
GraphQLWithIAMIntegrationTests-amplifyconfiguration.json
8787
GraphQLWithIAMIntegrationTests-credentials.json
8888

89-
AWSDataStoreCategoryPluginIntegrationTests-amplifyconfiguration.json
89+
AWSDataStoreCategoryPluginIntegrationTests-amplifyconfiguration.json
90+
*.code-workspace

Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,16 @@ extension AuthCategory: AuthCategoryBehavior {
7474
) async throws {
7575
try await plugin.confirmResetPassword(for: username, with: newPassword, confirmationCode: confirmationCode, options: options)
7676
}
77+
78+
public func setUpTOTP() async throws -> TOTPSetupDetails {
79+
try await plugin.setUpTOTP()
80+
}
81+
82+
public func verifyTOTPSetup(
83+
code: String,
84+
options: VerifyTOTPSetupRequest.Options? = nil
85+
) async throws {
86+
try await plugin.verifyTOTPSetup(code: code, options: options)
87+
}
88+
7789
}

Amplify/Categories/Auth/AuthCategoryBehavior.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,25 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi
124124
/// - options: Parameters specific to plugin behavior
125125
func confirmResetPassword(for username: String, with newPassword: String, confirmationCode: String, options: AuthConfirmResetPasswordRequest.Options?) async throws
126126

127+
/// Initiates TOTP Setup
128+
///
129+
/// Invoke this operation to setup TOTP for the user while signed in.
130+
/// Calling this method will initiate TOTP setup process and returns a shared secret that can be used to generate QR code.
131+
/// The setup details also contains a URI generator helper that can be used to retireve a TOTP Setup URI.
132+
///
133+
func setUpTOTP() async throws -> TOTPSetupDetails
134+
135+
/// Verifies TOTP Setup
136+
///
137+
/// Invoke this operation to verify TOTP setup for the user while signed in.
138+
/// Calling this method with the verification code from the associated Authenticator app will complete the TOTP setup process.
139+
///
140+
/// - Parameters:
141+
/// - code: verification code from the associated Authenticator app
142+
/// - options: Parameters specific to plugin behavior
143+
func verifyTOTPSetup(
144+
code: String,
145+
options: VerifyTOTPSetupRequest.Options?
146+
) async throws
147+
127148
}

Amplify/Categories/Auth/Models/AuthSignInStep.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8+
/// Set of allowed MFA types that would be used for continuing sign in during MFA selection step
9+
public typealias AllowedMFATypes = Set<MFAType>
10+
811
/// Auth SignIn flow steps
912
///
1013
///
@@ -23,6 +26,19 @@ public enum AuthSignInStep {
2326
///
2427
case confirmSignInWithNewPassword(AdditionalInfo?)
2528

29+
/// Auth step is TOTP multi factor authentication.
30+
///
31+
/// Confirmation code for the MFA will be retrieved from the associated Authenticator app
32+
case confirmSignInWithTOTPCode
33+
34+
/// Auth step is for continuing sign in by setting up TOTP multi factor authentication.
35+
///
36+
case continueSignInWithTOTPSetup(TOTPSetupDetails)
37+
38+
/// Auth step is for continuing sign in by selecting multi factor authentication type
39+
///
40+
case continueSignInWithMFASelection(AllowedMFATypes)
41+
2642
/// Auth step required the user to change their password.
2743
///
2844
case resetPassword(AdditionalInfo?)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
public enum MFAType: String {
9+
10+
/// Short Messaging Service linked with a phone number
11+
case sms
12+
13+
/// Time-based One Time Password linked with an authenticator app
14+
case totp
15+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
public struct TOTPSetupDetails {
11+
12+
/// Secret code returned by the service to help setting up TOTP
13+
public let sharedSecret: String
14+
15+
/// username that will be used to construct the URI
16+
public let username: String
17+
18+
public init(sharedSecret: String, username: String) {
19+
self.sharedSecret = sharedSecret
20+
self.username = username
21+
}
22+
/// Returns a TOTP setup URI that can help the customers avoid barcode scanning and use native password manager to handle TOTP association
23+
/// Example: On iOS and MacOS, URI will redirect to associated Password Manager for the platform
24+
///
25+
/// throws AuthError.validation if a `URL` cannot be formed with the supplied parameters
26+
/// (for example, if the parameter string contains characters that are illegal in a URL, or is an empty string).
27+
public func getSetupURI(
28+
appName: String,
29+
accountName: String? = nil) throws -> URL {
30+
guard let URL = URL(
31+
string: "otpauth://totp/\(appName):\(accountName ?? username)?secret=\(sharedSecret)&issuer=\(appName)") else {
32+
33+
throw AuthError.validation(
34+
"appName or accountName",
35+
"Invalid Parameters. Cannot form URL from the supplied appName or accountName",
36+
"Please make sure that the supplied parameters don't contain any characters that are illegal in a URL or is an empty String",
37+
nil)
38+
}
39+
return URL
40+
}
41+
42+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Request to verify TOTP setup
11+
public struct VerifyTOTPSetupRequest: AmplifyOperationRequest {
12+
13+
/// Code from the associated Authenticator app that will be used for verification
14+
public var code: String
15+
16+
/// Extra request options defined in `VerifyTOTPSetupRequest.Options`
17+
public var options: Options
18+
19+
public init(
20+
code: String,
21+
options: Options) {
22+
self.code = code
23+
self.options = options
24+
}
25+
}
26+
27+
public extension VerifyTOTPSetupRequest {
28+
29+
struct Options {
30+
31+
/// Extra plugin specific options, only used in special circumstances when the existing options do not provide
32+
/// a way to utilize the underlying auth plugin functionality. See plugin documentation for expected
33+
/// key/values
34+
public let pluginOptions: Any?
35+
36+
public init(pluginOptions: Any? = nil) {
37+
self.pluginOptions = pluginOptions
38+
}
39+
}
40+
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/AWSCognitoAuthPlugin+Configure.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import Amplify
1111
import AWSCognitoIdentity
1212
import AWSCognitoIdentityProvider
1313
import AWSPluginsCore
14-
1514
import ClientRuntime
1615

1716
extension AWSCognitoAuthPlugin {

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/AWSCognitoAuthPlugin+EscapeHatch.swift

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,6 @@ import AWSCognitoIdentityProvider
1212

1313
public extension AWSCognitoAuthPlugin {
1414

15-
func federateToIdentityPool(
16-
withProviderToken: String,
17-
for provider: AuthProvider,
18-
options: AuthFederateToIdentityPoolRequest.Options? = nil
19-
) async throws -> FederateToIdentityPoolResult {
20-
21-
let options = options ?? AuthFederateToIdentityPoolRequest.Options()
22-
let request = AuthFederateToIdentityPoolRequest(token: withProviderToken, provider: provider, options: options)
23-
let task = AWSAuthFederateToIdentityPoolTask(request, authStateMachine: authStateMachine)
24-
return try await task.value
25-
26-
}
27-
28-
func clearFederationToIdentityPool(options: AuthClearFederationToIdentityPoolRequest.Options? = nil) async throws {
29-
let options = options ?? AuthClearFederationToIdentityPoolRequest.Options()
30-
let request = AuthClearFederationToIdentityPoolRequest(options: options)
31-
let task = AWSAuthClearFederationToIdentityPoolTask(request, authStateMachine: authStateMachine)
32-
try await task.value
33-
}
34-
3515
func getEscapeHatch() -> AWSCognitoAuthService {
3616
var service: AWSCognitoAuthService?
3717
switch authConfiguration {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Amplify
9+
import AWSCognitoIdentity
10+
import AWSCognitoIdentityProvider
11+
12+
public extension AWSCognitoAuthPlugin {
13+
14+
func federateToIdentityPool(
15+
withProviderToken: String,
16+
for provider: AuthProvider,
17+
options: AuthFederateToIdentityPoolRequest.Options? = nil
18+
) async throws -> FederateToIdentityPoolResult {
19+
20+
let options = options ?? AuthFederateToIdentityPoolRequest.Options()
21+
let request = AuthFederateToIdentityPoolRequest(token: withProviderToken, provider: provider, options: options)
22+
let task = AWSAuthFederateToIdentityPoolTask(request, authStateMachine: authStateMachine)
23+
return try await task.value
24+
25+
}
26+
27+
func clearFederationToIdentityPool(
28+
options: AuthClearFederationToIdentityPoolRequest.Options? = nil
29+
) async throws {
30+
let options = options ?? AuthClearFederationToIdentityPoolRequest.Options()
31+
let request = AuthClearFederationToIdentityPoolRequest(options: options)
32+
let task = AWSAuthClearFederationToIdentityPoolTask(request, authStateMachine: authStateMachine)
33+
try await task.value
34+
}
35+
36+
func fetchMFAPreference() async throws -> UserMFAPreference {
37+
let task = FetchMFAPreferenceTask(
38+
authStateMachine: authStateMachine,
39+
userPoolFactory: authEnvironment.cognitoUserPoolFactory)
40+
return try await task.value
41+
}
42+
43+
func updateMFAPreference(
44+
sms: MFAPreference?,
45+
totp: MFAPreference?
46+
) async throws {
47+
let task = UpdateMFAPreferenceTask(
48+
smsPreference: sms,
49+
totpPreference: totp,
50+
authStateMachine: authStateMachine,
51+
userPoolFactory: authEnvironment.cognitoUserPoolFactory)
52+
return try await task.value
53+
}
54+
55+
}

0 commit comments

Comments
 (0)