@@ -90,26 +90,59 @@ public class SignUpState: AuthenticatorBaseState {
9090 setBusy ( true )
9191 let cognitoConfiguration = authenticatorState. configuration
9292
93- var existingFields : Set < String > = [ ]
93+ var existingFields : Set < SignUpAttribute > = [ ]
9494 var inputs = signUpFields. compactMap { field -> Field ? in
95- guard !existingFields. contains ( field. rawValue ) else {
95+ guard !existingFields. contains ( field. attributeType ) else {
9696 log. warn ( " Skipping configuring field of type ' \( field. rawValue) ' because it was already present. " )
9797 return nil
9898 }
9999
100- existingFields. insert ( field. rawValue )
100+ existingFields. insert ( field. attributeType )
101101 return Field ( field: field)
102102 }
103+
104+ // Validate username attribute is present and required
105+ let usernameAttribute = cognitoConfiguration. usernameAttribute
106+ if existingFields. contains ( usernameAttribute. asSignUpAttribute) ,
107+ let usernameField = inputs. first ( where: { $0. field. attributeType == usernameAttribute. asSignUpAttribute } ) {
108+ if !usernameField. isRequired {
109+ log. verbose ( " Marking username attribute \( usernameAttribute. rawValue) as required " )
110+ usernameField. isRequired = true
111+ }
112+ } else {
113+ // Add username field at the top
114+ log. verbose ( " Adding missing username attribute \( usernameAttribute. rawValue) to Sign Up Fields " )
115+ inputs. insert ( . init( field: . signUpField( from: usernameAttribute) ) , at: 0 )
116+ existingFields. insert ( usernameAttribute. asSignUpAttribute)
117+ }
118+
119+ // Validate all required sign up attributes are present
120+ for attribute in cognitoConfiguration. signupAttributes {
121+ if existingFields. contains ( attribute. asSignUpAttribute) ,
122+ let field = inputs. first ( where: { $0. field. attributeType == attribute. asSignUpAttribute } ) {
123+ if !field. isRequired {
124+ log. verbose ( " Marking sign up attribute \( attribute. rawValue) as required " )
125+ field. isRequired = true
126+ }
127+ } else {
128+ log. verbose ( " Adding missing required sign up attribute \( attribute. rawValue) to Sign Up Fields " )
129+ inputs. append ( . init( field: . signUpField( from: attribute, isRequired: true ) ) )
130+ existingFields. insert ( attribute. asSignUpAttribute)
131+ }
132+ }
103133
134+ // Validate all verification attributes are present
104135 for attribute in cognitoConfiguration. verificationMechanisms {
105- if let index = inputs. firstIndex ( where: { $0. field. attributeType == attribute. asSignUpAttribute } ) {
106- if !inputs[ index] . field. isRequired {
136+ if existingFields. contains ( attribute. asSignUpAttribute) ,
137+ let field = inputs. first ( where: { $0. field. attributeType == attribute. asSignUpAttribute } ) {
138+ if !field. isRequired {
107139 log. verbose ( " Marking verification attribute \( attribute. rawValue) as required " )
108- inputs [ index ] = Field ( field: . signUpField ( from : attribute ) )
140+ field. isRequired = true
109141 }
110142 } else {
111143 log. verbose ( " Adding missing verification attribute \( attribute. rawValue) to Sign Up Fields " )
112- inputs. append ( Field ( field: . signUpField( from: attribute) ) )
144+ inputs. append ( . init( field: . signUpField( from: attribute) ) )
145+ existingFields. insert ( attribute. asSignUpAttribute)
113146 }
114147 }
115148 self . fields = inputs
@@ -126,26 +159,22 @@ public class SignUpState: AuthenticatorBaseState {
126159 . confirmPassword( )
127160 ]
128161
162+ var existingFields : Set < SignUpAttribute > = [ ]
129163 for field in initialSignUpFields {
130164 fields. append ( . init( field: field) )
165+ existingFields. insert ( field. attributeType)
131166 }
132167
133- for attribute in cognitoConfiguration. signupAttributes {
134- guard !fields. contains ( where: { $0. field. attributeType == attribute. asSignUpAttribute } ) else {
135- continue
136- }
137-
138- let isVerificationAttribute = cognitoConfiguration. verificationMechanisms. contains {
139- $0. rawValue == attribute. rawValue
140- }
141- let field : SignUpField = . signUpField( from: attribute, isRequired: isVerificationAttribute)
142- fields. append ( Field ( field: field) )
168+ // Add all required sign up attributes
169+ for attribute in cognitoConfiguration. signupAttributes where !existingFields. contains ( attribute. asSignUpAttribute) {
170+ fields. append ( . init( field: . signUpField( from: attribute, isRequired: true ) ) )
171+ existingFields. insert ( attribute. asSignUpAttribute)
143172 }
144173
145- for attribute in cognitoConfiguration . verificationMechanisms {
146- if ! ( fields . contains { $0 . field . attributeType == attribute. asSignUpAttribute } ) {
147- fields. append ( Field ( field: . signUpField( from: attribute) ) )
148- }
174+ // Add all verification mechanisms that might not be present
175+ for attribute in cognitoConfiguration . verificationMechanisms where !existingFields . contains ( attribute. asSignUpAttribute) {
176+ fields. append ( . init ( field: . signUpField( from: attribute) ) )
177+ existingFields . insert ( attribute . asSignUpAttribute )
149178 }
150179
151180 setBusy ( false )
@@ -155,7 +184,7 @@ public class SignUpState: AuthenticatorBaseState {
155184public extension SignUpState {
156185 /// Represents a pair between a `SignUpField` and the value that is provided by the user
157186 class Field : ObservableObject , Hashable {
158- public let field : SignUpField
187+ private ( set ) public var field : SignUpField
159188 @Published public var value : String = " "
160189
161190 init ( field: SignUpField ) {
@@ -169,6 +198,25 @@ public extension SignUpState {
169198 public func hash( into hasher: inout Hasher ) {
170199 return hasher. combine ( field. attributeType)
171200 }
201+
202+ var isRequired : Bool {
203+ set {
204+ guard isRequired != newValue else { return }
205+ switch field {
206+ case var baseField as BaseSignUpField :
207+ baseField. isRequired = newValue
208+ field = baseField
209+ case var customField as CustomSignUpField :
210+ customField. isRequired = newValue
211+ field = customField
212+ default :
213+ log. error ( " Unsupported SignUpField of type \( type ( of: self ) ) cannot be mutated " )
214+ }
215+ }
216+ get {
217+ field. isRequired
218+ }
219+ }
172220 }
173221}
174222
0 commit comments