Skip to content

Commit

Permalink
@W-14662360/W-15061210: [iOS] Add additional native login feature(s):…
Browse files Browse the repository at this point in the history
… forgot password/(user registration) (#3728)
  • Loading branch information
JohnsonEricAtSalesforce authored Jun 21, 2024
1 parent 849ef81 commit 14df0e9
Show file tree
Hide file tree
Showing 3 changed files with 693 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//
// Created by Brandon Page on 1/3/24.
// Copyright (c) 2024-present, salesforce.com, inc. All rights reserved.
//
//
// Redistribution and use of this software in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice, this list of conditions
Expand All @@ -15,7 +15,7 @@
// * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written
// permission of salesforce.com, inc.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
Expand All @@ -26,12 +26,22 @@
// WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import Foundation

@objc public enum NativeLoginResult: Int {
case invalidUsername // Username does not meet Salesforce criteria (length, email format, ect).
case invalidPassword // Password does not meet the weakest Salesforce criteria.
case invalidCredentials // Username/password combination is incorrect.
/// Email address is not a valid format
case invalidEmail

/// Username does not meet Salesforce criteria (length, email format, ect)
case invalidUsername

/// Password does not meet the weakest Salesforce criteria
case invalidPassword

/// Username/password combination is incorrect
case invalidCredentials

case unknownError

case success
}

Expand Down Expand Up @@ -72,15 +82,96 @@ public protocol NativeLoginManager {
/// Note: this call will dismiss your login view controller.
@objc func biometricAuthenticationSuccess()

// MARK: Headless, Password-Less Login Via One-Time-Passcode
// MARK: Salesforce Identity API Headless Registration Flow

/// Submits a request to start a user registration to the Salesforce Identity API headless registration
/// flow. This fulfills step four of the headless registration flow.
///
/// See https://help.salesforce.com/s/articleView?id=sf.remoteaccess_headless_registration_public_clients.htm&type=5
///
/// - Parameters:
/// - email: The user-entered email address
/// - firstName: The user-entered first name
/// - lastName: The user-entered last name
/// - username: A valid Salesforce username or email
/// - newPassword: The user-entered new password
/// - reCaptchaToken: A reCAPTCHA token provided by the reCAPTCHA SDK
/// - otpVerificationMethod: The delivery method for the OTP
/// - Returns: The start registration result with the request identifier returned by the Salesforce
/// Identity API and a native login result indicating success or one of several possible failures,
/// including both in-app and Salesforce Identity API results
@objc func startRegistration(
email: String,
firstName: String,
lastName: String,
username: String,
newPassword: String,
reCaptchaToken: String,
otpVerificationMethod: OtpVerificationMethod
) async -> StartRegistrationResult

/// Submits a request to complete a user registration to the Salesforce Identity API headless
/// registration flow. This fulfills step eight of the headless registration flow.
///
/// See https://help.salesforce.com/s/articleView?id=sf.remoteaccess_headless_registration_public_clients.htm&type=5
///
/// - Parameters:
/// - otp: A user-entered one-time-password
/// - requestIdentifier: The request identifier issued by the Salesforce Identity API headless
/// registration flow in the start registration method
/// - otpVerificationMethod: The one-time-password verification method used to obtain the
/// OTP identifier
/// - Returns: A native login result indicating success or one of several possible failures, including
/// both in-app and Salesforce Identity API results
@objc func completeRegistration(
otp: String,
requestIdentifier: String,
otpVerificationMethod: OtpVerificationMethod
) async -> NativeLoginResult

// MARK: Salesforce Identity API Headless Forgot Password Flow

/// Submits a request to start a password reset to the Salesforce Identity API headless forgot password
/// flow. This fulfills step one of the headless forgot password flow.
///
/// See https://help.salesforce.com/s/articleView?id=sf.remoteaccess_headless_forgot_password_flow.htm&type=5
///
/// - Parameters:
/// - username: A valid Salesforce username or email
/// - reCaptchaToken: A reCAPTCHA token provided by the reCAPTCHA SDK
/// - Returns: A native login result indicating success or one of several possible failures, including
/// both in-app and Salesforce Identity API results
@objc func startPasswordReset(
username: String,
reCaptchaToken: String
) async -> NativeLoginResult

/// Submits a request to complete a password reset to the Salesforce Identity API headless forgot
/// password flow. This fulfills step four of the headless forgot password flow.
///
/// See https://help.salesforce.com/s/articleView?id=sf.remoteaccess_headless_forgot_password_flow.htm&type=5
///
/// - Parameters:
/// - username: A valid Salesforce username or email
/// - otp: A user-entered one-time-password
/// - newPassword: The user-entered new password
/// - Returns: A native login result indicating success or one of several possible failures, including
/// both in-app and Salesforce Identity API results
@objc func completePasswordReset(
username: String,
otp: String,
newPassword: String
) async -> NativeLoginResult

// MARK: Salesforce Identity API Headless, Password-Less Login Via One-Time-Passcode

/// Submits a request for a one-time-passcode to the Salesforce headless password-less login flow.
/// This fulfills step three of the headless password-less login flow.
/// Submits a request to start password-less login via one-time-passcode to the Salesforce Identity API
/// headless, password-less login flow. This fulfills step three of the headless, password-less login flow.
///
/// See https://help.salesforce.com/s/articleView?id=sf.remoteaccess_headless_passwordless_login_public_clients.htm&type=5
///
/// - Parameters:
/// - username: A valid Salesforce username. Note that email may be used for community users
/// - username: A valid Salesforce username or email
/// - reCaptchaToken: A reCAPTCHA token provided by the reCAPTCHA SDK
/// - otpVerificationMethod: The delivery method for the OTP
/// - Returns: An OTP request result with the overall login result and the OTP identifier for
Expand All @@ -91,16 +182,20 @@ public protocol NativeLoginManager {
reCaptchaToken: String,
otpVerificationMethod: OtpVerificationMethod) async -> OtpRequestResult

/// Submits a request for a one-time-passcode to the Salesforce headless password-less login flow.
/// This fulfills steps eight, eleven and thirteen of the headless password-less login flow.
/// Submits a request to complete a password-less login to the Salesforce Identity API headless,
/// password-less login flow. This fulfills steps eight, eleven and thirteen of the headless password-less
/// login flow.
///
/// See https://help.salesforce.com/s/articleView?id=sf.remoteaccess_headless_passwordless_login_public_clients.htm&type=5
///
/// - Parameters:
/// - otp: A user-entered OTP
/// - otpIdentifier: The OTP identifier issued by the Headless Identity API
/// - otpVerificationMethod: The OTP verification method used to obtain the OTP identifier
/// - Returns: A login result indicating the outcome of the authorization and access token requests
/// - otp: A user-entered one-time-password
/// - otpIdentifier: The one-time-password identifier issued by the Salesforce Identity API
/// headless, password-less login flow in the start password-less authorization method.
/// - otpVerificationMethod: The one-time-password verification method used to obtain the
/// OTP identifier
/// - Returns: A native login result indicating success or one of several possible failures, including
/// both in-app and Salesforce Identity API results
///
@objc func submitPasswordlessAuthorizationRequest(
otp: String,
Expand All @@ -109,12 +204,41 @@ public protocol NativeLoginManager {
) async -> NativeLoginResult
}

// MARK: Salesforce Identity API Headless Registration Flow Data Types

/// An Objective-C compatible start registration result.
@objc(SFStartRegistrationResult)
@objcMembers
public class StartRegistrationResult: NSObject {

/// The overall result of the start registration request
public let nativeLoginResult: NativeLoginResult

/// On success result, the email address provided by the Salesforce Identity API
public let email: String?

/// On success result, the request identifier provided by the Salesforce Identity API
public let requestIdentifier: String?

init(
nativeLoginResult: NativeLoginResult,
email: String? = nil,
requestIdentifier: String? = nil
) {
self.nativeLoginResult = nativeLoginResult
self.email = email
self.requestIdentifier = requestIdentifier
}
}

// MARK: Salesforce Identity API Headless, Password-Less Login Via One-Time-Passcode Data Types

/// An Objective-C compatible OTP request result
@objc(SFOtpRequestResult)
@objcMembers
public class OtpRequestResult: NSObject {

/// The overall result of the OTP request.
/// The overall result of the OTP request
public let nativeLoginResult: NativeLoginResult

/// On success result, the OTP identifier provided by the API
Expand All @@ -129,6 +253,8 @@ public class OtpRequestResult: NSObject {
}
}

// MARK: Common Data Types

/// The possible OTP verification methods.
@objc public enum OtpVerificationMethod: Int {
case email
Expand Down
Loading

0 comments on commit 14df0e9

Please sign in to comment.