Skip to content

Commit 44ad12b

Browse files
committed
feat(Auth): provide AuthConfiguration from plugin
1 parent 7d9640a commit 44ad12b

File tree

10 files changed

+200
-11
lines changed

10 files changed

+200
-11
lines changed

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/AWSCognitoAuthPlugin.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ public final class AWSCognitoAuthPlugin: AWSCognitoAuthPluginBehavior {
2121
var queue: OperationQueue!
2222

2323
/// Configuration for the auth plugin
24-
var authConfiguration: AuthConfiguration!
24+
@_spi(InternalAmplifyConfiguration)
25+
internal(set) public var authConfiguration: AuthConfiguration!
2526

2627
/// Handles different auth event send through hub
2728
var hubEventHandler: AuthHubEventBehavior!
@@ -35,6 +36,7 @@ public final class AWSCognitoAuthPlugin: AWSCognitoAuthPluginBehavior {
3536
/// The user network preferences for timeout and retry
3637
let networkPreferences: AWSCognitoNetworkPreferences?
3738

39+
@available(*, deprecated, message: "Use `authConfiguration`")
3840
@_spi(InternalAmplifyConfiguration)
3941
internal(set) public var jsonConfiguration: JSONValue?
4042

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/AuthConfiguration.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
enum AuthConfiguration {
10+
public enum AuthConfiguration {
1111
case userPools(UserPoolConfigurationData)
1212
case identityPools(IdentityPoolConfigurationData)
1313
case userPoolsAndIdentityPools(UserPoolConfigurationData, IdentityPoolConfigurationData)
@@ -21,7 +21,7 @@ extension AuthConfiguration: Codable {
2121
case identityPools
2222
}
2323

24-
func encode(to encoder: Encoder) throws {
24+
public func encode(to encoder: Encoder) throws {
2525
var container = encoder.container(keyedBy: CodingKeys.self)
2626

2727
switch self {
@@ -35,7 +35,7 @@ extension AuthConfiguration: Codable {
3535
}
3636
}
3737

38-
init(from decoder: Decoder) throws {
38+
public init(from decoder: Decoder) throws {
3939
let values = try decoder.container(keyedBy: CodingKeys.self)
4040

4141
let userConfigData = try? values.decode(UserPoolConfigurationData.self, forKey: .userPools)

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/IdentityPoolConfigurationData.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
struct IdentityPoolConfigurationData: Equatable {
10+
public struct IdentityPoolConfigurationData: Equatable {
1111
let poolId: String
1212
let region: String
1313

@@ -25,7 +25,7 @@ extension IdentityPoolConfigurationData: CustomDebugDictionaryConvertible {
2525
}
2626

2727
extension IdentityPoolConfigurationData: CustomDebugStringConvertible {
28-
var debugDescription: String {
28+
public var debugDescription: String {
2929
debugDictionary.debugDescription
3030
}
3131
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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+
import Amplify
10+
11+
@_spi(InternalAmplifyConfiguration)
12+
public struct PasswordProtectionSettings: Equatable, Codable {
13+
public var minLength: Int?
14+
public var characterPolicy: [PasswordCharacterPolicy]
15+
16+
public init(minLength: Int?,
17+
characterPolicy: [PasswordCharacterPolicy]) {
18+
self.minLength = minLength
19+
self.characterPolicy = characterPolicy
20+
}
21+
}
22+
23+
@_spi(InternalAmplifyConfiguration)
24+
public enum PasswordCharacterPolicy: String, Codable {
25+
case lowercase = "REQUIRES_LOWERCASE"
26+
case uppercase = "REQUIRES_UPPERCASE"
27+
case numbers = "REQUIRES_NUMBERS"
28+
case symbols = "REQUIRES_SYMBOLS"
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
@_spi(InternalAmplifyConfiguration)
11+
public enum SignUpAttributeType: String, Codable {
12+
case address = "ADDRESS"
13+
case birthDate = "BIRTHDATE"
14+
case email = "EMAIL"
15+
case familyName = "FAMILY_NAME"
16+
case gender = "GENDER"
17+
case givenName = "GIVEN_NAME"
18+
case middleName = "MIDDLE_NAME"
19+
case name = "NAME"
20+
case nickname = "NICKNAME"
21+
case phoneNumber = "PHONE_NUMBER"
22+
case preferredUsername = "PREFERRED_USERNAME"
23+
case profile = "PROFILE"
24+
case website = "WEBSITE"
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
import Amplify
10+
11+
@_spi(InternalAmplifyConfiguration)
12+
public enum UsernameAttribute: String, Codable {
13+
case username = "USERNAME"
14+
case email = "EMAIL"
15+
case phoneNumber = "PHONE_NUMBER"
16+
17+
public init?(from authUserAttributeKey: AuthUserAttributeKey) {
18+
switch authUserAttributeKey {
19+
case .email:
20+
self = .email
21+
case .phoneNumber:
22+
self = .phoneNumber
23+
default:
24+
return nil
25+
}
26+
}
27+
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/UserPoolConfigurationData.swift

+19-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import ClientRuntime
99

10-
struct UserPoolConfigurationData: Equatable {
10+
public struct UserPoolConfigurationData: Equatable {
1111

1212
let poolId: String
1313
let clientId: String
@@ -17,6 +17,14 @@ struct UserPoolConfigurationData: Equatable {
1717
let pinpointAppId: String?
1818
let hostedUIConfig: HostedUIConfigurationData?
1919
let authFlowType: AuthFlowType
20+
@_spi(InternalAmplifyConfiguration)
21+
public let passwordProtectionSettings: PasswordProtectionSettings?
22+
@_spi(InternalAmplifyConfiguration)
23+
public let usernameAttributes: [UsernameAttribute]
24+
@_spi(InternalAmplifyConfiguration)
25+
public let signUpAttributes: [SignUpAttributeType]
26+
@_spi(InternalAmplifyConfiguration)
27+
public let verificationMechanisms: [VerificationMechanism]
2028

2129
init(
2230
poolId: String,
@@ -26,7 +34,11 @@ struct UserPoolConfigurationData: Equatable {
2634
clientSecret: String? = nil,
2735
pinpointAppId: String? = nil,
2836
authFlowType: AuthFlowType = .userSRP,
29-
hostedUIConfig: HostedUIConfigurationData? = nil
37+
hostedUIConfig: HostedUIConfigurationData? = nil,
38+
passwordProtectionSettings: PasswordProtectionSettings? = nil,
39+
usernameAttributes: [UsernameAttribute] = [],
40+
signUpAttributes: [SignUpAttributeType] = [],
41+
verificationMechanisms: [VerificationMechanism] = []
3042
) {
3143
self.poolId = poolId
3244
self.clientId = clientId
@@ -36,6 +48,10 @@ struct UserPoolConfigurationData: Equatable {
3648
self.pinpointAppId = pinpointAppId
3749
self.hostedUIConfig = hostedUIConfig
3850
self.authFlowType = authFlowType
51+
self.passwordProtectionSettings = passwordProtectionSettings
52+
self.usernameAttributes = usernameAttributes
53+
self.signUpAttributes = signUpAttributes
54+
self.verificationMechanisms = verificationMechanisms
3955
}
4056

4157
/// Amazon Cognito user pool: cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>,
@@ -62,7 +78,7 @@ extension UserPoolConfigurationData: CustomDebugDictionaryConvertible {
6278
}
6379

6480
extension UserPoolConfigurationData: CustomDebugStringConvertible {
65-
var debugDescription: String {
81+
public var debugDescription: String {
6682
debugDictionary.debugDescription
6783
}
6884
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
@_spi(InternalAmplifyConfiguration)
11+
public enum VerificationMechanism: String, Codable {
12+
case email = "EMAIL"
13+
case phoneNumber = "PHONE_NUMBER"
14+
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Support/Helpers/ConfigurationHelper.swift

+77-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct ConfigurationHelper {
2323
return nil
2424
}
2525

26+
// parse `pinpointId`
2627
var pinpointId: String?
2728
if case .string(let pinpointIdFromConfig) = cognitoUserPoolJSON.value(at: "PinpointAppId") {
2829
pinpointId = pinpointIdFromConfig
@@ -44,6 +45,7 @@ struct ConfigurationHelper {
4445
return nil
4546
}()
4647

48+
// parse `authFlowType`
4749
var authFlowType: AuthFlowType
4850
if case .boolean(let isMigrationEnabled) = cognitoUserPoolJSON.value(at: "MigrationEnabled"),
4951
isMigrationEnabled == true {
@@ -56,22 +58,96 @@ struct ConfigurationHelper {
5658
authFlowType = .userSRP
5759
}
5860

61+
// parse `clientSecret`
5962
var clientSecret: String?
6063
if case .string(let clientSecretFromConfig) = cognitoUserPoolJSON.value(at: "AppClientSecret") {
6164
clientSecret = clientSecretFromConfig
6265
}
6366

67+
// parse `hostedUIConfig`
6468
let hostedUIConfig = parseHostedConfiguration(
6569
configuration: config.value(at: "Auth.Default.OAuth"))
6670

71+
// parse `passwordProtectionSettings`
72+
let cognitoConfiguration = config.value(at: "Auth.Default")
73+
var passwordProtectionSettings: PasswordProtectionSettings?
74+
if case .object(let passwordSettings) = cognitoConfiguration?.value(at: "passwordProtectionSettings") {
75+
76+
// parse `minLength`
77+
var minLength: Int?
78+
if case .number(let value) = passwordSettings["passwordPolicyMinLength"] {
79+
minLength = Int(value)
80+
} else if case .string(let value) = passwordSettings["passwordPolicyMinLength"],
81+
let intValue = Int(value) {
82+
minLength = intValue
83+
}
84+
85+
// parse `characterPolicy`
86+
var characterPolicy: [PasswordCharacterPolicy] = []
87+
if case .array(let characters) = passwordSettings["passwordPolicyCharacters"] {
88+
characterPolicy = characters.compactMap { value in
89+
guard case .string(let string) = value else {
90+
return nil
91+
}
92+
93+
return .init(rawValue: string)
94+
}
95+
}
96+
97+
passwordProtectionSettings = PasswordProtectionSettings(
98+
minLength: minLength,
99+
characterPolicy: characterPolicy
100+
)
101+
}
102+
103+
// parse `usernameAttributes`
104+
var usernameAttributes: [UsernameAttribute] = []
105+
if case .array(let attributes) = cognitoConfiguration?["usernameAttributes"] {
106+
usernameAttributes = attributes.compactMap { value in
107+
guard case .string(let string) = value else {
108+
return nil
109+
}
110+
111+
return .init(rawValue: string)
112+
}
113+
}
114+
115+
// parse `signUpAttributes`
116+
var signUpAttributes: [SignUpAttributeType] = []
117+
if case .array(let attributes) = cognitoConfiguration?["signupAttributes"] {
118+
signUpAttributes = attributes.compactMap { value in
119+
guard case .string(let string) = value else {
120+
return nil
121+
}
122+
123+
return .init(rawValue: string)
124+
}
125+
}
126+
127+
var verificationMechanisms: [VerificationMechanism] = []
128+
if case .array(let attributes) = cognitoConfiguration?["verificationMechanisms"] {
129+
verificationMechanisms = attributes.compactMap { value in
130+
guard case .string(let string) = value else {
131+
return nil
132+
}
133+
134+
return .init(rawValue: string)
135+
}
136+
}
137+
67138
return UserPoolConfigurationData(poolId: poolId,
68139
clientId: appClientId,
69140
region: region,
70141
endpoint: endpoint,
71142
clientSecret: clientSecret,
72143
pinpointAppId: pinpointId,
73144
authFlowType: authFlowType,
74-
hostedUIConfig: hostedUIConfig)
145+
hostedUIConfig: hostedUIConfig,
146+
passwordProtectionSettings: passwordProtectionSettings,
147+
usernameAttributes: usernameAttributes,
148+
signUpAttributes: signUpAttributes,
149+
verificationMechanisms: verificationMechanisms)
150+
75151
}
76152

77153
static func parseHostedConfiguration(configuration: JSONValue?) -> HostedUIConfigurationData? {

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignIn/AWSAuthSignInOptionsTestCase.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import XCTest
99
import AWSCognitoIdentity
1010
@testable import Amplify
11-
@testable import AWSCognitoAuthPlugin
11+
@_spi(InternalAmplifyConfiguration) @testable import AWSCognitoAuthPlugin
1212
import AWSCognitoIdentityProvider
1313
import ClientRuntime
1414

0 commit comments

Comments
 (0)