Okta-idx-swift - issue selecting a phone authenticator method

I’m working with the okta-idx-swift package and am running into issues selecting a phone factor. I’ve tried the sample code from the example/signin samples folder.

here is the sample below:

  func remediate(context: AuthenticationRemediationContext, completion: @escaping AuthenticationRemediationContext.StrategyResult) {
    guard let response = context.response,
          let remediation = response.remediations[.selectAuthenticatorAuthenticate] ?? response.remediations[.selectAuthenticatorEnroll],
          let authenticatorField: Remediation.Form.Field = remediation["authenticator"],
          let selectedFactor: Remediation.Form.Field = authenticatorField.options?.first(where: { field in
            field.authenticator?.type == factor
          }),
          let selectedMethod: Remediation.Form.Field = selectedFactor["methodType"]?.options?.first(where: { field in
            field.value as? String == method.stringValue
          })
    else {
      return completion(.failure(.factorNotFound))
    }
        
    selectedFactor["phoneNumber"]?.value = phonenumber
    authenticatorField.selectedOption = selectedMethod
    
    remediation.proceed {
      result in
      switch result {
      case .success(let response):
        completion(.success(response))
      case .failure:
        completion(.failure(.factorApiError))
      }
    }
  }

in this case the authenticator.kind is .phone and the selected method is .sms

However, this leads to this response:
{“version”:“1.0.0”,“messages”:{“type”:“array”,“value”:[{“message”:“The request body was not well-formed.”,“i18n”:{“key”:“E0000003”},“class”:“ERROR”}]}}

I’ve copied the request body that is send to the okta/idx/challenge endpoint:
{“stateHandle”:“[redacted]”,“authenticator”:“sms”}

With the okta-idx-java package, don’t have any issues getting through this flow, but there is a nice wrapper class that makes it a bit easier to work with.

I feel there is something I’m not setting correctly with the form prior to calling proceed. Any help or suggestions are appreciated.

Okay, so after reviewing the embedded auth example and debugging the form values during this step I found that I was grabbing the wrong remediation and was not going deep enough into the form to set the selected option of sms/voice

Here is the working solution in this case where the user was already enrolled in the phone factor:

func remediate(context: AuthenticationRemediationContext, completion: @escaping AuthenticationRemediationContext.StrategyResult) {
    guard let response = context.response else {
      return completion(.failure(.noContext))
    }
    
    guard let remediation = response.remediations[.authenticatorVerificationData],
          let authenticatorField = remediation["authenticator"],
          let methodTypeField = authenticatorField["methodType"],
          let selectedMethod = methodTypeField.options?.first(where: { field in
            field.value as? String == method.stringValue
          })
    else {
      return completion(.failure(.factorNotFound))
    }
            
    methodTypeField.selectedOption = selectedMethod
        
    remediation.proceed {
      result in
      switch result {
      case .success(let response):
        completion(.success(response))
      case .failure:
        completion(.failure(.factorApiError))
      }
    }
  }

If anyone runs into this issue, definitely debug through the embedded auth example app to see what the form looks like if you are not integrating the form data into your UI.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.