# addAccountRecoveryCallback URL: /sdk-ios/addAccountRecoveryCallback.html AppDelegate.reachfive().addAccountRecoveryCallback([recoveryCallback](#recoveryCallback)) ## Setup Before using this method, you need to setup deep link interception by using [application(\_:open:options)](application/applicationOpenUrl.html). ## About this command Add the callback that will be executed when the account recovery url is intercepted. Parse the link and extract the verification code. ## Examples You would typically call this method in the controller handling the UI for manually entering the verification code: ```swift import Reach5 import UIKit class RecoveryVerificationController: UIViewController { override func viewDidLoad() { AppDelegate.reachfive().addAccountRecoveryCallback { result in switch result { case .success(let response): let email = response.email let verificationCode = response.verificationCode // show UI for setting up a new passkey or choosing a new password case .failure(let error): // handle failure } } } } ``` ## Parameters ##### recoveryCallback AccountRecoveryCallback The callback that will be executed when the account recovery link is intercepted. The callback takes a `Result` with either an `AccountRecoveryResponse` or a `ReachFiveError`. ##### AccountRecoveryResponse When the url is properly parsed and the verification code is present. Contains the profile email `string` and the verification code `string`. ##### ReachFiveError When an error occured. --- # addPasswordlessCallback URL: /sdk-ios/addPasswordlessCallback.html AppDelegate.reachfive().addPasswordlessCallback([passwordlessCallback](#passwordlessCallback)) ## Setup Before using this method, you need to setup deep link interception by using [application(\_:open:options)](application/applicationOpenUrl.html). ## About this command Add the callback that will be executed when the magic link is intercepted. Parse the link and perform a code exchange for authentication. ## Examples You can call this method when the app is launched: ```swift import Reach5 @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { AppDelegate.reachfive().addPasswordlessCallback { result in switch (result) { case .success(let authToken): // Handle authToken case .failure(let error): // Handle error } } return true } } ``` ## Parameters ##### passwordlessCallback PasswordlessCallback The callback that will be executed when the magic link is intercepted. The callback takes a `Result` with either an `AuthToken` or a `ReachFiveError`. ##### AuthToken When the code exchange succeed and the user is authenticated. ##### ReachFiveError When an error occured. --- # beginAutoFillAssistedPasskeyLogin URL: /sdk-ios/beginAutoFillAssistedPasskeyLogin.html AppDelegate.reachfive().beginAutoFillAssistedPasskeyLogin([withRequest](#withRequest)) ## Description Logs the user in using a saved passkey. The passkey is shown in the QuickType bar when selecting a field with the Username content type. ## Usage Start the request automatically early in the view lifecycle (e.g., in `viewDidAppear`), alone, or in reaction to a modal request with display `IfImmediatelyAvailableCredentials` that resulted in an `.AuthCanceled`. ## Examples ```swift do { let authToken = try await AppDelegate.reachfive().beginAutoFillAssistedPasskeyLogin(withRequest: NativeLoginRequest(presenting: presenting)) // get auth token on success } catch { // return ReachFive error on failure } ``` ## Parameters ##### withRequest NativeLoginRequest Object containing parameters to send along with the request. Object parameters: - `presenting`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). - `originWebAuthn`: The origin of the webauthn call. Defaults to the `originWebAuthn` of your `SdkConfig`, or to `https://${domain}`. - `scopes`: The scopes granted to the profile. - `origin`: The origin of the call. This helps categorize inbound traffic. ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) This method returns the authorization token when successfully logged in or a Purse Identity error if unsuccessful. ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # deleteWebAuthnRegistration URL: /sdk-ios/deleteWebAuthnRegistration.html AppDelegate.reachfive().deleteWebAuthnRegistration([id](#webAuthnId),[authToken](#authToken)) ## Description Deletes a passkey the user has registered. ## Examples ```swift do { try await AppDelegate.reachfive().deleteWebAuthnRegistration(id: id, authToken: profileAuthToken) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### id The ID of the passkey. ## Response **Error**: [ReachFiveError](#reachfiveerror) ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # getProfile URL: /sdk-ios/getProfile.html AppDelegate.reachfive().getProfile([authToken](#authToken)) ## Description Retrieve the profile’s information. > - The profile must have been granted the `profile` scope at the last authentication otherwise the profile’s attributes are null. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { let profile = try await AppDelegate.reachfive().getProfile(authToken: profileAuthToken) // Get the profile } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response - **Type**: [Profile](#profile) - **Error**: [ReachFiveError](#reachfiveerror) It will return the fetched profile, otherwise you’ll get a `ReachFiveError`. ### Profile ##### id string The Purse Identity identifier of the profile. ##### givenName string The given name of the profile. ##### middleName string The middle name of the profile. ##### familyName string The family name of the profile. ##### name string The full name of the profile. ##### nickname string The nickname of the profile. ##### birthdate string The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### profileURL string The URL of one of the user’s profile page (usually a social provider’s page). ##### picture string The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### externalId string The external identifier of the profile. ##### authTypes String\[\] The list of the authentication providers used to login by the profile (e.g. facebook, password …​). ##### loginSummary LoginSummary The login activities history of the profile. ##### firstLogin string The time of the first login. ##### lastLogin string The time of the last login. ##### total string The number of login. ##### origins string Some additional information about the login. ##### devices string The devices used for login (`desktop`, `ios`, `android`, `mobile_web` and `windows_phone`). ##### lastProvider string The last provider used for login (e.g. `local`, `lite`, `facebook` …​). ##### username string The username of the profile (the login’s name). ##### gender string The gender of the profile. Allowed values are `female`, `male` and `other`. ##### email string The primary email address of the profile. ##### emailVerified boolean `true` if the profile’s e-mail address has been verified; otherwise `false`. ##### emails Emails The e-mail addresses of the profile. ##### verified string\[\] The list of the verified e-mail addresses of the profile. ##### unverified string\[\] The list of the unverified e-mail addresses of the profile. ##### phoneNumber string The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### addresses List of ProfileAddress The list of the profile’s postal addresses. To get this attribute, the profile must have been granted the `address` scope at the last authentication. ##### title string The title of the address. This value can’t be an empty string. ##### isDefault boolean Whether the address is the default postal address of the profile. Only a single address can be the default address. Defaults to `true`. ##### addressType string The type of address Allowed values: `delivery` or `billing`. ##### streetAddress string The full street address component which may include the house number, the street’s name and the extended street address information separated by newlines. This value can’t be an empty string. ##### addressComplement A complementary address field which can contain additional information about the address. ##### locality string The name of the city. ##### region string The name of the region. ##### postalCode string The zip code. ##### country string The name of the country. This value can’t be an empty string. ##### deliveryNote string An additional note from the profile for the delivery. ##### recipient string The name of the recipient located at this address. ##### company string The name of the company located at this address. ##### phoneNumber string The phone number of the contact point at this address (no format validation is required). ##### locale string The profile’s language code in lowercase and country code in uppercase, separated by a dash (e.g. `en`, `fr-FR` …​). ##### bio string The biography of the profile. ##### customFields Map The custom fields of the profile. [Structured custom fields](../docs/custom-fields.html) are only available using the full key for the field (e.g., `full.custom_field.key`). They are not supported as nested objects. ##### consents Map The consents granted to the profile. It is a map of string keys with the associated consent object. ##### granted boolean Whether the consent was granted to the profile or not. ##### consentType boolean The type of consent. Allowed values: `opt-in` `opt-out`. ##### date string The time the consent was last updated. ##### createdAt string The time the profile’s information was created. ##### updatedAt string The time the profile’s information was last updated. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # getProvider URL: /sdk-ios/getProvider.html AppDelegate.reachfive().getProvider([name](#name)) ## Description Retrieve a provider registered on the Purse Identity client by name. Refer at the iOS SDK Installation to initialize the providers at the client’s instantiation. > - The scopes provided are the permissions setup in the provider’s configuration through the console. > ## Usage For `.login`, pass the initiating [UIViewController](https://developer.apple.com/documentation/uikit/uiviewcontroller) wrapped in a `Presentation`: ```swift try await provider.login(scope: scope, origin: origin, presenting: Presentation(from: self)) ``` Each provider derives what it needs from it, depending on how it authenticates: - Web-based providers ([`WebProvider`](providerCreator.html), and any provider with no matching native creator, falling back to `DefaultProvider`) open an `ASWebAuthenticationSession` and need a presentation context. The SDK derives one from the view controller; if it already implements [`ASWebAuthenticationPresentationContextProviding`](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationpresentationcontextproviding), its own `presentationAnchor(for:)` keeps precedence. - `AppleProvider` needs the view controller to be attached to a window at call time. - Native SDK providers (`GoogleProvider`, `FacebookProvider`, `WeChat`) need only the view controller itself, or nothing at all. In every case, call `.login` from `viewDidAppear` or a user interaction, not from `viewDidLoad`, so the view controller is attached to a window. ## Examples ```swift import Reach5 let providerName: String = // Here paste the name of the provider let scope = ["openid", "email", "profile", "phone", "full_write", "offline_access"] do { if let provider = AppDelegate.reachfive().getProvider(name: providerName) { let authToken = try await provider.login( scope: scope, origin: "home", presenting: Presentation(from: self) ) // Get the profile's authentication token } } catch { // Return a ReachFive error } ``` ```swift import Reach5 let providerName: String = // Here paste the name of the provider do { if let provider = AppDelegate.reachfive().getProvider(name: providerName) { try await provider.logout() // Do something } } catch { // Return a ReachFive error } ``` ## Parameters ##### name string The name of the provider. possible values - `facebook` - `google` - `paypal` - `twitter` - `franceconnect` - `apple` - `oney` - `bconnect` - `line` ## Response **Type**: [Provider](#provider) ### Provider The provider which name matches the name passed in argument. ##### name string The name of the provider. possible values - `facebook` - `google` - `paypal` - `twitter` - `franceconnect` - `apple` - `oney` - `bconnect` - `line` ##### login function Expect the following arguments: - `scope` `[String]`: the list of the profile’s scopes. Make sure they are allowed by the client. Default scopes are the allowed scopes set up in the client’s configuration. - `origin` `String`: the origin of the call - `presenting` `Presentation`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). It authenticates the profile with the provider otherwise it returns a `ReachFiveError`. ##### logout function No argument is expected. Kill the SSO session of the profile otherwise returns a `ReachFiveError`. --- # getProviders URL: /sdk-ios/getProviders.html AppDelegate.reachfive().getProviders() ## Description Retrieve all the providers registered on the Purse Identity client. Refer at the iOS SDK Installation to initialize the providers at the client’s instantiation. > - The scopes provided are the permissions setup in the provider’s configuration through the console. > ## Examples ```swift import Reach5 let providers = AppDelegate.reachfive().getProviders() ``` ## Response **Type**: [Provider\[\]](#provider) ### Provider The provider which name matches the name passed in argument. ##### name string The name of the provider. possible values - `facebook` - `google` - `paypal` - `twitter` - `franceconnect` - `apple` - `oney` - `bconnect` - `line` ##### login function Expect the following arguments: - `scope` `[String]`: the list of the profile’s scopes. Make sure they are allowed by the client. Default scopes are the allowed scopes set up in the client’s configuration. - `origin` `String`: the origin of the call - `presenting` `Presentation`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). It authenticates the profile with the provider otherwise it returns a `ReachFiveError`. ##### logout function No argument is expected. Kill the SSO session of the profile otherwise returns a `ReachFiveError`. --- # Getting Started URL: /sdk-ios/index.html Breaking changes for `11.0.0`, please read. ## Breaking changes for `iOS 11.0.0` There are several updates with the `iOS 11.0.0` release that are considered breaking. Read the following for an overview of the changes, and follow the linked pages for the current API. ### `SdkConfig` - Redirect URL fields (`redirectUri`, `mfaUri`, `accountRecoveryUri`, `emailVerificationUri`) are now `URL` instead of `String`. - The `scheme` alias for `redirectUri` is removed. - `baseScheme` is renamed to `customScheme`. - The initializer stops the app with a `preconditionFailure` when the scheme, domain, redirect URLs, or `originWebAuthn` fail validation, instead of failing later during a network call. See [Configure the iOS SDK](#configure-the-ios-sdk). ### Passkey `originWebAuthn` A passkey request’s `originWebAuthn` is validated and normalized the same way as the `SdkConfig` value. The call can throw `ReachFiveError.TechnicalError` if validation fails. See [Customise the WebAuthn origin](#customise-the-webauthn-origin). ### App-lifecycle callbacks return `false` [`application(_:open:options:)_`](application/applicationOpenUrl.html) _and [`application(`](application/applicationContinueUserActivity.html)_[`:continue:restorationHandler:)`](application/applicationContinueUserActivity.html) now return `false` when neither the SDK nor a registered provider consumed the URL or activity. Previously they always returned `true`. > If your app also routes universal links or custom-scheme URLs, do so only when the call returns `false`. ### `ProviderCreator` and `Presentation` The `ProviderCreator` factory receives the `ReachFive` instance instead of sub-components, so it can reuse helpers such as `buildAuthorizeURL`, `authWithCode`, `webviewLogin`, and `login(withProvider:)`. See [Implement a custom provider](guides/custom-provider.html). `Provider.login` and native passkey requests take a `Presentation` instead of a `UIViewController?` or an `anchor: ASPresentationAnchor`. See [getProvider](getProvider.html) and [login(withRequest)](loginWithRequest.html) respectively. ### CocoaPods is dropped The core SDK and the Facebook and Google providers are only distributed with Swift Package Manager. `import Reach5` no longer brings `UIKit` or `Foundation` into scope. Add those imports where your files need them. See [Installation](#installation). ## Requirements The minimal iOS version of an application using the Purse Identity iOS SDKs has to be `13`. To initialize the Purse Identity client: - You need a [Domain URL and Client ID](../docs/console.html#get-domain). - You must whitelist all available domains where the Purse Identity SDK will be used. > This is done in the **Allowed Origins (CORS)** field of your Purse Identity console, in the **Settings** menu. ## iOS specific prerequisites - The [client](../docs/clients.html) must be a `First-party client` with `Token Endpoint Authentication Method` set to `None`. - You must have the schemes registered in `Allowed Callback URLs`. - You should enforce PKCE for security purposes and enable Refresh Tokens for convenience. For more on configuring a client, see [Set up a client](../docs/clients.html#configure-client-first). ## Installation Purse Identity SDKs are available with Swift Package Manager as independent modules. Only [WeChat Connect](#wechat-connect) still uses Cocoapods. > If you are migrating from CocoaPods, `import Reach5` no longer brings `UIKit` or `Foundation` into scope. Add an explicit `import UIKit` and `import Foundation` in each file that uses those types. > You can also find releases directly on the Purse Identity repo at [ReachFive iOS SDK](https://github.com/ReachFive/reachfive-ios/releases/). Below, you’ll find a description and instructions for installation for each module. - [SDK Core](#sdk-core) - [Facebook native provider](#facebook-native-provider) - [Google native provider](#google-native-provider) - [WeChat Connect](#wechat-connect) * * * ### SDK Core The core SDK contains all the main tools, interfaces, and methods related to standard authentication by identifier and password, passkey, passwordless, and so on. #### Installation Add the package dependency with XCode using this package URL: ```none https://github.com/ReachFive/reachfive-ios.git ``` Or directly add this to the dependencies in `Package.swift` ```swift dependencies: [ .package(url: "https://github.com/ReachFive/reachfive-ios.git", .upToNextMajor(from: "11.1.0")) ] ``` #### Configuration Configure your application’s `Info.plist` file with the following XML snippet: ```xml CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLSchemes reachfive-${clientId} ``` > See [Info.plist reference](#info-plist-reference) for a comprehensive look at the file. ### Facebook native provider This module uses the Facebook native SDK to provide a better user experience. > Refer to the [Meta Connect (Facebook Login)](../docs/facebook.html) guide to create your Facebook application. #### Installation Add the package dependency with XCode using this package URL: ```none https://github.com/ReachFive/reachfive-ios-facebook.git ``` Or directly add this to the dependencies in `Package.swift` ```swift dependencies: [ .package(url: "https://github.com/ReachFive/reachfive-ios-facebook.git", .upToNextMajor(from: "9.0.0")) ] ``` #### Configuration > If you’re using the latest version of the Facebook API, remove the `user_gender` scope from the Purse Identity client configuration to prevent any issues. 1. Configure the `Info.plist` file with the following XML snippet that contains data about your application: ```xml CFBundleURLTypes CFBundleURLSchemes fb$(YOUR_FACEBOOK_APPLICATION_ID) FacebookAppID $(YOUR_FACEBOOK_APPLICATION_ID) FacebookClientToken $(YOUR_FACEBOOK_CLIENT_TOKEN) FacebookDisplayName $(YOUR_APPLICATION_NAME) ``` 2. Then to use any of the Facebook dialogs (e.g., Login, Share, App Invites, etc.) that can perform an app switch to Facebook apps, include the following lines: ```xml LSApplicationQueriesSchemes fbauth2 (1) fbapi fb-messenger-share-api ``` - (1) Required for [Fast App Switch](#fast-app-switch), which `Reach5Facebook` supports from 9.0.0. > See [Info.plist reference](#info-plist-reference) for a comprehensive look at the file. #### Fast App Switch Fast App Switch sends the user to the native Facebook app to sign in instead of to a Safari view controller, so a user already signed in to the Facebook app does not have to sign in again. The `fbauth2` scheme lets the SDK open the Facebook app, and `fbapi` lets it detect that the app is installed. The `appSwitch` parameter is `.enabled` by default. Pass `appSwitch: .disabled` to [`FacebookProvider`](providerCreator.html#FacebookProvider) to always use the browser flow. Your login still completes through the browser flow in these cases: - The Facebook app is not installed, in which case the Facebook SDK falls back on its own. - Meta has not enabled Fast App Switch for your Facebook application, as the feature is controlled remotely, and classic and limited logins are gated separately. > You get a classic login only when you build the provider with `prefersLoginTracking: .enabled`, the default being `.limited`, and App Tracking Transparency is authorized on the device. Otherwise the SDK asks Facebook for a limited login. > > An app switch returns to your application through the `fb$(YOUR_FACEBOOK_APPLICATION_ID)` scheme you declared above. Forward [`application(_:open:options)`](application/applicationOpenUrl.html) to Purse Identity, and `scene(_:openURLContexts:)` too if your application uses scenes, otherwise the login never completes after the user approves in the Facebook app. ### Google native provider This module uses the Google native SDK to provide a better user experience. > Refer to the [Google Connect](../docs/google.html) guide to create your Google application. #### Installation Add the package dependency with XCode using this package URL: ```none https://github.com/ReachFive/reachfive-ios-google.git ``` Or directly add this to the dependencies in `Package.swift` ```swift dependencies: [ .package(url: "https://github.com/ReachFive/reachfive-ios-google.git", .upToNextMajor(from: "9.0.0")) ] ``` #### Configuration Configure the `Info.plist` file with the following XML snippet that contains data about your application: 1. Add your Google Client ID to the `Info.plist` file: ```xml GIDClientID GOOGLE_CLIENT_ID (1) ``` - (1) This is your Google Client ID in standard format. For example, `1234567890-abcdefg.apps.googleusercontent.com`. See [Info.plist reference](#info-plist-reference) for a comprehensive look at the file. 2. Add your reversed Google Client ID to the URL Scheme. ```xml CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLSchemes YOUR_REVERSED_GOOGLE_CLIENT_ID (1) ``` - (1) The URL Scheme is the reversed Google Client ID (not Purse Identity’s [clientID](../docs/clients.html)), which is your Google Client ID with the order of the dot-delimited fields reversed. For example, `com.googleusercontent.apps.abcdefg-1234567890`. See [Info.plist reference](#info-plist-reference) for a comprehensive look at the file. ### WeChat Connect As of 2026-10-30, WeChat is not yet available for our iOS SDK version 11.1.0. We will update this page accordingly when it is available. This module uses the WeChat native SDK to be able to interact with the WeChat app. #### Installation 1. Add this line to your `Podfile` file. ```none pod 'IdentitySdkWeChat', '~> 7.0.0' (1) ``` - (1) `7.0.0` is the latest version of SDK. 2. Then run: ```javascript pod install ``` Swift Package Manager is not yet supported. #### Configuration - Configure the `Info.plist` file with the following XML snippet that contains data about your application: ```xml LSApplicationQueriesSchemes weixin weixinULAPI weixinURLParamsAPI ``` > See [Info.plist reference](#info-plist-reference) for a comprehensive look at the file. ## Configure the iOS SDK You must configure the iOS SDK to use it. This is where you provide the values for your domain and client ID, and define which native library you want to integrate with for Social Login. By default, the URL scheme follows this pattern: `reachfive-${clientId}://callback`. There are multiple schemes. All **must be** whitelisted in Allowed Callback URLs on your Purse Identity Console. ##### reachfive-${clientId}://callback This callback URL is used to open the app from another app such as an email client or the web for passwordless. Other uses: - Switching from web context to app context in `webviewLogin` or some providers. - OAuth flow ##### reachfive-${clientId}://mfa This callback URL is used for MFA verification. Available from version `6.3.0`. ##### reachfive-${clientId}://account-recovery This callback URL is used for account recovery code verification. Available from version `7.0.0`. ##### reachfive-${clientId}://email-verification This callback URL is used to return to the app after email verification. Available from version `8.2.0`. ### Configuration ```swift let reachfive = ReachFive( // The configuration parameters required to initialize the ReachFive client sdkConfig: SdkConfig( (1) domain: DOMAIN, clientId: CLIENT_ID ), // The list of the social providers needed by the application providersCreators: [GoogleProvider(), FacebookProvider(), WeChatProvider()] (2) ) ``` - (1) Sets the required parameters such as `domain`, Purse Identity `clientId`, and the `customScheme`. - (2) Lists the social providers you need for your iOS application. For more details, see [providerCreator](providerCreator.html). #### Customise `scheme` You can also specify a scheme manually and customise schemes as shown here. ```swift let reachFive = ReachFive( sdkConfig: SdkConfig( domain: DOMAIN, clientId: CLIENT_ID, customScheme: "myOwnScheme", (1) redirectUri: URL(string: "myOwnScheme://myOwnRedirectPath")!, (2) mfaUri: URL(string: "myOwnScheme://myOwnMfaPath")!, (3) accountRecoveryUri: URL(string: "myOwnScheme://myOwnRecoveryPath")!, (4) emailVerificationUri: URL(string: "myOwnScheme://myOwnEmailVerificationPath")! (5) ) ) ``` - (1) The custom URL scheme. Pass the scheme only (no `://`); it replaces the default `reachfive-${clientId}`. Every callback URI that you don’t override explicitly is then derived from it (`myOwnScheme://callback`, `myOwnScheme://mfa`, and so on). - (2) Overrides the full default callback URI. - (3) Overrides the full MFA callback URI. - (4) Overrides the full account recovery callback URI. - (5) Overrides the full email verification callback URI. #### Associated Domains Passkeys and [`WebProvider`](providerCreator.html) `.universalLink` need an Associated Domain and a matching `apple-app-site-association` file. Associated domains also link your app to your website, so that credential managers can autofill passwords your users already saved for that website. See [apple-app-site-association](guides/apple-app-site-association.html). #### Customise the WebAuthn origin Passkey requests carry an origin, which defaults to `https://${domain}`. Set `originWebAuthn` when your passkeys are bound to another domain, such as a custom domain or one shared by several of your apps. Pass a full URL such as `https://auth.example.com`, not a bare host. > A value with no scheme, such as `auth.example.com`, is not a valid origin. `SdkConfig` stops the app at initialisation instead of falling back to your domain. You never set the Relying Party ID yourself. Purse Identity derives it from the origin’s host (`auth.example.com`) and returns it with each passkey request. Declare that same host in your Associated Domains and `apple-app-site-association` file, as described in [apple-app-site-association](guides/apple-app-site-association.html). Set the origin once in the `SdkConfig` rather than on every passkey request. A request that carries its own `originWebAuthn` still takes precedence over this value. > The origin you send must be allowed in the Purse Identity Console under **Settings**  **WebAuthn**, or the server rejects the passkey request. See [Allowed origins](guides/passkeys.html#allowed-origins). ```swift let reachFive = ReachFive( sdkConfig: SdkConfig( domain: DOMAIN, clientId: CLIENT_ID, originWebAuthn: URL(string: "https://auth.example.com")! (1) ) ) ``` - (1) Only the scheme, the host and a non-default port are sent: a path or a trailing slash is ignored. #### Customise storage Storage is used by the iOS SDK to store the PKCE code during passwordless and MFA flows. By default it uses the [UserDefaults storage](https://developer.apple.com/documentation/foundation/userdefaults), but it can be customised to be any object that implements our [`Storage` protocol](https://github.com/ReachFive/reachfive-ios/blob/master/Sources/Core/Classes/utils/Storage.swift). For an example of a custom implementation, see [Purse Identity-ios: Secure storage](https://github.com/ReachFive/reachfive-ios/blob/master/Sandbox/Sandbox/Utils/SecureStorage.swift) using the keychain. ```swift let reachFive = ReachFive( sdkConfig: SdkConfig( domain: DOMAIN, clientId: CLIENT_ID ), storage: UserDefaultsStorage() (1) ) ``` - (1) This value can be any object that implements our `Storage` protocol. ## Initialize iOS SDK You must initialize the iOS SDK to use it. Initializing the iOS SDK ensures the client configuration is properly fetched (which contains default scope) and native social providers are properly initialized. You initialize your iOS client with: ```swift reachfive.application(application, didFinishLaunchingWithOptions: launchOptions) ``` ### Full examples The full file examples below show you were to initialize the client as well as providing context for the overall configuration and initialization. ```swift import UIKit (1) import Reach5 class AppDelegate: UIResponder, UIApplicationDelegate { let DOMAIN = "Here paste your ReachFive domain" (2) let CLIENT_ID = "Here paste your ReachFive client ID" (3) let reachfive = ReachFive( // The configuration parameters required to initialize the ReachFive client sdkConfig: SdkConfig(domain: DOMAIN, clientId: CLIENT_ID) ) func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Initialize the ReachFive client return reachfive.application(application, didFinishLaunchingWithOptions: launchOptions) (4) } } ``` - (1) Import the UIKit if using it. If using another UI framework, you may not initialize provider configuration. - (2) Your Purse Identity domain, as a bare host such as `integ-sandbox.reach5.dev` — no `https://` prefix, no port and no trailing slash. - (3) The Purse Identity client such as `zhU43…​51nvOM`; - (4) Initializes the iOS SDK by fetching information from the server about the client. For more details, see [application(\_:didFinishLaunchingWithOptions:)](application/applicationDidFinishLaunchingWithOptions.html). ```swift import UIKit import Reach5 import Reach5Facebook import Reach5Google import Reach5WeChat class AppDelegate: UIResponder, UIApplicationDelegate { let DOMAIN = "Here paste your ReachFive domain" // e.g. integ-sandbox-squad2.reach5.dev, as a bare host — no https:// prefix, no port and no trailing slash let CLIENT_ID = "Here paste your ReachFive client ID" // e.g. zhU43aRKZtzps551nvOM let reachfive = ReachFive( // The configuration parameters required to initialize the ReachFive client sdkConfig: SdkConfig(domain: DOMAIN, clientId: CLIENT_ID), // The list of the social providers needed by the application providersCreators: [GoogleProvider(), FacebookProvider(), WeChatProvider()] ) // Return the ReachFive client static func reachfive() → ReachFive { (1) let app = UIApplication.shared.delegate as! AppDelegate return app.reachfive } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) → Bool { (2) reachfive.addPasswordlessCallback { result in // Check result and extract the authToken if the callback was successful, then continue your flow (for example redirect to the profile page) } // Initialize the ReachFive client return reachfive.application(application, didFinishLaunchingWithOptions: launchOptions) } func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) → Void) → Bool { reachfive.application(application, continue: userActivity, restorationHandler: restorationHandler) (3) } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) → Bool { reachfive.application(app, open: url, options: options) (4) } func applicationDidBecomeActive(_ application: UIApplication) { reachfive.applicationDidBecomeActive(application) (5) } } ``` - (1) An example of how to access the Purse Identity object from within the app. - (2) Initializes the iOS SDK by fetching information from the server about the client. For more details, see [application(\_:didFinishLaunchingWithOptions:)](application/applicationDidFinishLaunchingWithOptions.html). - (3) Forwards universal links to Purse Identity. Required by WeChat and by custom providers whose callback is a universal link; not by `WebProvider` `.universalLink`. For more details, see [application(\_:continue:restorationHandler:)](application/applicationContinueUserActivity.html). - (4) Forwards custom-scheme callbacks used by passwordless, MFA, account recovery, and provider native apps. For more details, see [application(\_:open:options)](application/applicationOpenUrl.html). - (5) This method is used to provide functionality to the providers. For more details, see [applicationDidBecomeActive(\_:)](application/applicationDidBecomeActive.html). ## iOS methods The sidebar contains are all the functions/methods accessible via the iOS SDK. In all the code examples, the Purse Identity client is instantiated and stored in your `AppDelegate` class. You can access it through the `AppDelegate.reachfive()` method as shown here and in [Configuration](#configuration). ```swift // Return the ReachFive client static func reachfive() -> ReachFive { let app = UIApplication.shared.delegate as! AppDelegate return app.reachfive } ``` ## Info.plist reference If you configure all four SDKs, your `Info.plist` file should contain the following `XML` Snippet. ```xml CFBundleURLTypes CFBundleURLSchemes fb1634029666893228 CFBundleTypeRole Editor CFBundleURLSchemes com.googleusercontent.apps.abcdefg-1234567890 CFBundleTypeRole Editor CFBundleURLSchemes reachfive-TYAIHFRJ2a1FGJ1T8pKD GIDClientID 1234567890-abcdefg.apps.googleusercontent.com FacebookAppID 1634029666893228 FacebookClientToken ec97b21afcd93ce699091a774a90e2e5 FacebookDisplayName Reach5 SDK Mobile GIDClientID abcdefg-1234567890.apps.googleusercontent.com LSApplicationQueriesSchemes weixin weixinULAPI weixinURLParamsAPI fbauth2 fbapi fb-messenger-share-api ``` --- # listWebAuthnCredentials URL: /sdk-ios/listWebAuthnCredentials.html AppDelegate.reachfive().listWebAuthnCredentials([authToken](#authToken)) ## Description Lists all passkeys the user has registered. ## Examples ```swift do { let listCredentials = try await AppDelegate.reachfive().listWebAuthnCredentials(authToken: profileAuthToken) // Get the list of devices } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response **Type**: <<\[DeviceCredential\]>> **Error**: [ReachFiveError](#reachfiveerror) ### DeviceCredential The details of a device credential. ##### friendlyName string The name that is displayed by the system when presenting the passkey for login. ##### id string The identifier of the credential. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # loadLoginWebview URL: /sdk-ios/loadLoginWebview.html loginWebview.loadLoginWebview([reachfive](#reachfive): AppDelegate.reachfive()) ## Description Opens an _insecure_ webview through the authorization endpoint: - If end-users have an active in-app SSO session, the authorization endpoint immediately redirects to the application. - If end-users do not have an active in-app SSO session, they are redirected to the client’s Login URL for authentication. > You must have configured a Login URL and enabled [request orchestration tokens](../docs/orchestration-token.html) for your identity client. > > Orchestrated flows are supported from [version `1.24.0`](https://github.com/ReachFive/identity-web-core-sdk/releases/tag/v1.24.0) for the [Core SDK](../sdk-core/index.html) and [version `1.16.0`](https://github.com/ReachFive/identity-web-ui-sdk/releases/tag/v1.16.0) for the [UI SDK](../sdk-ui/index.html). > We recommend using the standard native login or standard webview login for iOS. Proceed with caution while using this particular method for user authentication. > > Only supports flows that never leave the app. Use [WebProvider](providerCreator.html) or [webviewLogin](webviewLogin.html) instead. ## Examples ```swift import UIKit import Foundation import Reach5 class LoginWKWebviewController: UIViewController { @IBOutlet var loginWebview: LoginWKWebview! override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) Task { do { let authToken = try await loginWebview.loadLoginWebview(reachfive: AppDelegate.reachfive()) goToProfile(authToken) } catch { let alert = AppDelegate.createAlert(title: "Login failed", message: "Error: \(error.localizedDescription)") self.present(alert, animated: true) } } } } ``` > You can find this example with its UI integration in the [Purse Identity sandbox](https://github.com/ReachFive/reachfive-ios/blob/master/Sandbox/Sandbox/Controllers/Web/LoginWKWebviewController.swift). ## Customisation To further customise the behaviour and appearance of the `WKWebview`, please see the [Purse Identity sandbox](https://github.com/ReachFive/reachfive-ios/blob/master/Sandbox/Sandbox/Controllers/Web/LoginCustomWebviewController.swift). ## Parameters ##### reachfive The Purse Identity `AppDelegate` method. ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # login(withNonDiscoverableUserName) URL: /sdk-ios/loginWithNonDiscoverableUserName.html AppDelegate.reachfive().login( [withNonDiscoverableUserName](#withNonDiscoverableUserName), [forRequest](#forRequest), [usingModalAuthorizationFor](#usingModalAuthorizationForNonDiscoverable), [display](#displayForNonDiscoverable) ) ## Description Logs the user in using a saved passkey. The system only displays the passkey associated with the given username in a [modal sheet](https://developer.apple.com/design/human-interface-guidelines/sheets). > In this case, the user needs to manually enter the username in the username field. ## Usage By default, you should use the [login(withRequest)](loginWithRequest.html) method. > Use this method only when heightened security is required or when the user has already supplied a username. ## Examples ```swift do { let authToken = try await AppDelegate.reachfive().login( withNonDiscoverableUsername: .Unspecified(username), forRequest: NativeLoginRequest(presenting: presenting), usingModalAuthorizationFor: [.Passkey], display: .Always ) // get auth token on success } catch { // return ReachFive error on failure } ``` ## Parameters ##### withNonDiscoverableUserName The username of the profile. ##### forRequest NativeLoginRequest Object containing parameters to send along with the request. Object parameters: - `presenting`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). - `originWebAuthn`: The origin of the webauthn call. Defaults to the `originWebAuthn` of your `SdkConfig`, or to `https://${domain}`. - `scopes`: The scopes granted to the profile. - `origin`: The origin of the call. This helps categorize inbound traffic. ##### usingModalAuthorizationFor The type of credential, currently only `.Passkey` is supported. ##### display Choice of behaviour when there are no credentials available. options - `Always`: the system presents a QR code to allow signing in with a passkey from a nearby device. - `IfImmediatelyAvailableCredentials`: No UI appears and the call ends in `ReachFiveError.AuthCanceled` which you can intercept and react to (e.g., display other login options). ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # loginWithPassword URL: /sdk-ios/loginWithPassword.html AppDelegate.reachfive().loginWithPassword( [email](#email), [phoneNumber](#phoneNumber) [customIdentifier](#customIdentifier) [password](#password), // Optional arguments [scope](#scope) ) ## Description Authenticate the user with the specified identifier (email, phone number, or custom identifier) and password. A user may identify themselves with either their email address or their phone number if the SMS feature is enabled. In the case where step-up authentication is required, `loginWithPassword` returns [an `OngoingStepUp` response](#response). ## Examples ```swift do { let authToken = try await AppDelegate.reachfive().loginWithPassword( email: "john.doe@gmail.com", password: "UCrcF4RH", scope: ["openid", "profile", "email"] ) // Get the profile's authentication token } catch { // Return a ReachFive error } ``` ```swift do { let authToken = try await AppDelegate.reachfive().loginWithPassword( phoneNumber: "+33682234940", password: "UCrcF4RH", scope: ["openid", "profile", "email"] ) // Get the profile's authentication token } catch { // Return a ReachFive error } ``` ```swift do { let authToken = try await AppDelegate.reachfive().loginWithPassword( customIdentifier: "coolCat55", password: "UCrcF4RH", scope: ["openid", "profile", "email"] ) // Get the profile's authentication token } catch { // Return a ReachFive error } ``` ## Parameters ##### email string The email address of the profile. ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### customIdentifier string A string that allows users to authenticate with something other than an `email` or `phone_number`. It’s important to note that an `email` and/or `phone_number` is still required to create a managed profile. Each `custom_identifier` value must be unique. The `custom_identifier` must be between _4-80_ characters. ##### password string The password of the profile. ##### scope string\[\] The scopes granted to the profile. Make sure they are allowed by the client. Default scopes are the allowed scopes set up in the client’s configuration. ## Response - **Type**: LoginFlow.[AchievedLogin](#achievedlogin) | [OngoingStepUp](#ongoingstepup) - **Error**: [ReachFiveError](#reachfiveerror) If the credentials are valid, the promise returns the profile’s authentication token or continues the step-up process depending on the flow. Otherwise it is rejected and returns a `ReachFiveError`. ### AchievedLogin Returns the authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### OngoingStepUp ##### token string The token obtained after initiating the step-up flow. ##### availableMfaCredentialItemTypes \[MfaCredentialItemType\] The MFA credential type such as `email` or `sms`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # login(withRequest) URL: /sdk-ios/loginWithRequest.html AppDelegate.reachfive().login( [withRequest](#withRequest), [usingModalAuthorizationFor](#usingModalAuthorizationFor), [display](#display) ) ## Description Logs the user in using credentials saved for your app. The system displays all available credentials in a [modal sheet](https://developer.apple.com/design/human-interface-guidelines/sheets). Credentials can be any combination of passwords, passkeys, or Sign in with Apple. In the case where step-up authentication is required, `loginWithRequest` returns [an `OngoingStepUp` response](#response). ## Usage Start this request in response to a user interaction. Setting the parameter [`display`](#parameters) to `.Always` works best. Alternatively, start the request automatically early in a view lifecycle (e.g., in `viewDidAppear`) or during the application launch. Prefer setting [`display`](#parameters) to `.IfImmediatelyAvailableCredentials` for this use case. ## Examples ```swift do { let loginFlow = try await AppDelegate.reachfive().login(withRequest: NativeLoginRequest(presenting: presenting), usingModalAuthorizationFor: [.Passkey, .Password, .SignInWithApple], display: .IfImmediatelyAvailableCredentials) // handle successful auth or MFA challenge } catch ReachFiveError.AuthCanceled { return // No credentials are available. If called at app launch, do nothing. If called in `viewDidAppear`, presents other options for the user to login. } catch { // Real failure. } ``` ## Parameters ##### withRequest NativeLoginRequest Object containing parameters to send along with the request. Object parameters: - `presenting`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). - `originWebAuthn`: The origin of the webauthn call. Defaults to the `originWebAuthn` of your `SdkConfig`, or to `https://${domain}`. - `scopes`: The scopes granted to the profile. - `origin`: The origin of the call. This helps categorize inbound traffic. ##### usingModalAuthorizationFor An array of types of credential to unlock. Any combination of `.Password`, `.Passkey` and `SignInWithApple`. ##### display Choice of behaviour when there are no credentials available. options - `Always`: Depending on the type of credential: - `.Passkey`: the system presents a QR code to allow signing in with a passkey from a nearby device. - `.SignInWithApple`: a signup sheet appears. - `.Password`: no UI appears. - `IfImmediatelyAvailableCredentials`: No UI appears and the call ends in `ReachFiveError.AuthCanceled` which you can intercept and react to (e.g., display other login options). ## Response - **Type**: LoginFlow.[AchievedLogin](#achievedlogin) | [OngoingStepUp](#ongoingstepup) - **Error**: [ReachFiveError](#reachfiveerror) If the credentials are valid, the promise returns the profile’s authentication token or continues the step-up process depending on the flow. Otherwise it is rejected and returns a `ReachFiveError`. ### AchievedLogin Returns the authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### OngoingStepUp ##### token string The token obtained after initiating the step-up flow. ##### availableMfaCredentialItemTypes \[MfaCredentialItemType\] The MFA credential type such as `email` or `sms`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # logout URL: /sdk-ios/logout.html AppDelegate.reachfive().logout([webSessionLogout](#webSessionLogout) request: [WebSessionLogoutRequest](#WebSessionLogoutRequest)? = nil, [revoke](#revoke) token: AuthToken? = nil) async throws ## Description Terminates the main [SSO session](../docs/sso.html), all provider sessions, and optionally revokes user tokens or initiates a web-based logout. - **Provider Sessions**: Logs out from all configured identity providers (e.g., Google, Facebook). - **Web Session Logout**: When a `[WebSessionLogoutRequest](#WebSessionLogoutRequest)` is provided via the `webSessionLogout` parameter, triggers a web-based logout by opening a web authentication session to the server’s logout endpoint (e.g., `/logout`). - **Token Revocation**: When an `AuthToken` is provided via the `revoke` parameter, revokes the specified token, invalidating the user’s session. This applies to both access and refresh tokens. - **Main SSO Session**: Terminates the core SSO session. Both `webSessionLogout` and `revoke` are optional and default to `nil`. If neither is provided, the method logs out from provider sessions and the main SSO session but does not revoke specific tokens or clear browser cookies. Native vs Web For native app flows, use `logout(revoke:)` with an `AuthToken` to revoke tokens and end the session. For web-based SSO flows, use `logout(webSessionLogout:)` to clear browser cookies and handle redirects. For web-based logout, the app’s scheme must be configured in the Purse Identity Console’s SSO settings as an **Allowed logout callback URL**. Failure to configure this will result in a “URI redirect not allowed” error. **Example**: `reachfive-://callback` ## Examples ```swift // Basic logout (no parameters) do { try await AppDelegate.reachfive().logout() // User is logged out from provider sessions and main SSO session // Tokens are not revoked, and browser cookies are not cleared } catch { // Handle ReachFiveError } // Native logout with token revocation do { let authToken = // Obtain AuthToken from storage or authentication try await AppDelegate.reachfive().logout(revoke: authToken) // User is logged out, tokens are revoked } catch { // Handle ReachFiveError } // Web-based logout with redirect do { let request = try WebSessionLogoutRequest(presenting: Presentation(from: self), origin: "app_logout") try await AppDelegate.reachfive().logout(webSessionLogout: request) // Browser cookies are cleared, user is redirected } catch { // Handle ReachFiveError } ``` ## Parameters ##### webSessionLogout WebSessionLogoutRequest? _optional_ The web session logout request. Defaults to `nil`. If provided, triggers a [web-based logout](#WebSessionLogoutRequest) by opening a web authentication session to the server’s logout endpoint. The URL must be defined in your Purse Identity Console settings at **Security**  **SSO**  **Allowed Callback URLs**. ##### WebSessionLogoutRequest Use `WebSessionLogoutRequest` to enable web-based SSO logout, which opens a browser window to the server’s logout endpoint. This class is only needed for apps using web-based SSO. Includes: - _required_ `presentationContextProvider`: A delegate that provides a display context whereby the system is able to present an authentication session to the user. - _optional_ `origin`: The origin of the call. ##### revoke AuthToken? _optional_ The authentication token to revoke, invalidating the user’s session. Use `nil` to skip token revocation. Defaults to `nil`. > The `logout` method invalidates any tokens found here. The `logout` method invalidates any tokens found here. ## Response **Error**: [ReachFiveError](#reachfiveerror) ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaDeleteCredential URL: /sdk-ios/mfaDeleteCredential.html AppDelegate.reachfive().mfaDeleteCredential( [phoneNumber](#phoneNumber), **(1)** [authToken](#authToken) ) - (1) Passing the `phoneNumber` is only applicable for deleting phone numbers. For emails, you only need to pass the `authToken`. ## About this command Removes a credential for use as a second factor for MFA purposes. You can remove a phone number or email. ## Examples ```kotlin import Reach5 do { try await AppDelegate.reachfive().mfaDeleteCredential(authToken: profileAuthToken) // Do something } catch { // Return a ReachFive error } ``` ```kotlin import Reach5 do { try await AppDelegate.reachfive().mfaDeleteCredential( "+33682234940", authToken: profileAuthToken ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ## Response **Error**: [ReachFiveError](#reachfiveerror) ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaDeleteTrustedDevice URL: /sdk-ios/mfaDeleteTrustedDevice.html AppDelegate.reachfive().mfaDelete([trustedDeviceId](#trustedDeviceId), [authToken](#authToken)) ## About this command Removes an MFA trusted device for a user. ## Examples ```kotlin import Reach5 do { try await AppDelegate.reachfive().mfaDelete(trustedDeviceId: deviceId, authToken: profileAuthToken) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### trustedDeviceId string The ID of the trusted device. ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response **Error**: [ReachFiveError](#reachfiveerror) ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaListCredentials URL: /sdk-ios/mfaListCredentials.html AppDelegate.reachfive().mfaListCredentials([authToken](#authToken)) ## About this command Lists a user’s MFA credentials. These credentials are those verified for use as a second factor during the MFA process. ## Examples ```kotlin import Reach5 do { let credentials = try await AppDelegate.reachfive().mfaListCredentials(authToken: profileAuthToken) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response - **Type**: [MfaCredentialsListResponse](#mfacredentialslistresponse) - **Error**: [ReachFiveError](#reachfiveerror) ### MfaCredentialsListResponse ```json credentials: [ {"createdAt": "createdAtDate", "friendlyName": "friendlyName", "email": "joe@example.com", "type": CredentialType} ] (1) ``` - (1) Contains array of `MfaCredentialItem` objects. ```json credentials: [ {"createdAt": "createdAtDate", "friendlyName": "friendlyName", "phoneNumber": "+35312345678", "type": CredentialType} ] (1) ``` - (1) Contains array of `MfaCredentialItem` objects. ##### credentials friendlyName `string` createdAt `string` phoneNumber `string` email `string` type `CredentialType` ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaListTrustedDevices URL: /sdk-ios/mfaListTrustedDevices.html AppDelegate.reachfive().mfaListTrustedDevices([authToken](#authToken)) ## About this command Lists any MFA trusted devices for a user. ## Examples ```kotlin import Reach5 do { let trustedDevices = try await AppDelegate.reachfive().mfaListTrustedDevices(authToken: profileAuthToken) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response - **Type**: \[[MfaTrustedDevice](#mfatrusteddevice)\] - **Error**: [ReachFiveError](#reachfiveerror) ### MfaTrustedDevice ##### id string The trusted device ID. ##### userId string The user ID. ##### createdAt string The date and time when the device was trusted. ##### metaData object The metadata associated with the trusted device. This includes: - `ip`: The IP of the trusted device. - `operatingSystemAgent`: The Operating System such as iOS. - `userAgent`: The User Agent information. - `deviceClass`: The device class such as mobile. - `deviceName`: The device name such as "My Mobile". ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaStart(Registering credential) URL: /sdk-ios/mfaStart.html AppDelegate.reachfive().mfaStart( [registering](#Credential), [authToken](#authToken), [action](#action), [trustDevice](#trustDevice) ) ## About this command Starts the MFA email registration flow. When the flow is started, an email or SMS is sent to the user for verification depending on which `Credential` is used. > **Email**: > > If the user already has a verified email in their account, no additional verification code is sent. If an existing email exists but is unverified, it becomes automatically verified with [mfaVerify(Credential)](mfaVerify.html). > > **Mobile**: > > If the user already has a verified phone number with the same value in their account, no additional verification code is sent. If an existing phone number exists with the same value but is unverified, it becomes automatically verified with [mfaVerify(Credential)](mfaVerify.html). ## Examples ```kotlin import Reach5 do { let response = try await AppDelegate.reachfive().mfaStart( registering: .Email(redirectUrl: URL(string: "reachfive-${clientId}://callback")!), authToken: profileAuthToken ) // Do something } catch { // Return a ReachFive error } ``` ```kotlin import Reach5 do { let response = try await AppDelegate.reachfive().mfaStart( registering: .PhoneNumber("+3531235555"), authToken: profileAuthToken ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### registering The credential type to register. This is a method that requires an `authToken`. You pass either `.Email` or `.PhoneNumber`. For `.Email`, you also pass `redirectUri` as well. For `.PhoneNumber`, you also pass the `phoneNumber`. Email example ```swift AppDelegate.reachfive() .mfaStart(.Email( redirectUri: "reachfive-${clientId}://callback"), authToken: profileAuthToken) ``` PhoneNumber example ```swift AppDelegate.reachfive() .mfaStart(.PhoneNumber( phoneNumber: "+3531235555"), authToken: profileAuthToken) ``` ##### trustDevice boolean Boolean indicating if the device should be trusted or not. - `true` = trust the device - `false` = do not trust the device > This option only applies during registration when the second factor is already verified and the user doesn’t need to enter a verification code to complete enrollment. This option only applies during registration when the second factor is already verified and the user doesn’t need to enter a verification code to complete enrollment. ##### action String A string describing the action for the MFA flow. You can value this with whatever you like. It should match the value you describe in your [MFA templates](../docs/mfa-templates.html). We recommend using meaningful values like `login` or `transaction` to help better align with MFA email and SMS templates. ## Response - **Type**: MfaStartRegistrationResponse - **Error**: [ReachFiveError](#reachfiveerror) ### Credential verified If the credential is already verified, you receive a success with the MFA credential item. ### Credential unverified If the credential is unverified, you receive `ContinueRegistration` allowing you to then use the `mfaVerify` method. ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaStart(WithStepUp) URL: /sdk-ios/mfaStartWithStepUp.html AppDelegate.reachfive().mfaStart( [stepUp](#startStepUp): StartStepUp. **(1)** ) - (1) Depending on your [requirements](#about-this-command), this will either be `AuthTokenFlow` or `LoginFlow`. ## About this command Starts the step-up process for the MFA flow. This method handles two cases: - `AuthTokenFlow`: for the traditional step-up flow which requires an auth token. - `LoginFlow`: for initiating the step-up flow using [loginWithPassword](loginWithPassword.html). > The presence of an active session cookie is required. It is automatically retrieved by the function. ## Examples ```kotlin import Reach5 let scope = ["openid", "email", "profile", "phone", "full_write", "offline_access"] do { let response = try await AppDelegate.reachfive().mfaStart( stepUp: .AuthTokenFlow( authType: .email, authToken: profileAuthToken, scope: scope ) ) // Do something } catch { // Return a ReachFive error } ``` ```kotlin import Reach5 let scope = ["openid", "email", "profile", "phone", "full_write", "offline_access"] do { let response = try await AppDelegate.reachfive().mfaStart( stepUp: .LoginFlow( authType: .email, stepUpToken: "stepUpToken123", redirectUri: URL(string: "https://example.com/callback")!, origin: "ios-app" ) ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### stepUp Contains the necessary fields to begin the step up process. - `authType`: The authorization type. This is `email` or `sms`. **required** - `authToken`: The authorization token. **required** - `scope`: The defined scope such as `openid`, `email`, or `phone_number`. - `redirectUri`: The URL to which the user is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your ReachFive client settings. - `origin`: The domain of the origin. It must be a valid URL. - `action`: A string describing the action for the MFA flow. You can value this with whatever you like. It should match the value you describe in your [MFA templates](../docs/mfa-templates.html). We recommend using meaningful values like `login` or `transaction` to help better align with MFA email and SMS templates. - `trustDevice`: Boolean indicating if the device should be trusted or not. - `true` = trust the device - `false` = do not trust the device This option only applies during registration when the second factor is already verified and the user doesn’t need to enter a verification code to complete enrollment. ```swift AppDelegate.reachfive() .mfaStart(stepUp: StartStepUp.AuthTokenFlow( authType: "email", scope: scope, redirectUri: "https://example.com/callback", authToken: profileAuthToken, origin: "ios-app", action: "signup" )) ``` - `authType`: The authorization type. This is `email` or `sms`. **required** - `stepUpToken`: A new token generated during the login process. **required** - `redirectUri`: Ignored. The step-up token already carries the redirect URI that [loginWithPassword](loginWithPassword.html) sent, `SdkConfig.redirectUri`. - `origin`: The domain of the origin. It must be a valid URL. ```swift AppDelegate.reachfive() .mfaStart(stepUp: StartStepUp.LoginFlow( authType: "email", stepUpToken: "stepUpToken123", redirectUri: "https://example.com/callback", origin: "ios-app" )) ``` ## Response - **Type**: ContinueStepUp - **Error**: [ReachFiveError](#reachfiveerror) ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaVerify(Credential) URL: /sdk-ios/mfaVerify.html AppDelegate.reachfive().mfaVerify( [CredentialType](#CredentialType), **(1)** [code](#code), [authToken](#authToken), [trustDevice](#trustDevice) ) - (1) This "CredentialType" should be either `.Email` or `.PhoneNumber` as shown in the [examples](#examples) below. ## About this command Verifies the phone number or email as a second factor for MFA. ## Examples ```kotlin import Reach5 do { let credential = try await AppDelegate.reachfive().mfaVerify( .Email, code: verificationCode, authToken: profileAuthToken ) // Do something } catch { // Return a ReachFive error } ``` ```kotlin import Reach5 do { let credential = try await AppDelegate.reachfive().mfaVerify( .PhoneNumber, code: verificationCode, authToken: profileAuthToken ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### CredentialType The credential type to verify. Values - `.Email` - `.PhoneNumber` ##### code string The verification code sent to the user. ##### trustDevice boolean Boolean indicating if the device should be trusted or not. - `true` = trust the device - `false` = do not trust the device > This option only applies during registration when the second factor is already verified and the user doesn’t need to enter a verification code to complete enrollment. This option only applies during registration when the second factor is already verified and the user doesn’t need to enter a verification code to complete enrollment. ## Response - **Type**: [MfaCredentialItem](#mfacredentialitem) - **Error**: [ReachFiveError](#reachfiveerror) ### MfaCredentialItem ##### friendlyName string The name that is displayed by the system for the MFA credential item. ##### createdAt string The time when the MFA credential item was created. ##### phoneNumber string The phone number for the MFA credential. This is only applicable for the type `sms`. ##### email string The email for the MFA credential. This is only applicable for the type `email`. ##### type CredentialType The MFA credential type. - `sms` - `email` ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # mfaVerify(WithStepUp) URL: /sdk-ios/mfaVerifyWithStepUp.html AppDelegate.reachfive().mfaVerify( [stepUp](#verifyStepUp) ) ## About this command Verifies the step up process by passing the verification code and challenge ID. ## Examples ```kotlin import Reach5 do { let authToken = try await AppDelegate.reachfive().mfaVerify( stepUp: VerifyStepUp( challengeId: "m3DaoT...7Rzp1m", verificationCode: "123456", trustDevice: true ) ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### stepUp Contains the necessary fields to begin the step up process. This includes the following: - `verificationCode`: The verification code sent by email or SMS. - `challengeId`: The code challenge ID to verify the user. - `trustDevice`: _Optional_ boolean to trust the device or not. Accepts `true` to mark the device as trusted and `false` to mark the device as not trusted. ```swift ... AppDelegate.reachfive() .mfaVerify(stepUp( challengeId: "m3DaoT...7Rzp1m", verificationCode: "123456", trustDevice: true)) ... ``` ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### Error response ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # providerCreator URL: /sdk-ios/providerCreator.html `providerCreator` is a protocol that defines specific social login providers (e.g., Google, Facebook, Apple) available in our iOS SDK. These specific providers use native calls or external libraries to authenticate users. All providers except [Apple](../docs/apple.html) that you configure in the Purse Identity Console for which you don’t use a specific provider creator will authenticate through an `ASWebAuthenticationSession`. You should define and configure these providers when you [configure the iOS SDK](index.html#configure-the-ios-sdk). ## Examples ```swift static let reachfive: ReachFive = ReachFive( sdkConfig: sdkRemote, providersCreators: [ GoogleProvider(), FacebookProvider(), AppleProvider(variant: "ios_native"), WeChat(), WebProvider(name: .bconnect, variant: "natif", mode: .customScheme) ] ) ``` ## Available provider creators The providers who have a variant parameter have the following algorithm to choose a variant configured on the console. - If a variant is provided, the variant with the exact name, irrespective of case, is chosen. If no variant matches, the algorithm chooses the variant as if no variant was provided. - If no variant is provided, the first variant containing `ios` in its name, irrespective of case, if any, is chosen. Otherwise, the default variant is chosen. ##### GoogleProvider The object for configuring [Google native provider](index.html#google-native-provider) for our iOS SDK. Optionally takes a variant parameter. ```swift GoogleProvider(variant: "native") (1) ``` - (1) Available from `Reach5Google` 7.1.0. ##### 1 Available from `Reach5Google` 7.1.0. ##### FacebookProvider The object for configuring [Facebook native provider](index.html#facebook-native-provider) for our iOS SDK. This provider takes three optional parameters: - variant `string`: the provider variant to use. - prefersLoginTracking `FBSDKLoginKit.LoginTracking`: Indicates preference to the Facebook SDK for the limited or classic login. Facebook SDK is ultimately responsible for the decision. - appSwitch `FBSDKLoginKit.AppSwitch`: whether the login may open the native Facebook app instead of a Safari view controller. Defaults to `.enabled`; pass `.disabled` to always use the browser flow. It only takes effect when your `Info.plist` declares the `fbauth2` scheme and Meta has enabled Fast App Switch for your Facebook application. See [Fast App Switch](index.html#fast-app-switch). ```swift FacebookProvider( variant: "ios", (1) prefersLoginTracking: .enabled, (2) appSwitch: .enabled (3) ) ``` - (1) Available from `Reach5Facebook` 7.1.0. - (2) Available from `Reach5Facebook` 7.2.0. - (3) Available from `Reach5Facebook` 9.0.0. ##### 1 Available from `Reach5Facebook` 7.1.0. ##### 2 Available from `Reach5Facebook` 7.2.0. ##### 3 Available from `Reach5Facebook` 9.0.0. ##### AppleProvider Optionally takes a variant parameter. > Not specifying `AppleProvider` at all in the `providerCreators` array is equivalent to specifying `AppleProvider` with no variant. ```swift AppleProvider(variant: "native") (1) ``` - (1) Available from `Purse Identity` 7.1.3. Not specifying `AppleProvider` at all in the `providerCreators` array is equivalent to specifying `AppleProvider` with no variant. ##### 1 Available from `Purse Identity` 7.1.3. ##### WeChat The object for configuring [WeChat Connect](index.html#wechat-connect) for our iOS SDK. ```swift WeChat() (1) ``` - (1) WeChat takes no parameters. ##### 1 WeChat takes no parameters. ##### WebProvider The object for configuring a **web-only** provider — one with no native SDK component, authenticated entirely through an `ASWebAuthenticationSession`. Takes a `name`, an optional `variant`, and a `mode` controlling how the session’s redirection reaches the app: - `.customScheme` (default): the SDK’s custom scheme. Covers a redirect intercepted inside the sheet **and** one delivered to [application(\_:open:options)](application/applicationOpenUrl.html) when a provider hands the flow off to their own native app. - `.universalLink` (iOS 17.4+): the universal-link redirect is intercepted directly inside the authentication sheet. Requires the `webcredentials:` Associated Domain and a `universalLink` on the provider’s backend configuration. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). ```swift WebProvider(name: .bconnect, variant: "natif", mode: .customScheme) ``` > A provider configured on your client with no matching entry in `providersCreators` still logs in, falling back to `.customScheme` automatically. Add an explicit `WebProvider` only when you need `.universalLink`, or a specific `variant`. > Integrating a `.universalLink` provider? See [`.universalLink` instead](#universal-link-web-providers). > > To implement your own provider (native SDK, custom flow) instead, see [Implement a custom provider](guides/custom-provider.html). A provider configured on your client with no matching entry in `providersCreators` still logs in, falling back to `.customScheme` automatically. Add an explicit `WebProvider` only when you need `.universalLink`, or a specific `variant`. Integrating a `.universalLink` provider? See [`.universalLink` instead](#universal-link-web-providers). To implement your own provider (native SDK, custom flow) instead, see [Implement a custom provider](guides/custom-provider.html). ## Use a WebProvider with `.universalLink` (iOS 17.4+) Use this only when the OAuth `redirect_uri` must be the provider’s `https` `universalLink`, intercepted inside the authentication sheet. This mode cannot complete a login that leaves the app for a third-party app. There is no fallback below iOS 17.4: `login()` fails with a `TechnicalError` if the OS is too old or the provider has no `universalLink` in its backend configuration. - Register `WebProvider` with `mode: .universalLink`. The URL comes from the provider’s backend configuration; you do not pass it in. - Add `webcredentials:${host}` and the matching AASA section (see [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials)). > None of these fit your case? See [Implement a custom provider](guides/custom-provider.html) to implement your own. --- # refreshAccessToken URL: /sdk-ios/refreshAccessToken.html AppDelegate.reachfive().refreshAccessToken([authToken](#authToken)) ## Description Obtain a new `AuthToken` once your access token has expired. > - An expired access token (short-lived) can be renewed using a refresh token (long-lived). > > - Refreshing access tokens using an expired refresh token fails and invalidates all refresh tokens issued previously, for this Purse Identity client only. > > - The profile must have been granted the `offline_access` scope at the last authentication to obtain a refresh token. > > - For refresh token to be included in your `AuthToken`, your client must be configured on the Purse Identity Console to enforce PKCE and to enable refresh tokens. > > > For more on refresh tokens, check out the [Refresh Tokens](../docs/refresh-tokens.html) page. ## Examples ```swift import Reach5 let authToken: AuthToken = // The authentication token obtained from login or signup. do { let refreshedAuthToken = try await AppDelegate.reachfive().refreshAccessToken(authToken: authToken) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) If the credentials are valid, the promise will return the profile’s authentication token. Otherwise it will be rejected and will return a `ReachFiveError`. ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # registerNewPasskey URL: /sdk-ios/registerNewPasskey.html AppDelegate.reachfive().registerNewPasskey( [withRequest](#NewPasskeyRequest), [authToken](#authToken) ) ## Description Registers a new passkey for an existing user which currently has no passkeys in the keychain, or replace the existing passkey with a new one. ## Usage You should use this to allow users with existing accounts to register a passkey to their account. ## Examples ```swift do { try await AppDelegate.reachfive().registerNewPasskey(withRequest: NewPasskeyRequest(presenting: presenting, friendlyName: friendlyName), authToken: authToken) // get auth token on success } catch { // return ReachFive error on failure } ``` ## Parameters ##### withRequest NewPasskeyRequest Object containing parameters to send along with the request. Object parameters: - `presenting`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). - `friendlyName`: The name that is displayed by the system when presenting the passkey for login. - `originWebAuthn`: The origin of the webauthn call. Defaults to the `originWebAuthn` of your `SdkConfig`, or to `https://${domain}`. - `origin`: The origin of the call. This helps categorize inbound traffic. ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ## Response **Error**: [ReachFiveError](#reachfiveerror) ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # requestAccountRecovery URL: /sdk-ios/requestAccountRecovery.html AppDelegate.reachfive().requestAccountRecovery( [email](#email), [phoneNumber](#phoneNumber), [redirectUrl](#redirectUrl), // Optional arguments [origin](#origin) ) ## Description Request an account recovery reset for a profile. It sends an email if the email address is provided and an SMS if the phone number is given. You must configure and enable the [Email Account Recovery](../docs/email-templates.html#account-recovery) and/or the [SMS Account Recovery](../docs/sms-templates.html#account-recovery) templates in your Purse Identity account settings. ## Examples ```swift do { try await AppDelegate.reachfive().requestAccountRecovery( email: "john.doe@gmail.com", redirectUrl: URL(string: "reachfive-clientId://account-recovery")! ) // Do something } catch { // Return a ReachFive error } ``` ```swift do { try await AppDelegate.reachfive().requestAccountRecovery( phoneNumber: "+33682234940", redirectUrl: URL(string: "https://example-password-reset.com")! ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### email string The email address of the profile. ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### origin string The origin of the call. ##### redirectUrl string The URL to which the user is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your Purse Identity client settings. ## Response **Error**: [ReachFiveError](#reachfiveerror) The profile receives an email or an SMS depending if you pass an email or mobile phone number. If the identifier is invalid or if the templates are incomplete, the promise is rejected and returns a `ReachFiveError`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # requestPasswordReset URL: /sdk-ios/requestPasswordReset.html AppDelegate.reachfive().requestPasswordReset( // Optional arguments [email](#email), [phoneNumber](#phoneNumber), [redirectUrl](#redirectUrl), [origin](#origin) ) ## Description Request a password reset for a profile. It will send an email if the email address is provided and an SMS if the phone number is given. You must configure and enable the _Password reset email_ or the _Password reset SMS_ templates in your Purse Identity account settings. ## Examples ```swift do { try await AppDelegate.reachfive().requestPasswordReset( email: "john.doe@gmail.com", redirectUrl: URL(string: "reachfive-clientId://password-reset")! ) // Do something } catch { // Return a ReachFive error } ``` ```swift do { try await AppDelegate.reachfive().requestPasswordReset(phoneNumber: "+33682234940") // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### email string The email address of the profile. ##### redirectUrl string The URL to which the user is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your Purse Identity client settings. ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### origin string The origin of the call. ## Response **Error**: [ReachFiveError](#reachfiveerror) The profile will receive an email or an SMS. If the identifier is invalid or if the templates are incomplete, the promise will be rejected and will return a `ReachFiveError`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # resetPasskeys URL: /sdk-ios/resetPasskeys.html AppDelegate.reachfive().resetPasskeys( [withRequest](#ResetPasskeyRequest) ) ## Description Resets the passkey for a user. This method is the end of the flow for [Account recovery](guides/account-recovery.html). ## Examples ```swift do { try await AppDelegate.reachfive().resetPasskeys(withRequest: ResetPasskeyRequest(verificationCode: verificationCode, friendlyName: friendlyName, presenting: presenting, email: email)) // handle success } catch { // return ReachFive error on failure } ``` ## Parameters ##### withRequest ResetPasskeyRequest Object containing parameters to send along with the request to reset a passkey. Object parameters: - `email`: The user’s email. - `phoneNumber`: The user’s phone number. - `verificationCode`: The verification code that confirms the user. - `originWebAuthn`: The origin of the webauthn call. Defaults to the `originWebAuthn` of your `SdkConfig`, or to `https://${domain}`. - `origin`: The origin of the call. - `friendlyName`: The name that will be displayed by the system when presenting the passkey for login - `presenting`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). ## Response **Error**: [ReachFiveError](#reachfiveerror) ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # sendEmailVerification URL: /sdk-ios/sendEmailVerification.html AppDelegate.reachfive().sendEmailVerification([authToken](#authToken), [redirectUrl](#redirectUrl)) **(1)** - (1) `redirectUrl` is optional. ## Description Initiates the email verification process by sending a verification email to the user’s registered email address. The email contains a unique verification code required to confirm the email address. This method requires the user to be authenticated and is typically used after signup or an email update. > - You should configure and enable the [Verify email](../docs/email-templates.html#verify-email) template in the account’s settings. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { let emailVerificationResponse = try await AppDelegate.reachfive().sendEmailVerification( authToken: profileAuthToken, redirectUrl: URL(string: "https://example-email-verification.com")! // optional ) switch emailVerificationResponse { case .Success: // Email verification process completed successfully case .VerificationNeeded(let continueEmailVerification): // Verification email sent, use continueEmailVerification.verify(code: String, email: String, freshAuthToken: AuthToken? = nil) or AppDelegate.reachfive().verifyEmail to complete the flow } } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### redirectUrl string **optional** The URL to which the user will be redirected after clicking the verification link in the email. This URL must be whitelisted in the `Allowed Callback URLs` field of your Purse Identity client settings. ## Response - **Type**: EmailVerificationResponse - **Error**: [ReachFiveError](#reachfiveerror) The response is an `EmailVerificationResponse` enum with two cases: - `.Success`: Indicates the email verification process completed without requiring further action. - `.VerificationNeeded(ContinueEmailVerification)`: Indicates a verification email was sent, and further action (e.g., entering a verification code) is required to [complete the process](#completing-the-flow). The promise is rejected and returns a `ReachFiveError` if: - The parameters are invalid. - The email template is incomplete. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. ### Completing the flow Use `continueEmailVerification.verify(code: String, email: String, freshAuthToken: AuthToken? = nil)` or [verifyEmail](verifyEmail.html) to complete the verification. --- # signup URL: /sdk-ios/signup.html AppDelegate.reachfive().signup( [profile](#profileSignupRequest), // Optional arguments [redirectUrl](#redirectUrl), [scope](#scope) ) ## Description Create and authenticate a new user with the specified data. > Users can identify themselves with an email address or mobile number (if the `SMS` feature is enabled). ## Examples ```swift import Reach5 do { let signupFlow = try await AppDelegate.reachfive().signup( profile: ProfileSignupRequest( password: "hjk90wxc", email: "john.doe@gmail.com", customIdentifier: "coolCat55", givenName: "John", familyName: "Doe", gender: "male" ), redirectUrl: URL(string: "https://www.example.com/redirect")!, scope: ["openid", "profile", "email"] ) switch signupFlow { case .AchievedLogin(authToken: let authToken): // Signup completed and user is logged in // Use authToken as needed case .AwaitingIdentifierVerification: // Signup completed but email/phone verification is required } } catch { // Handle ReachFive error } ``` ```swift import Reach5 do { let signupFlow = try await AppDelegate.reachfive().signup( profile: ProfileSignupRequest( password: "hjk90wxc", phoneNumber: "+353875551234", customIdentifier: "coolCat55", givenName: "John", familyName: "Doe", gender: "male" ), scope: ["openid", "profile", "phone"] ) switch signupFlow { case .AchievedLogin(authToken: let authToken): // Signup completed and user is logged in // Use authToken as needed case .AwaitingIdentifierVerification: // Signup completed but phone verification is required } } catch { // Handle ReachFive error } ``` ## Parameters ##### profile ProfileSignupRequest The data of the profile. ##### password string The password of the profile. Password must meet the minimum requirements defined by the [zxcvbn](https://github.com/dropbox/zxcvbn) used. ##### email string The primary email address of the profile. ##### phoneNumber string The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### customIdentifier string A string that allows users to authenticate with something other than an `email` or `phone_number`. It’s important to note that an `email` and/or `phone_number` is still required to create a managed profile. Each `custom_identifier` value must be unique. The `custom_identifier` must be between _4-80_ characters. ##### givenName string The given name of the profile. ##### middleName string The middle name of the profile. ##### familyName string The family name of the profile. ##### name string The full name of the profile. ##### nickname string The nickname of the profile. ##### birthdate string The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### profileURL string The URL of one of the user’s profile page (usually a social provider’s page). ##### picture string The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### username string The username of the profile (the login’s name). ##### gender string The gender of the profile. Allowed values are `female`, `male` and `other`. ##### company string The company’s name of the profile. ##### addresses ProfileAddress\[\] The list of the profile’s postal addresses ##### locale string The profile’s language code in lowercase and country code in uppercase, separated by a dash (eg `en`, `fr-FR` …​). ##### bio string The biography of the profile. ##### customFields Map The custom fields of the profile. ##### consents Map The consents granted to the profile. It is a map of string keys with the associated consent object. ##### redirectUrl string The URL to which the user is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your Purse Identity client settings. ##### scope string\[\] The scopes granted to the profile. Make sure they are allowed by the client. Default scopes are the allowed scopes set up in the client’s configuration. ## Response - **Type**: SignupFlow.[AchievedLogin(authToken: AuthToken)](#achievedlogin) | [AwaitingIdentifierVerification](#awaitingidentifierverification) - **Error**: [ReachFiveError](#reachfiveerror) If the signup completes successfully, the promise returns either the authentication token (`AchievedLogin`) or indicates that the user must verify their identifier (`AwaitingIdentifierVerification`). Otherwise it is rejected and returns a `ReachFiveError`. ### AchievedLogin Returned when a signup completes successfully and the user is immediately logged in. Contains the authentication token and user information. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### AwaitingIdentifierVerification Returned when a signup completes but the user must verify their identifier (email or phone) before logging in. - No `AuthToken` is returned. - You should prompt the user to check their email or SMS for verification instructions. - After verification, the user can log in normally to receive an `AuthToken`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # signup(withRequest) URL: /sdk-ios/signupWithRequest.html AppDelegate.reachfive().signup( [withRequest](#PasskeySignupRequest) ) ## Description Signs up a user using a passkey. ## Usage You should use this for users that don’t have accounts and want to sign up using the passkey option. ## Examples ```swift import Reach5 do { let authToken = try await AppDelegate.reachfive().signup(withRequest: PasskeySignupRequest(passkeyProfile: profile, friendlyName: username, presenting: presenting)) // Get the profile's authentication token } catch { // Return a ReachFive error } ``` ## Parameters ##### withRequest PasskeySignupRequest Object containing parameters to send along with the request. Object parameters: - `passkeyProfile`: The data of the profile. - `friendlyName`: The name that is displayed by the system when presenting the passkey for login. - `presenting`: Where the credential provider presents its UI, built with `Presentation(from: self)` from a view controller attached to a window (`viewDidAppear` or a user interaction, not `viewDidLoad`). - `originWebAuthn`: The origin of the webauthn call. Defaults to the `originWebAuthn` of your `SdkConfig`, or to `https://${domain}`. - `scopes`: The scopes granted to the profile. - `origin`: The origin of the call. This helps categorize inbound traffic. ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # startPasswordless URL: /sdk-ios/startPasswordless.html AppDelegate.reachfive().startPasswordless( // Optional arguments [email](#email), [phoneNumber](#phoneNumber), [redirectUri](#redirectUri), [scope](#scope) ) ## Description Starts passwordless flow by sending an email or an SMS to the user with a single-use auth code. ## Examples ```swift import Reach5 do { try await AppDelegate.reachfive().startPasswordless(.Email( email: "john.doe@gmail.com", redirectUri: URL(string: "reachfive-${clientId}://callback")!, scope: ["openid", "email", "offline_access"] )) // Do something } catch { // Return a ReachFive error } ``` ```swift import Reach5 do { try await AppDelegate.reachfive().startPasswordless(.PhoneNumber( phoneNumber: "+33792244940", redirectUri: URL(string: "reachfive-${clientId}://callback")! )) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### email string The email address of the profile. ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### redirectUri string The URL where the user will be redirected after the passwordless success. Default value is `reachfive-${clientId}://callback`. ##### scope string\[\] The scopes granted to the profile. Make sure they are allowed by the client. Default scopes are the allowed scopes set up in the client’s configuration. ## Response **Error**: [ReachFiveError](#reachfiveerror) The profile will receive an email or an SMS. If the parameters are invalid, the promise will be rejected and will return a `ReachFiveError`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # updateEmail URL: /sdk-ios/updateEmail.html AppDelegate.reachfive().updateEmail( [authToken](#authToken), [email](#updateEmail), // Optional arguments [redirectUrl](#redirectUrl) ) ## Description Update the profile’s email address and send a verification email. > - The profile must have been granted the `full_write` scope at the last authentication. > > - It is required to configure and to enable the [Email update template](../docs/email-templates.html) in the account’s settings. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { let updatedProfile = try await AppDelegate.reachfive().updateEmail( authToken: profileAuthToken, email: "johnatthan.doe@gmail.com", redirectUrl: URL(string: "https://example-email-update.com")! ) // Get the updated profile } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### email string The email address of the profile. The new email address must be different from the old one. Unverified emails If the email being updated is unverified, the user’s email is updated immediately. Verified emails If the email being updated is verified, the user must click on the verification link sent in the email to finish the _update email flow_. Users won’t be able to use the new email for authentication until it is verified. > For more, see our [Email address management page](../docs/email-address-management.html#changing-email-address-when-logged-in). For more, see our [Email address management page](../docs/email-address-management.html#changing-email-address-when-logged-in). ##### redirectUrl string The URL to which the user is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your Purse Identity client settings. ## Response - **Type**: [Profile](#profile) - **Error**: [ReachFiveError](#reachfiveerror) Return the profile with the updated email address. The promise will be rejected and will return a `ReachFiveError` if: - The parameters are invalid, - The `full_write` scope is missing, - The email template is incomplete. ### Profile ##### id string The Purse Identity identifier of the profile. ##### givenName string The given name of the profile. ##### middleName string The middle name of the profile. ##### familyName string The family name of the profile. ##### name string The full name of the profile. ##### nickname string The nickname of the profile. ##### birthdate string The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### profileURL string The URL of one of the user’s profile page (usually a social provider’s page). ##### picture string The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### externalId string The external identifier of the profile. ##### authTypes String\[\] The list of the authentication providers used to login by the profile (e.g. facebook, password …​). ##### loginSummary LoginSummary The login activities history of the profile. ##### firstLogin string The time of the first login. ##### lastLogin string The time of the last login. ##### total string The number of login. ##### origins string Some additional information about the login. ##### devices string The devices used for login (`desktop`, `ios`, `android`, `mobile_web` and `windows_phone`). ##### lastProvider string The last provider used for login (e.g. `local`, `lite`, `facebook` …​). ##### username string The username of the profile (the login’s name). ##### gender string The gender of the profile. Allowed values are `female`, `male` and `other`. ##### email string The primary email address of the profile. ##### emailVerified boolean `true` if the profile’s e-mail address has been verified; otherwise `false`. ##### emails Emails The e-mail addresses of the profile. ##### verified string\[\] The list of the verified e-mail addresses of the profile. ##### unverified string\[\] The list of the unverified e-mail addresses of the profile. ##### phoneNumber string The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### addresses List of ProfileAddress The list of the profile’s postal addresses. To get this attribute, the profile must have been granted the `address` scope at the last authentication. ##### title string The title of the address. This value can’t be an empty string. ##### isDefault boolean Whether the address is the default postal address of the profile. Only a single address can be the default address. Defaults to `true`. ##### addressType string The type of address Allowed values: `delivery` or `billing`. ##### streetAddress string The full street address component which may include the house number, the street’s name and the extended street address information separated by newlines. This value can’t be an empty string. ##### addressComplement A complementary address field which can contain additional information about the address. ##### locality string The name of the city. ##### region string The name of the region. ##### postalCode string The zip code. ##### country string The name of the country. This value can’t be an empty string. ##### deliveryNote string An additional note from the profile for the delivery. ##### recipient string The name of the recipient located at this address. ##### company string The name of the company located at this address. ##### phoneNumber string The phone number of the contact point at this address (no format validation is required). ##### locale string The profile’s language code in lowercase and country code in uppercase, separated by a dash (e.g. `en`, `fr-FR` …​). ##### bio string The biography of the profile. ##### customFields Map The custom fields of the profile. [Structured custom fields](../docs/custom-fields.html) are only available using the full key for the field (e.g., `full.custom_field.key`). They are not supported as nested objects. ##### consents Map The consents granted to the profile. It is a map of string keys with the associated consent object. ##### granted boolean Whether the consent was granted to the profile or not. ##### consentType boolean The type of consent. Allowed values: `opt-in` `opt-out`. ##### date string The time the consent was last updated. ##### createdAt string The time the profile’s information was created. ##### updatedAt string The time the profile’s information was last updated. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # updatePassword URL: /sdk-ios/updatePassword.html AppDelegate.reachfive().updatePassword([updatePasswordRequest](#parameters)) ## Description Update the profile’s password. The parameters required in addition to the new password are either: - A fresh access token (less than 5 minutes old). - The old password. - The profile’s email address/phone number and the verification code sent by email/SMS through a request password reset flow. > - The profile must have been granted the `full_write` scope at the last authentication. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { try await AppDelegate.reachfive().updatePassword( .AccessTokenParams( authToken: profileAuthToken, password: "ZPf7LFtc", oldPassword: "gVc7piBn" ) ) // Do something } catch { // Return a ReachFive error } ``` ```swift import Reach5 let freshProfileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login (less than 5 min) do { try await AppDelegate.reachfive().updatePassword( .FreshAccessTokenParams( authToken: freshProfileAuthToken, password: "ZPf7LFtc" ) ) // Do something } catch { // Return a ReachFive error } ``` ```swift import Reach5 do { try await AppDelegate.reachfive().updatePassword( .EmailParams( email: "john.doe@example.com", verificationCode: "234", password: "ZPf7LFtc" ) ) // Do something } catch { // Return a ReachFive error } ``` ```swift import Reach5 do { try await AppDelegate.reachfive().updatePassword( .SmsParams( phoneNumber: "+33682234940", verificationCode: "234", password: "ZPf7LFtc" ) ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters The `UpdatePasswordRequest` enum class consists into: - `FreshAccessTokenParams` - `AccessTokenParams` - `EmailParams` - `SmsParams` `FreshAccessTokenParams` ##### freshAccessToken AuthToken Authorization token of the profile retrieved from login (less than 5 minutes old). ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire.@ ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### password string The new password of the profile. Password must meet the minimum requirements defined by the [zxcvbn](https://github.com/dropbox/zxcvbn) used. It must also be different from the old one. `AccessTokenParams` ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### oldPassword string The old password of the profile. ##### password string The new password of the profile. Password must meet the minimum requirements defined by the [zxcvbn](https://github.com/dropbox/zxcvbn) used. It must also be different from the old one. `EmailParams` ##### email string The email address of the profile. ##### verificationCode string The verification code sent by email or SMS. ##### password string The new password of the profile. Password must meet the minimum requirements defined by the [zxcvbn](https://github.com/dropbox/zxcvbn) used. It must also be different from the old one. `SmsParams` ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### verificationCode string The verification code sent by email or SMS. ##### password string The new password of the profile. Password must meet the minimum requirements defined by the [zxcvbn](https://github.com/dropbox/zxcvbn) used. It must also be different from the old one. ## Response **Error**: [ReachFiveError](#reachfiveerror) The profile’s password will be updated. If the parameters are invalid or if the `full_write` scope is missing, the promise will be rejected and will return a `ReachFiveError`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # updatePhoneNumber URL: /sdk-ios/updatePhoneNumber.html AppDelegate.reachfive().updatePhoneNumber([authToken](#authToken), [phoneNumber](#phoneNumber)) ## Description Update the profile’s phone number and send a verification code by SMS. > - The profile must have been granted the `full_write` scope at the last authentication. > > - It is required to configure and to enable the _Verification SMS_ template in the account’s settings. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { let updatedProfile = try await AppDelegate.reachfive().updatePhoneNumber( authToken: profileAuthToken, phoneNumber: "+33792244940" ) // Get the updated profile } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### phoneNumber string The phone number of the profile. The new phone number can be identical to the old one. > Both the international format and the national conventions of the account’s country are accepted if configured in account settings. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ## Response - **Type**: [Profile](#profile) - **Error**: [ReachFiveError](#reachfiveerror) It will return the profile with the updated phone number. The promise will be rejected and will return a `ReachFiveError` if: - The parameters are invalid, - The `full_write` scope is missing, - The SMS template is incomplete. ### Profile ##### id string The Purse Identity identifier of the profile. ##### givenName string The given name of the profile. ##### middleName string The middle name of the profile. ##### familyName string The family name of the profile. ##### name string The full name of the profile. ##### nickname string The nickname of the profile. ##### birthdate string The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### profileURL string The URL of one of the user’s profile page (usually a social provider’s page). ##### picture string The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### externalId string The external identifier of the profile. ##### authTypes String\[\] The list of the authentication providers used to login by the profile (e.g. facebook, password …​). ##### loginSummary LoginSummary The login activities history of the profile. ##### firstLogin string The time of the first login. ##### lastLogin string The time of the last login. ##### total string The number of login. ##### origins string Some additional information about the login. ##### devices string The devices used for login (`desktop`, `ios`, `android`, `mobile_web` and `windows_phone`). ##### lastProvider string The last provider used for login (e.g. `local`, `lite`, `facebook` …​). ##### username string The username of the profile (the login’s name). ##### gender string The gender of the profile. Allowed values are `female`, `male` and `other`. ##### email string The primary email address of the profile. ##### emailVerified boolean `true` if the profile’s e-mail address has been verified; otherwise `false`. ##### emails Emails The e-mail addresses of the profile. ##### verified string\[\] The list of the verified e-mail addresses of the profile. ##### unverified string\[\] The list of the unverified e-mail addresses of the profile. ##### phoneNumber string The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### addresses List of ProfileAddress The list of the profile’s postal addresses. To get this attribute, the profile must have been granted the `address` scope at the last authentication. ##### title string The title of the address. This value can’t be an empty string. ##### isDefault boolean Whether the address is the default postal address of the profile. Only a single address can be the default address. Defaults to `true`. ##### addressType string The type of address Allowed values: `delivery` or `billing`. ##### streetAddress string The full street address component which may include the house number, the street’s name and the extended street address information separated by newlines. This value can’t be an empty string. ##### addressComplement A complementary address field which can contain additional information about the address. ##### locality string The name of the city. ##### region string The name of the region. ##### postalCode string The zip code. ##### country string The name of the country. This value can’t be an empty string. ##### deliveryNote string An additional note from the profile for the delivery. ##### recipient string The name of the recipient located at this address. ##### company string The name of the company located at this address. ##### phoneNumber string The phone number of the contact point at this address (no format validation is required). ##### locale string The profile’s language code in lowercase and country code in uppercase, separated by a dash (e.g. `en`, `fr-FR` …​). ##### bio string The biography of the profile. ##### customFields Map The custom fields of the profile. [Structured custom fields](../docs/custom-fields.html) are only available using the full key for the field (e.g., `full.custom_field.key`). They are not supported as nested objects. ##### consents Map The consents granted to the profile. It is a map of string keys with the associated consent object. ##### granted boolean Whether the consent was granted to the profile or not. ##### consentType boolean The type of consent. Allowed values: `opt-in` `opt-out`. ##### date string The time the consent was last updated. ##### createdAt string The time the profile’s information was created. ##### updatedAt string The time the profile’s information was last updated. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # updateProfile URL: /sdk-ios/updateProfile.html AppDelegate.reachfive().updateProfile([authToken](#authToken), [profile](#profile)) ## Description Update a user profile. > - The profile must have been granted the `full_write` scope at the last authentication. > > - The `email` and the `password` fields of the profile can’t be updated with this method, except if the profile has no email address (usually when it is not provided by the social provider). Instead, use the [updateEmail](updateEmail.html) method. > > - The `phoneNumber` field of the profile can’t be updated if the SMS verification code is disabled on the account settings. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { let updatedProfile = try await AppDelegate.reachfive().updateProfile( authToken: profileAuthToken, profile: Profile(givenName: "Jonathan", phoneNumber: "+33750253354") ) // Get the updated profile } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### profile Profile The profile with the new data. Only the provided fields are updated. ## Response - **Type**: [Profile](#profile-2) - **Error**: [ReachFiveError](#reachfiveerror) Return the profile with the updated data. If parameters are not valid or if the `full_write` scope is missing, the promise will be rejected and will return a `ReachFiveError`. ### Profile ##### id string The Purse Identity identifier of the profile. ##### givenName string The given name of the profile. ##### middleName string The middle name of the profile. ##### familyName string The family name of the profile. ##### name string The full name of the profile. ##### nickname string The nickname of the profile. ##### birthdate string The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### profileURL string The URL of one of the user’s profile page (usually a social provider’s page). ##### picture string The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### externalId string The external identifier of the profile. ##### authTypes String\[\] The list of the authentication providers used to login by the profile (e.g. facebook, password …​). ##### loginSummary LoginSummary The login activities history of the profile. ##### firstLogin string The time of the first login. ##### lastLogin string The time of the last login. ##### total string The number of login. ##### origins string Some additional information about the login. ##### devices string The devices used for login (`desktop`, `ios`, `android`, `mobile_web` and `windows_phone`). ##### lastProvider string The last provider used for login (e.g. `local`, `lite`, `facebook` …​). ##### username string The username of the profile (the login’s name). ##### gender string The gender of the profile. Allowed values are `female`, `male` and `other`. ##### email string The primary email address of the profile. ##### emailVerified boolean `true` if the profile’s e-mail address has been verified; otherwise `false`. ##### emails Emails The e-mail addresses of the profile. ##### verified string\[\] The list of the verified e-mail addresses of the profile. ##### unverified string\[\] The list of the unverified e-mail addresses of the profile. ##### phoneNumber string The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### addresses List of ProfileAddress The list of the profile’s postal addresses. To get this attribute, the profile must have been granted the `address` scope at the last authentication. ##### title string The title of the address. This value can’t be an empty string. ##### isDefault boolean Whether the address is the default postal address of the profile. Only a single address can be the default address. Defaults to `true`. ##### addressType string The type of address Allowed values: `delivery` or `billing`. ##### streetAddress string The full street address component which may include the house number, the street’s name and the extended street address information separated by newlines. This value can’t be an empty string. ##### addressComplement A complementary address field which can contain additional information about the address. ##### locality string The name of the city. ##### region string The name of the region. ##### postalCode string The zip code. ##### country string The name of the country. This value can’t be an empty string. ##### deliveryNote string An additional note from the profile for the delivery. ##### recipient string The name of the recipient located at this address. ##### company string The name of the company located at this address. ##### phoneNumber string The phone number of the contact point at this address (no format validation is required). ##### locale string The profile’s language code in lowercase and country code in uppercase, separated by a dash (e.g. `en`, `fr-FR` …​). ##### bio string The biography of the profile. ##### customFields Map The custom fields of the profile. [Structured custom fields](../docs/custom-fields.html) are only available using the full key for the field (e.g., `full.custom_field.key`). They are not supported as nested objects. ##### consents Map The consents granted to the profile. It is a map of string keys with the associated consent object. ##### granted boolean Whether the consent was granted to the profile or not. ##### consentType boolean The type of consent. Allowed values: `opt-in` `opt-out`. ##### date string The time the consent was last updated. ##### createdAt string The time the profile’s information was created. ##### updatedAt string The time the profile’s information was last updated. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # updateProfile with delete URL: /sdk-ios/updateProfile_withDelete.html AppDelegate.reachfive().updateProfile([authToken](#authToken), [ProfileUpdate](#ProfileUpdate)) ## Description Update a user profile including removing a field. > This method allows you to remove a field from the user profile, whereas the [updateProfile](updateProfile.html) method only lets you update fields. > - The profile must have been granted the `full_write` scope at the last authentication. > > - The `email` and the `password` fields of the profile can’t be updated with this method, except if the profile has no email address (usually when it is not provided by the social provider). Instead, use the [updateEmail](updateEmail.html) method. > > - The `phoneNumber` field of the profile can’t be updated if the SMS feature is activated on the account settings. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { let updatedProfile = try await AppDelegate.reachfive().updateProfile( authToken: profileAuthToken, profileUpdate: ProfileUpdate(phoneNumber: .Delete) ) // Get the updated profile } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### Diff Data ##### Update(newValue) Update the field with the given new value. ##### Delete Delete the value of the field. ##### NoOp (the default) Don’t change the field. ##### ProfileUpdate ProfileUpdate The profile with the new data. Each field is a [Diff](#Diff). ##### givenName Diff The given name of the profile. ##### middleName Diff The middle name of the profile. ##### familyName Diff The family name of the profile. ##### name Diff The full name of the profile. ##### nickname Diff The nickname of the profile. ##### birthdate Diff The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### picture Diff The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### username Diff The username of the profile (the login’s name). ##### gender Diff The gender of the profile. Allowed values are `female`, `male` and `other`. ##### email Diff The primary email address of the profile. ##### phoneNumber Diff The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### customIdentifier Diff A string that allows users to authenticate with something other than an `email` or `phone_number`. Each `custom_identifier` value must be unique. The `custom_identifier` must be between _4-80_ characters. ##### locale Diff The profile’s language code in lowercase and country code in uppercase, separated by a dash (e.g. `en`, `fr-FR` …​). ##### company Diff The company associated with the profile. ## Response - **Type**: [Profile](#profile) - **Error**: [ReachFiveError](#reachfiveerror) Return the profile with the updated data. If parameters are not valid or if the `full_write` scope is missing, the promise will be rejected and will return a `ReachFiveError`. ### Profile ##### id string The Purse Identity identifier of the profile. ##### givenName string The given name of the profile. ##### middleName string The middle name of the profile. ##### familyName string The family name of the profile. ##### name string The full name of the profile. ##### nickname string The nickname of the profile. ##### birthdate string The birthdate of the profile, represented as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) `YYYY-MM-DD` format. ##### profileURL string The URL of one of the user’s profile page (usually a social provider’s page). ##### picture string The URL of one of the profile picture. This URL refers to an image file (PNG, JPEG, or GIF image file). ##### externalId string The external identifier of the profile. ##### authTypes String\[\] The list of the authentication providers used to login by the profile (e.g. facebook, password …​). ##### loginSummary LoginSummary The login activities history of the profile. ##### firstLogin string The time of the first login. ##### lastLogin string The time of the last login. ##### total string The number of login. ##### origins string Some additional information about the login. ##### devices string The devices used for login (`desktop`, `ios`, `android`, `mobile_web` and `windows_phone`). ##### lastProvider string The last provider used for login (e.g. `local`, `lite`, `facebook` …​). ##### username string The username of the profile (the login’s name). ##### gender string The gender of the profile. Allowed values are `female`, `male` and `other`. ##### email string The primary email address of the profile. ##### emailVerified boolean `true` if the profile’s e-mail address has been verified; otherwise `false`. ##### emails Emails The e-mail addresses of the profile. ##### verified string\[\] The list of the verified e-mail addresses of the profile. ##### unverified string\[\] The list of the unverified e-mail addresses of the profile. ##### phoneNumber string The primary phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### addresses List of ProfileAddress The list of the profile’s postal addresses. To get this attribute, the profile must have been granted the `address` scope at the last authentication. ##### title string The title of the address. This value can’t be an empty string. ##### isDefault boolean Whether the address is the default postal address of the profile. Only a single address can be the default address. Defaults to `true`. ##### addressType string The type of address Allowed values: `delivery` or `billing`. ##### streetAddress string The full street address component which may include the house number, the street’s name and the extended street address information separated by newlines. This value can’t be an empty string. ##### addressComplement A complementary address field which can contain additional information about the address. ##### locality string The name of the city. ##### region string The name of the region. ##### postalCode string The zip code. ##### country string The name of the country. This value can’t be an empty string. ##### deliveryNote string An additional note from the profile for the delivery. ##### recipient string The name of the recipient located at this address. ##### company string The name of the company located at this address. ##### phoneNumber string The phone number of the contact point at this address (no format validation is required). ##### locale string The profile’s language code in lowercase and country code in uppercase, separated by a dash (e.g. `en`, `fr-FR` …​). ##### bio string The biography of the profile. ##### customFields Map The custom fields of the profile. [Structured custom fields](../docs/custom-fields.html) are only available using the full key for the field (e.g., `full.custom_field.key`). They are not supported as nested objects. ##### consents Map The consents granted to the profile. It is a map of string keys with the associated consent object. ##### granted boolean Whether the consent was granted to the profile or not. ##### consentType boolean The type of consent. Allowed values: `opt-in` `opt-out`. ##### date string The time the consent was last updated. ##### createdAt string The time the profile’s information was created. ##### updatedAt string The time the profile’s information was last updated. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # verifyEmail URL: /sdk-ios/verifyEmail.html AppDelegate.reachfive().verifyEmail([authToken](#authToken), [code](#code), [email](#email)) ## Description Confirms the user’s email address using the provided verification code. This method is called after the user receives the verification email and inputs the code. If successful, the email is marked as verified in the user’s profile. > - The profile must have been granted the `full_write` scope at the last authentication. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { try await AppDelegate.reachfive().verifyEmail( authToken: profileAuthToken, code: "123456", email: "johnatthan.doe@gmail.com" ) // Successfully verified email } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### code string The verification code sent to the user. ##### email string The email address of the profile. ## Response **Error**: [ReachFiveError](#reachfiveerror) If verified, the response indicates "Successfully verified email". If the email is already verified, the response indicates "Email already verified". The promise is rejected and returns a `ReachFiveError` if: - The parameters are invalid. - The verification code is incorrect or expired. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # verifyPasswordlessCode URL: /sdk-ios/verifyPasswordlessCode.html AppDelegate.reachfive().verifyPasswordlessCode([verifyAuthCodeRequest](#verifyAuthCodeRequest)) ## Description Verify the verification code sent by SMS to the specified phone number or email. ## Examples ```swift import Reach5 let verifyAuthCodeRequest = VerifyAuthCodeRequest( email: emailInput, verificationCode: verificationCodeInput ) do { let authToken = try await AppDelegate.reachfive().verifyPasswordlessCode(verifyAuthCodeRequest: verifyAuthCodeRequest) // Do something } catch { // Return a ReachFive error } ``` ```swift import Reach5 let verifyAuthCodeRequest = VerifyAuthCodeRequest( phoneNumber: phoneNumberInput, verificationCode: verificationCodeInput ) do { let authToken = try await AppDelegate.reachfive().verifyPasswordlessCode(verifyAuthCodeRequest: verifyAuthCodeRequest) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### verifyAuthCodeRequest VerifyAuthCodeRequest ##### phoneNumber string The phone number of the profile. > Both the international format and the national conventions of the account’s country are accepted if configured in account settings. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### verificationCode string **Required** The verification code sent by SMS. ##### email string The email address. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) If the credentials are valid, the promise will return the profile’s authentication token. Otherwise it will be rejected and will return a `ReachFiveError`. ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # verifyPhoneNumber URL: /sdk-ios/verifyPhoneNumber.html AppDelegate.reachfive().verifyPhoneNumber( [authToken](#authToken), [phoneNumber](#phoneNumber), [verificationCode](#verificationCode) ) ## Description Verify the profile’s phone number with the verification code sent by SMS after signup. > - The profile must have been granted the `full_write` scope at the last authentication. > ## Examples ```swift import Reach5 let profileAuthToken: AuthToken = // Here paste the authorization token of the profile retrieved after login do { try await AppDelegate.reachfive().verifyPhoneNumber( authToken: profileAuthToken, phoneNumber: "+33750253354", verificationCode: "501028" ) // Do something } catch { // Return a ReachFive error } ``` ## Parameters ##### authToken AuthToken Authorization token of the profile retrieved from login. ##### idToken string The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. ##### accessToken string The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken string The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. ##### tokenType string The type of token. Always equal to `Bearer`. ##### expiresIn number The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIdUser The user’s information contained in the ID token. ##### phoneNumber string The phone number of the profile. Both the international format and the national conventions of the account’s country are accepted if configured in account settings. ##### verificationCode string The verification code sent by email or SMS. ## Response **Error**: [ReachFiveError](#reachfiveerror) If the `full_write` scope is missing or if the verification code is incorrect, the promise will be rejected and will return a `ReachFiveError`. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # webviewLogin URL: /sdk-ios/webviewLogin.html AppDelegate.reachfive().webviewLogin(WebviewLoginRequest( [presentationContextProvider](#presentationContextProvider) // optional [state](#state), [nonce](#nonce), [scope](#scope), **(1)** [origin](#origin), [prefersEphemeralWebBrowserSession](#prefersEphemeralWebBrowserSession), **(2)** [webSessionMode](#webSessionMode), **(3)** [loginUrlFragment](#loginUrlFragment), **(4)** )) - (1) Scope isn’t explicitly required. If not provided here, it defaults to the scopes set up in the client configuration which is picked up when you initialize the iOS SDK. - (2) Available starting with version 7.1.3 - (3) Optional; defaults to `.customScheme`, which also covers providers that hand the flow off to their own native app. Use `.universalLink` only when the login must come back on a universal link intercepted in the sheet — see [providerCreator.adoc#universal-link-web-providers](providerCreator.html#universal-link-web-providers) and [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - (4) Optional; requires [request orchestration tokens](../docs/orchestration-token.html) to be enabled for the client. ## Description Opens a **secure** webview through the authorization endpoint. > You must have configured a Login URL and enabled [request orchestration tokens](../docs/orchestration-token.html) for your identity client. > > Orchestrated flows are supported from [version `1.24.0`](https://github.com/ReachFive/identity-web-core-sdk/releases/tag/v1.24.0) for the [Core SDK](../sdk-core/index.html) and [version `1.16.0`](https://github.com/ReachFive/identity-web-ui-sdk/releases/tag/v1.16.0) for the [UI SDK](../sdk-ui/index.html). - If end-users have an active web SSO session, then the authorization endpoint immediately redirects to the application. - If end-users do not have an active web SSO session, they are redirected to the client’s Login URL for authentication. When logging in with secure webview, a dialog pops up where you must select **Continue** and acknowledge that by continuing "This allows the app and the website to exchange information about you". ![secure login dialog](_images/secure-login-dialog.png) ### One web login at a time `webviewLogin` and a `login` on a [web provider](providerCreator.html) share a single web session. A call made while another one is still in progress ends with `AuthCanceled` and leaves the login under way untouched. To end a web login early, cancel the `Task` that started it: the sheet closes and the call returns `AuthCanceled`. A SwiftUI `.task` or any `Task` you cancel when tearing down your screen does this for you. ## Usage Build the request with `presenting: Presentation(from: self)` from the initiating [UIViewController](https://developer.apple.com/documentation/uikit/uiviewcontroller): the SDK derives the presentation context itself, as it does for [`provider.login`](getProvider.html). Alternatively, pass your own [`presentationContextProvider`](#presentationContextProvider) — any object implementing `ASWebAuthenticationPresentationContextProviding`, for instance the view controller itself: ```swift func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { view.window! } ``` ## Examples ```swift do { let authToken = try await AppDelegate.reachfive().webviewLogin(WebviewLoginRequest( state: "zf3ifjfmdkj", nonce: "n-0S6_PzA3Ze", scope: ["openid", "profile", "email"], presenting: Presentation(from: self) )) // Get the profile's authentication token } catch { // Return a ReachFive error } ``` ## Parameters ##### presentationContextProvider string A delegate that provides a display context whereby the system is able to present an authentication session to the user. > For more, see [Apple docs](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession/3237232-presentationcontextprovider). For more, see [Apple docs](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession/3237232-presentationcontextprovider). ##### state string The OAuth2 state value. > This is a random string sent to the auth server. The auth server sends the state parameter back. If they match, you’re good to go. If they don’t match, someone (or something) else initiated the auth request. This is a random string sent to the auth server. The auth server sends the state parameter back. If they match, you’re good to go. If they don’t match, someone (or something) else initiated the auth request. ##### nonce string An OIDC nonce value. > This binds the tokens with the client and serves as a token validation parameter. This binds the tokens with the client and serves as a token validation parameter. ##### scope string\[\] The scopes granted to the profile. Make sure they are allowed by the client. Default scopes are the allowed scopes set up in the client’s configuration. ##### origin string The origin of the call. ##### prefersEphemeralWebBrowserSession Bool A Boolean value that indicates whether the session should ask the browser for a private authentication session. The value of this property is false by default. > For more, see [here](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession/prefersephemeralwebbrowsersession). For more, see [here](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession/prefersephemeralwebbrowsersession). ##### webSessionMode WebSessionMode Controls the behavior of the `ASWebAuthenticationSession` callback and its `redirect_uri`. Defaults to `.customScheme`. Values - `.customScheme` (default): the SDK’s custom scheme. Covers a redirect intercepted inside the sheet **and** one delivered to [application(\_:open:options)](application/applicationOpenUrl.html) when a provider hands the flow off to their own native app. - `.universalLink(URL)` (iOS 17.4+): the universal-link redirect is intercepted directly inside the authentication sheet. Requires the `webcredentials:` Associated Domain. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). > See the [WebProvider](providerCreator.html) entry for a ready-made provider using this mechanism. See the [WebProvider](providerCreator.html) entry for a ready-made provider using this mechanism. ##### loginUrlFragment \[String: String\]? Key/value pairs propagated in the **fragment** of the [`/oauth/authorize` URL](https://docs.identity.purse.eu/openapi/identity.html#operation/authorizeUser) (e.g., `#key=value&key2=value2`). Intended for the token-orchestration flow: [`/oauth/authorize`](https://docs.identity.purse.eu/openapi/identity.html#operation/authorizeUser) redirects to the client’s Login URL. A fragment, unlike a query parameter, survives that redirect; the browser reapplies it onto the redirect target. The Login URL can then read it via `window.location.hash` to customize itself (logo, colors) per calling channel. > Requires the client to have a Login URL configured and [request orchestration tokens](../docs/orchestration-token.html) enabled; otherwise this parameter has no effect. Requires the client to have a Login URL configured and [request orchestration tokens](../docs/orchestration-token.html) enabled; otherwise this parameter has no effect. ## Response - **Type**: [AuthToken](#authtoken) - **Error**: [ReachFiveError](#reachfiveerror) ### AuthToken The authentication token. ##### idToken The ID token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) that contains the profile’s information. This is only available when the `openid` [scope](../docs/scope.html) is requested. ##### accessToken The authorization credential [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to access the Purse Identity API. ##### refreshToken The refresh token [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) used to obtain new access tokens once they expire. This is only available when the `offline_access` [scope](../docs/scope.html) is requested. ##### tokenType The type of token. Always equal to `Bearer`. ##### expiresIn The lifetime in seconds of the access token. If `expiresIn` is less than or equal to `0`, the `AuthToken` is expired. ##### user OpenIDUser The user’s information contained in the ID token. ##### id string The identifier of the user. ##### name string The full name of the user in displayable form including all name parts, possibly including titles and suffixes, ordered according to the user’s locale and preferences. ##### preferredUsername string The shorthand name by which the user wishes to be referred to. ##### givenName string The given name or first name of the user. ##### familyName string The surname or last name of the user. ##### middleName string The middle name of the user. ##### nickname string The casual name of the user that may or may not be the same as the givenName ##### picture string The URL of the user’s profile picture. ##### website string The URL of the user’s web page or blog. ##### email string The user’s preferred e-mail address. ##### emailVerified boolean True if the user’s e-mail address has been verified; otherwise false. ##### gender string The user’s gender. ##### zoneinfo string The string from zoneinfo time zone database representing the user’s time zone. ##### locale string The user’s language code in lowercase and country code in uppercase, separated by a dash. ##### phoneNumber string The user’s preferred telephone number. ##### phoneNumberVerified boolean `true` if the user’s phone number has been verified; otherwise `false`. ##### address string The user’s preferred postal address. ### ReachFiveError Based on the problem, the `ReachFiveError` will be: - `AuthCanceled`: Nothing happened, and nothing is expected of you — ignoring it is a valid way to handle it. This can happen for any of the following reasons: - The user canceled the request. - No passkey was saved for your app. - A web login was dropped because another one was already in progress. See [webviewLogin](webviewLogin.html). - The app is not associated with the host of an [`WebProvider` `.universalLink`](providerCreator.html#universal-link-web-providers) callback. See [guides/apple-app-site-association.adoc#webcredentials](guides/apple-app-site-association.html#webcredentials). - `RequestError(apiError: ApiError)` for a Bad Request (status 400) error. - `AuthFailure(reason: String, apiError: ApiError?)` mainly for Unauthorized (status 401) error. - `TechnicalError(reason: String, apiError: ApiError?)` if it’s an Internal Server Error (status 500) or other internal errors. #### ApiError ##### error string The main error message. ##### errorId string The identifier of the error. ##### errorUserMsg string The user-friendly error message. > This property is translated according to the user’s OS and app settings. Currently supported languages: Currently supported languages - `ar` - العربية _Arabic_ - `de` - Deutsch _German_ - `en` - English - `es` - Español _Spanish_ - `fr` - Français _French_ - `hu` - Magyar _Hungarian_ - `it` - Italiano _Italian_ - `jp` - 日本 _Japanese_ - `ko` - 한국인 _Korean_ - `nl` - Nederlands _Dutch_ - `pt` - Portuguese - `ru` - Ру́сский _Russian_ - `sk` - Slovenský _Slovak_ - `zh-CN` - _People’s Republic of China Simplified Chinese_ - `zh-Hans` - _Simplified Chinese_ - `zh-Hant` - _Traditional Chinese_ - `zh-HK` - _Hong Kong Traditional Chinese_ - `zh-MO` - _Macao Traditional Chinese_ - `zh-SG` - _Singapore Simplified Chinese_ - `zh-TW` - _Taiwan Traditional Chinese_ This property is translated according to the user’s OS and app settings. Currently supported languages: ##### errorMessageKey string The error message key. ##### errorDescription string The technical error message. ##### errorDetails FieldError\[\] ##### field string The field concerned by the error. ##### message string The message error returned for the `field`. ##### code string The code error returned for the `field`. --- # application(_:continue:restorationHandler:) URL: /sdk-ios/application/applicationContinueUserActivity.html AppDelegate.reachfive().application([application](#application), continue: [userActivity](#applicationUserActivity), restorationHandler: [restorationHandler](#applicationRestorationHandler)) ## Description Allows Purse Identity to handle user activity continuation such as handoffs, and more importantly, universal links. This method is required by [WeChat](../index.html#wechat-connect) and by a [custom provider](../guides/custom-provider.html) whose callback arrives as a universal link (`NSUserActivityTypeBrowsingWeb`). > [`WebProvider`](../providerCreator.html) does not support leaving your app and coming back with a universal link. The universal link callback in `.universalLink` mode is intercepted by the authentication sheet itself. Call this method in response to the equivalent UIKit method [`application(_:continue:restorationHandler:)_`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/)_. If your app uses scenes, forward [`scene(`](https://developer.apple.com/documentation/uikit/uiscenedelegate/)_[`:continue:)`](https://developer.apple.com/documentation/uikit/uiscenedelegate/) here as well. > The method returns a `Bool` that tells you whether Purse Identity actually consumed the activity. Do not assume Purse Identity handles every universal link you forward. When `false` is returned, your app should route the link itself. > > Delivering an https URL into the app requires an `applinks:` Associated Domain. See [guides/apple-app-site-association.adoc#applinks](../guides/apple-app-site-association.html#applinks). ## Examples ```swift import Reach5 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { return AppDelegate.reachfive().application(application, continue: userActivity, restorationHandler: restorationHandler) } } ``` ## Parameters ##### application UIApplication The UIKit Application instance. For more details, see [Apple: UIApplication](https://developer.apple.com/documentation/uikit/uiapplication). ##### userActivity NSUserActivity The activity object containing the data associated with the task the user was performing. ##### restorationHandler (\[UIUserActivityRestoring\]?) → Void A block to execute if your app creates objects to perform the task the user was performing. --- # applicationDidBecomeActive(_:) URL: /sdk-ios/application/applicationDidBecomeActive.html AppDelegate.reachfive().applicationDidBecomeActive([application](#application)) ## Description This method finalises SDK activation after launch or when resuming from the background. It ensures the SDK is ready for user interaction. Call this method in response to the equivalent UIKit method [`applicationDidBecomeActive(_:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/). Used by [Facebook](../index.html#facebook-native-provider). ## Examples ```swift import Reach5 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func applicationDidBecomeActive(_ application: UIApplication) { AppDelegate.reachfive().applicationDidBecomeActive(application) } } ``` ## Parameters ##### application UIApplication The UIKit Application instance. For more details, see [Apple: UIApplication](https://developer.apple.com/documentation/uikit/uiapplication). --- # application(_:didFinishLaunchingWithOptions:) URL: /sdk-ios/application/applicationDidFinishLaunchingWithOptions.html AppDelegate.reachfive().application([application](#application), didFinishLaunchingWithOptions: [launchOptions](#applicationLaunchOptions)) ## Description Allows Purse Identity to initialize the iOS SDK, by fetching information from the server about the client (e.g., default scopes, enabled features) and initializing any configured providers. Call this method in response to the equivalent UIKit method [`application(_:didFinishLaunchingWithOptions:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/). ## Examples ```swift import Reach5 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return AppDelegate.reachfive().application(application, didFinishLaunchingWithOptions: launchOptions) } } ``` ## Parameters ##### application UIApplication The UIKit Application instance. For more details, see [Apple: UIApplication](https://developer.apple.com/documentation/uikit/uiapplication). ##### launchOptions \[UIApplication.LaunchOptionsKey: Any\]? A dictionary indicating the reason the app was launched (if any). --- # application(_:open:options) URL: /sdk-ios/application/applicationOpenUrl.html AppDelegate.reachfive().application([application](#application), open: [url](#applicationOpenUrl), options: [options](#applicationOptions)) ## Description Allows Purse Identity to handle URLs in the following format: - `reachfive-clientId://` This callback URL is used to open the app from another app or by in-app web-based flow. The calling app can be a provider native app, or an email client in passwordless, MFA step-up or account recovery flows. Call this method in response to the equivalent UIKit method [`application(_:open:options)_`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/)_. If your app uses scenes, forward [`scene(`](https://developer.apple.com/documentation/uikit/uiscenedelegate/)_[`:openURLContexts:)`](https://developer.apple.com/documentation/uikit/uiscenedelegate/) here as well. > The method returns a `Bool` that tells you whether Purse Identity actually consumed the URL. Do not assume Purse Identity handles every URL you forward. When `false` is returned, your app should route the link itself. ## Examples ```swift import Reach5 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { return AppDelegate.reachfive().application(app, open: url, options: options) } } ``` ## Parameters ##### application UIApplication The UIKit Application instance. For more details, see [Apple: UIApplication](https://developer.apple.com/documentation/uikit/uiapplication). ##### url URL The URL resource to open. ##### options \[UIApplication.OpenURLOptionsKey : Any\] A dictionary of URL handling options. For more details, see [Apple: \_:open:options:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/application\(_:open:options:\)). --- # Account recovery URL: /sdk-ios/guides/account-recovery.html You can initiate account recovery with the [requestAccountRecovery](../requestAccountRecovery.html) or [requestPasswordReset](../requestPasswordReset.html) method, depending on your implementation of our SDK. In any case, account recovery is a multi-step account recovery process, which enables your users to regain access to their accounts by updating their password or resetting passkeys. This guide outlines the steps required to implement the full flow, from triggering the recovery request to completing the action with a verification code. Integrators must handle each step, including optional callback mechanisms, to ensure a seamless experience. ![flow accountRecovery](../_images/flows/flow_accountRecovery.jpg) ## Initiate the recovery request First, you need to: 1. Call [requestAccountRecovery](../requestAccountRecovery.html) or [requestPasswordReset](../requestPasswordReset.html) with the user’s identifier (e.g., email or phone number). 2. Our SDK sends a verification code to the user via the configured channel (e.g., email/SMS). Email example ```swift do { try await AppDelegate.reachfive().requestAccountRecovery( email: "john.doe@gmail.com", redirectUrl: URL(string: "reachfive-clientId://account-recovery")! ) // Do something } catch { // Return a ReachFive error } ``` Email example ```swift do { try await AppDelegate.reachfive().requestPasswordReset( email: "john.doe@gmail.com", redirectUrl: URL(string: "reachfive-clientId://password-reset")! ) // Do something } catch { // Return a ReachFive error } ``` ## Capture the verification code **Optionally**, implement `[addAccountRecoveryCallback](#addaccountrecoverycallback)` to automatically receive the verification code via deep link. You should provide a UI for manual verification code entry if callback isn’t used. `[addAccountRecoveryCallback](#addaccountrecoverycallback)` will autofill or bypass the UI in this case though. You should store the code securely to [complete the recovery process](#complete-the-recovery-process). ### addAccountRecoveryCallback `addAccountRecoveryCallback` only works when `requestAccountRecovery` is used, not with `requestPasswordReset`. `addAccountRecoveryCallback` allows you to register a closure that automatically receives the verification code. This is typically delivered via a deep link after the user interacts with the recovery email or SMS. This optional approach eliminates the need for manual code entry by capturing the code directly in the app. Once set, the closure is triggered by our iOS SDK with the verification code, which can then be passed to [updatePassword](#complete-the-recovery-process) or [resetPasskeys](#complete-the-recovery-process) to complete the recovery process. Refer to [addAccountRecoveryCallback](../addAccountRecoveryCallback.html) for further details. ## Complete the recovery process To complete the recovery process, use the verification code to finalize recovery: 1. Call [updatePassword](../updatePassword.html) with the code and new password to update the user’s password. This is common for account recovery or password reset flows. 2. Alternatively, call [resetPasskeys](../resetPasskeys.html) with the code to reset passkeys (specific to account recovery). 3. Be sure to handle both success (e.g., “Recovery complete”) and errors (e.g., invalid/expired code). --- # apple-app-site-association URL: /sdk-ios/guides/apple-app-site-association.html An [`apple-app-site-association`](https://developer.apple.com/documentation/xcode/supporting-associated-domains) file tells iOS that your app is associated with a given https host. You need it for two different Purse Identity features on iOS: - [Passkeys](passkeys.html), whose Relying Party ID is that host. - [`WebProvider` `.universalLink`](../providerCreator.html#universal-link-web-providers) (and [`webviewLogin`](../webviewLogin.html) with `.universalLink(_:)`), whose OAuth `redirect_uri` is an https URL on that host. A custom provider or [WeChat](../index.html#wechat-connect) that receives its callback as a universal link **into the app** also needs this file, with an `applinks` section. You also need it so that passwords your users saved for your website can be autofilled in your app. ## Host the file Serve the file at `https:///.well-known/apple-app-site-association` with a `200` response and a JSON `Content-Type`. A redirect or a non-JSON content type causes verification to fail. `` is the host you declare in Associated Domains: - For passkeys, the Relying Party ID (see [Passkeys on iOS](passkeys.html)). - For `.universalLink`, the host of the `universalLink` URL returned by Purse Identity for that provider. If Purse Identity should serve the file for passkeys on Hosted Pages, paste it in the Purse Identity Console as described in [Passkeys: Hosted pages](passkeys.html#hosted-pages). Otherwise, host it yourself on ``. ## Associated Domains entitlements In Xcode, add the Associated Domains capability and declare the entries that match the sections in your association file. ### webcredentials: Lets the system treat your app as associated with credentials and with ``ASWebAuthenticationSession’s `.https`` callback on that host. Declare this entry for: - [Passkeys](passkeys.html) on that Relying Party ID. - [`WebProvider`](../providerCreator.html) or [`webviewLogin`](../webviewLogin.html) with `.universalLink` (iOS 17.4+). If this entry or the matching `webcredentials` section is missing, the session ends with `AuthCanceled`. ### applinks: Lets iOS deliver an https URL on that host to your app as a universal link (`NSUserActivityTypeBrowsingWeb`), which you forward to [`application(_:continue:)`](../application/applicationContinueUserActivity.html). Declare this entry only when a **provider** must receive that link in the app: - [WeChat](../index.html#wechat-connect) - A [custom provider](custom-provider.html) whose callback arrives as a universal link Do **not** add `applinks:` for [`WebProvider`](../providerCreator.html) `.universalLink`. That mode intercepts the redirect inside the authentication sheet; `application(_:continue:)` is not on the path. Do **not** add `applinks:` for `.customScheme`, including providers that hand the flow off to their own native app. ## File contents Include the sections that correspond to the entitlements you declared. The sample below includes both, for a host used in more than one mode. apple-app-site-association example ```json { "applinks": { "details": [ { "appIDs": ["ABCDE12345.com.example.app"], (1) "components": [ {"/": "/callback"} (2) ] } ] }, "webcredentials": {"apps": ["ABCDE12345.com.example.app"]} (3) } ``` - (1) `.`. - (2) Restrict to the callback path iOS should deliver into the app. Omit the whole `components` array to match every path on the host. Only needed if you declare `applinks:`. - (3) Needed if you declare `webcredentials:` (`.universalLink`, or [passkeys](passkeys.html) on the same host). > If you declare `applinks:` and restrict `components` to a path, make sure that path matches both the success callback (`?code=…​`) **and** the OAuth error callback (`?error=…​`). --- # Migrating from BrightFutures to Swift Concurrency URL: /sdk-ios/guides/migrate-futures.html BrightFutures is a Swift library for managing asynchronous operations using _futures_. A future represents a value that may become available later, suitable for tasks like authentication in the Purse Identity iOS SDK. The `.onSuccess` and `.onFailure` methods are one of the main ways to handle successful results and errors, respectively. Why is BrightFutures being discontinued? BrightFutures development stopped due to Swift’s native concurrency features (see [Swift docs: Concurrency](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/)), which offer a standardized alternative for asynchronous operations. BrightFutures was used for asynchronous operations like `refreshAccessToken`, which uses exchange a refresh token and returns an authentication token or a Purse Identity error. The _Reach5Future SDK_ will be released to maintain compatibility with BrightFutures' `Future` for existing users. The main Purse Identity iOS SDK will adopt `async`/`await` for future development. ## Using `async throws` for Asynchronous Operations Swift’s native concurrency introduces `async throws` to declare functions that are both asynchronous and capable of throwing errors. For example, the Purse Identity SDK’s `refreshAccessToken` and `registerNewPasskey` methods are declared as: ```swift func refreshAccessToken(authToken: AuthToken) async throws -> AuthToken (1) func registerNewPasskey(withRequest request: NewPasskeyRequest, authToken: AuthToken) async throws (2) ``` - (1) The `async` keyword indicates the function performs asynchronous work (e.g., network requests), requiring `await` when called. - (2) The `throws` keyword means it may throw an error, usually a `ReachFiveError`, requiring `try` within a `do`/`catch` block. This replaces BrightFutures' `Future`, where `.onSuccess` handles the `AuthToken` and `.onFailure` handles errors. ## Replacing result handling of Future with `do/catch` and `try await` Swift’s native concurrency uses asynchronous methods, with `do-catch` statements to handle errors, replacing BrightFutures. The `do` block processes successful results (like `.onSuccess`), and the `catch` block handles errors (like `.onFailure`). When calling an `async throws` function, `try await` is used within a `do` clause to capture the result or throw an error to the `catch` clause. ### Example: Migrating `refreshAccessToken` Below is the `refreshAccessToken` method in BrightFutures and its Swift concurrency equivalent, using `async throws` and `do-catch`. ```swift AppDelegate.reachfive() .refreshAccessToken(authToken: staleToken) .onSuccess { freshToken in (1) // Use the profile's authentication token goToProfile(freshToken) } .onFailure { error in (1) // The error has type ReachFiveError print(error.message()) AppDelegate.storage.removeToken() } ``` - (1) This uses `.onSuccess` to handle the `AuthToken` and `.onFailure` to manage errors. ```swift do { (1) let freshToken = try await AppDelegate.reachfive().refreshAccessToken(authToken: staleToken) Task { @MainActor in (2) goToProfile(freshToken) } } catch { (3) // The error has type Error print(error.localizedDescription) (4) AppDelegate.storage.removeToken() } ``` - (1) The `do` block uses `try await` to call `async throws` methods, handling the successful `AuthToken` and navigation to the profile page. - (2) `Task { @MainActor in …​ }` creates an asynchronous context on the main thread, ensuring UI updates are safe. This is required when calling `async` methods from a synchronous context, such as a UIKit or AppKit event handler, and when you need to update UI elements. - (3) The `catch` block manages errors from any `throws` method. - (4) Migrate usage of ReachFiveError.message() to Error.localizedDescription, or cast the error ## Thread Management for UI Operations When using Swift concurrency, asynchronous operations like `refreshAccessToken` must be wrapped in a `Task` when called from a synchronous context, such as a UIKit or AppKit event handler. For operations that update UI elements (e.g., displaying the profile in `goToProfile`), the `Task` should be annotated with `@MainActor` to ensure thread safety, as UI updates in iOS must occur on the main thread. Unlike BrightFutures, which use a default threading behaviour where methods that started from the main thread would execute all their asynchronous operations also in the main thread, Swift concurrency uses background threads a lot more. This requires integrators to be more explicit about threading. The example above uses `Task { @MainActor in …​ }` to ensure `goToProfile` occur on the main thread, aligning with the `async throws` pattern. ## Key Differences and Benefits - **Syntax**: `do`/`catch` with `async`/`await` is native, reducing reliance on BrightFutures. - **Structured Concurrency**: Swift simplifies task lifecycles and cancellation compared to BrightFutures' closures. - **Error Handling**: `catch` supports specific error types (e.g., `catch ReachFiveError.AuthFailure { …​ }`) for precise control. - **Thread Management**: Swift concurrency requires explicit handling of threads for UI operations, offering more control but demanding careful implementation. - **Integration**: Using this approach, you have better integration with Swift’s native concurrency model, making your code more idiomatic and maintainable. --- # Migrating to the Reach5Future SDK compatibility bridge URL: /sdk-ios/guides/migrate-reach5future.html The **Reach5Future SDK** is a compatibility bridge for our iOS SDK customers who rely on BrightFutures for asynchronous operations and want to adopt Swift’s native concurrency features one step at a time. It ensures continued support for `Future`\-based methods like `.onSuccess` and `.onFailure`, maintaining compatibility with existing codebases. Our main iOS SDK is transitioning to `async throws` for future development, offering a modern, standardized approach to asynchronous programming. The **Reach5Future SDK** allows a gradual migration, enabling customers to maintain their BrightFutures-based implementations while optionally integrating Swift concurrency in the same project. ## Installation Instructions To use the **Reach5Future SDK**, integrate it into your project alongside or in place of the main Purse Identity iOS SDK. The compatibility bridge is provided as a separate module to ensure BrightFutures-based methods remain functional. ### Installation Add the package dependency with XCode using this package URL: ```none https://github.com/ReachFive/reachfive-ios-future.git ``` Or directly add this to the dependencies in `Package.swift` ```swift dependencies: [ .package(url: "https://github.com/ReachFive/reachfive-ios-future.git", .upToNextMajor(from: "11.1.1")) ] ``` ## Handling compilation errors When using the **Reach5Future SDK**, you may encounter compilation errors related to ambiguous return types in callbacks, particularly in nested `.map` and `.flatMap`. To resolve this, explicitly specify the return type of the callback methods. In this example, we try to register a new credential with a potentially stale token, and refresh it if necessary. ```swift AppDelegate.reachfive() .mfaStart(registering: credential, authToken: authToken) .recoverWith { error in guard case .AuthFailure(_, let apiError) = error, apiError?.errorMessageKey == "error.accessToken.freshness" else { return Future(error: error) } // Automatically refresh the token if it is stale return AppDelegate.reachfive() .refreshAccessToken(authToken: authToken).flatMap { (freshToken: AuthToken) -> Future in (1) AppDelegate.storage.setToken(freshToken) return AppDelegate.reachfive().mfaStart(registering: credential, authToken: freshToken) } } ``` - (1) Specify the return type explicitly to resolve the potential ambiguity in the callback. ## Explicit main thread binding Purse Identity SDK, up to version 8, used the default threading behaviour from BrightFuture, which runs a block of code in the main queue if the calling method is on the main thread, and from the global queue if the caller is not on the main thread. **Reach5Future SDK** offers the same API as Purse Identity SDK version 8, but with the same underlying implementation as Purse Identity SDK version 9, which uses async/await. This new underlying system may make different choices of execution queue in some context. Thus, you may need to add explicit thread management directives in your code, with standard tools like `@MainActor`, or with BrightFuture directives. Example ```swift let nativeRequest = NativeLoginRequest(presenting: Presentation(from: self), origin: "Password Manager") AppDelegate.reachfive() .login(withRequest: nativeRequest, usingModalAuthorizationFor: [.Password], display: .Always) .onSuccess(DispatchQueue.main.context) { loginFlow in self.handleLoginFlow(flow: loginFlow) // update the UI, we're on the main thread } .onFailure(DispatchQueue.global().context) { error in print(error.message()) // not on main thread } ``` ## Mixed approaches The **Reach5Future SDK** allows mixing BrightFutures' `Future`\-based methods with Swift’s `async throws` and `do-catch` in the same file, enabling a gradual migration to our main iOS SDK’s concurrency model. You can call `Future`\-based methods from the **Reach5Future SDK** alongside `async throws` methods from the main SDK, wrapping `async` calls in a `Task` with `@MainActor` for synchronous contexts and UI updates. Example ```swift @IBAction func login(_ sender: Any) { let password = … let username = … // Calling an async method guard password.isEmpty else { Task { await loginWithPassword(username: username, password: password) } return } // Using Reach5Future SDK with BrightFutures let request = NativeLoginRequest(presenting: Presentation(from: self), origin: "DemoController.login") AppDelegate.reachfive().login(withRequest: request, usingModalAuthorizationFor: [.Passkey], display: .Always) .onSuccess(callback: handleLoginFlow) .onFailure { error in presentErrorAlert(title: "Login failed", error.message()) } } // Using main ReachFive SDK with async/await func loginWithPassword(username: String, password: String) async { let origin = "DemoController.loginWithPassword" await handleLoginFlow { if username.contains("@") { try await AppDelegate.reachfive().loginWithPassword(email: username, password: password, origin: origin) } else { try await AppDelegate.reachfive().loginWithPassword(phoneNumber: username, password: password, origin: origin) } } } ``` --- # Implement a custom provider URL: /sdk-ios/guides/custom-provider.html Our built-in [provider creators](../providerCreator.html) cover the most common use cases for provider creation: - `GoogleProvider` - `FacebookProvider` - `AppleProvider` - `WeChat` - `WebProvider` This custom provider guide instructs you how to implement a provider that none of the built-ins model such as a social/SSO provider with its own native SDK, or a login flow that none of the built-ins model. If your provider has no native SDK component and only needs to choose **how** its `ASWebAuthenticationSession` returns to the app (custom scheme or universal link), you don’t need a custom provider, instead configure a [`WebProvider`](../providerCreator.html). That includes providers that hand the flow off to their own native app. ## The two protocols A provider is made of two pieces, both found in `Sources/Core/Classes/Provider.swift`: - `ProviderCreator`: a lightweight factory you list in `ReachFive(providersCreators:)`. It carries a `name` and an optional `variant` and builds the actual `Provider` once Purse Identity has fetched that provider’s configuration from the backend. - `Provider`: the object doing the actual work: `login`, `logout`, and the app-lifecycle hooks it needs to intercept its own callback. ```swift public protocol ProviderCreator { var name: String { get } var variant: String? { get } func create(reachFive: ReachFive, providerConfig: ProviderConfig, clientConfigResponse: ClientConfigResponse) -> Provider } public protocol Provider { var name: String { get } func login(scope: [String]?, origin: String, presenting: Presentation) async throws -> AuthToken func logout() async throws // Default (no-op) implementations provided — override only what your provider needs: func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool func applicationDidBecomeActive(_ application: UIApplication) func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool } ``` > `name` must match the provider’s name as configured on your Purse Identity Console. This is how Purse Identity matches your `ProviderCreator` against the provider configurations it fetches from the backend. A configured provider with no matching creator still logs in, falling back to either native Sign in with Apple or a generic web-based provider. ## Register the custom provider ```swift let reachfive = ReachFive( sdkConfig: SdkConfig(domain: DOMAIN, clientId: CLIENT_ID), providersCreators: [MyProvider(variant: "ios")] ) ``` ## Example: wrapping a native SDK The creator is a thin factory. The actual `Provider` calls into the third-party native SDK, then exchanges its result for a Purse Identity `AuthToken`. Your `create` method receives the shared `ReachFive` instance, which the SDK also stores in `ReachFive.providers`. When you build your `Provider`, decide how to access it from `login`: > When `create(reachFive:)` runs, the SDK has already decided to keep your `Provider` in `ReachFive.providers`. If your provider also keeps a **strong** reference back to that same `ReachFive` instance, neither object can ever be released — a **retain cycle** (`ReachFive` ↔ `Provider`) that pins the whole SDK object graph in memory. > > Use `weak var reachFive` in your provider, or copy only the properties you need at init time (e.g. `sdkConfig`, `reachFiveApi`, `scope`). > > For background on why this happens and how `weak` breaks the cycle, see [Apple: strong reference cycles between class instances](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting/#Strong-Reference-Cycles-Between-Class-Instances) and [`weak` references](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting/#Weak-References). ```swift public class MyProvider: ProviderCreator { public var name: String = "my-provider" public var variant: String? public init(variant: String? = nil) { self.variant = variant } public func create(reachFive: ReachFive, providerConfig: ProviderConfig, clientConfigResponse: ClientConfigResponse) -> Provider { ConfiguredMyProvider(reachFive: reachFive, providerConfig: providerConfig) } } class ConfiguredMyProvider: NSObject, Provider { let name: String private weak var reachFive: ReachFive? // weak: see the retain-cycle note above init(reachFive: ReachFive, providerConfig: ProviderConfig) { self.name = providerConfig.provider self.reachFive = reachFive } func login(scope: [String]?, origin: String, presenting: Presentation) async throws -> AuthToken { // 1. Drive your native SDK's own login UI/flow here, e.g.: let code = try await MyNativeSDK.shared.login(presenting: presenting.presentingViewController()) // 2. Exchange its authorization code for a ReachFive AuthToken. guard let reachFive else { throw ReachFiveError.TechnicalError(reason: "ReachFive instance was deallocated") } return try await reachFive.authWithCode(code: code, pkce: Pkce.generate()) } func logout() { MyNativeSDK.shared.logout() } } ``` ## Example: a fully custom web flow If your provider has no native SDK but needs behaviour `WebProvider` doesn’t offer, drive `ASWebAuthenticationSession` yourself (or reuse `reachFive.webviewLogin(_:)`, see [webviewLogin](../webviewLogin.html)) inside `login`, then return the resulting `AuthToken` the same way. ## App-lifecycle hooks Only implement the hooks your provider actually needs to intercept its own callback; every other hook has a default no-op implementation. ##### application(\_:open:options:) Your provider’s callback arrives through a custom URL scheme (`myapp://…​`). ##### application(\_:didFinishLaunchingWithOptions:) Your provider’s native SDK needs an explicit startup call. An example of this is registering itself before the app finishes launching. ##### applicationDidBecomeActive(\_:) Your provider needs to react to the app returning to the foreground. An example of this is resuming a paused native SDK session. ##### application(\_:continue:restorationHandler:) Your provider’s callback arrives as a **universal link** (`NSUserActivityTypeBrowsingWeb`). Return `true` only if you actually consumed the activity. Purse Identity relies on that return value (see [application(\_:continue:restorationHandler:)](../application/applicationContinueUserActivity.html) for details). Declare `applinks:` and the matching `applinks` section in `apple-app-site-association` (see [guides/apple-app-site-association.adoc#applinks](apple-app-site-association.html#applinks)). --- # Passkeys on iOS URL: /sdk-ios/guides/passkeys.html ## Introduction This guide explains how to implement passkey registration and authentication workflow on iOS applications. > The following code samples and screenshots are issued from our example application using our SDK. Feel free to check out the [Github project](https://github.com/ReachFive/reachfive-ios). ## Passkeys prerequisites To successfully enable passkeys for iOS: - Enable the **WebAuthn** feature on your ReachFive account. > You may need to contact [support](mailto:support@reach5.co) to have this enabled if you do not see it on your Purse Identity Console. You’ll also need: - An iOS device that supports passkeys. - iOS OS 16 or later. - To install our [SDK Core](../index.html#sdk-core) which exposes all of the passkey methods. - End users and those testing the setup need an iCloud account with 2-step authentication enabled. iCloud Keychain must be activated. ## Get started This section describes important terms and concepts as well the steps needed to get started with passkeys for iOS with Purse Identity. ### Relying Party ID The Relying Party ID is the domain to which passkeys are bound. Once bound to a domain, it can be used on subdomains but not other full domains. Using the Relying Party ID of `boulangerie.com` allows the use of credentials on `help.boulangerie.com` for example, but not on a different full domain like `boulangerie.fr`. Also, if the Relying Part ID is bound to a subdomain such as `login.boulangerie.com`, then it cannot be used on the root domain, another full root domain, or another subdomain of `boulangerie.com` such as `help.boulangerie.com`. In this case, customers would need a common login page for passkeys for varying full domains like the stated example here. ### Discoverable login With discoverable logins, the passkey manager presents the user with all the stored credentials for this app or website meaning that the user does not have to manually enter his or her identifier. Discoverable logins aren’t restricted to passkeys. This is also applicable to passwords. See [login(withRequest)](../loginWithRequest.html) for more details. ### Non-discoverable login With non-discoverable login, the user must manually enter his or her username before the passkey manager can find a credential. ### Associated Domain You need to host an `apple-app-site-association` file on `https:///.well-known/apple-app-site-association` so the app can register and authenticate with credentials associated with the Relying Party ID ``. Declare `webcredentials:` in Associated Domains. See [apple-app-site-association](apple-app-site-association.html) for the file format, hosting rules, and entitlements. #### Hosted pages If you are using Purse Identity’s [Hosted Pages](../../docs/hosted-pages.html) and need the `apple-app-site-association` file hosted on your domain at Purse Identity, you should input the content of your `apple-app-site-association` file into the text area called **apple-app-site-association** in the **Settings**  **WebAuthn** section of the Purse Identity Console. > We do not perform any validation on the file. If you do not use a custom domain, the Relying Party ID associated to credentials created on Hosted Pages is `.reach5.net`. Your apple-app-site-association file is served at `https://.reach5.net/.well-known/apple-app-site-association`. If you do use a custom domain, your Relying Party ID is `` (with no `https://` prefix). Your apple-app-site-association file is served at `https:///.well-known/apple-app-site-association`. You could also choose to host the `apple-app-site-association` file on your root domain. Hosted Pages are accessible via `auth.example.com`. You could then host the `apple-app-site-association` file at `example.com`. This is a viable long-term option in the case you may not use Hosted Pages in the future. #### Self-hosted If you do not use Purse Identity’s Hosted Pages option, you should host the file on your own. ```none https:///.well-known/apple-app-site-association (1) ``` - (1) Ensure you use the correct Relying Party ID as your domain here. ### Allowed origins In the Purse Identity Console, under **Settings**  **WebAuthn** you must allow: - the URL of the domain that corresponds to the Relying Party ID ![console webauthn settings](../_images/console-webauthn-settings.png) --- # iOS use cases URL: /sdk-ios/guides/use-cases.html There are a few different ways that you can leverage our Purse Identity iOS SDK. How you use it depends on your specific requirements and technical ecosystem. This page provides an overview of important key terms for our iOS SDK as well as the primary ways in which you can leverage it. There are several potential use cases. However, there are two core use cases that we would like to cover here, which primarily focus around whether the login is native or web-based. - [You want to authenticate users natively within your iOS app](#you-want-to-authenticate-users-natively-within-your-ios-app) - [You want to reuse your website authentication inside your iOS app](#you-want-to-reuse-your-website-authentication-inside-your-ios-app) ## You want to authenticate users natively within your iOS app Recommended This is possible using native SDK methods, for example with [loginWithPassword](../loginWithPassword.html). Allowing your users to log in natively from your iOS application is of course the ideal solution. This is the approach we recommend when it’s possible for your setup. In this scenario, access tokens, refresh tokens, and cookies are handled inside the iOS app. The session cookie is automatically shared with your in-app [WKWebViews](#wkwebview). Using the native approach, users authenticates in the native iOS application and navigate through the mobile app. They can leverage their native app session on other mobile apps as long as it is synchronised with their Apple account and implemented by the integrator (that’s you). This is possible by [Apple docs: Sharing keychain items among apps](https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps/). - When you require a seamless user experience without leaving the app interface. - When you need integration with other native functionalities. - When performance and responsiveness are absolutely critical. - If your users typically authenticate on your website first and use your mobile app to navigate through screens. - If your users typically authenticate on your mobile app and use your website to navigate through screens using Safari. ## You want to reuse your website authentication inside your iOS app If you have an iOS app but prefer to use your existing authentication/login page from your website or third-party social provider, you have a couple of options which are outlined here. ##### Use auth page and session from your website You want to use both your authentication/login page from your website and also share the session from the website inside the iOS app, it is possible through [ASWebAuthenticationSession](#aswebauthenticationsession). ##### Use session from a second or third-party website You want to leverage your own social connector or a third-party one (like Facebook Login, Google Login, and so on), it is possible through [ASWebAuthenticationSession](#aswebauthenticationsession). ##### Use only auth page from your website You only want to use the authentication/login page from your website, but not necessarily the session, it’s possible through either [ASWebAuthenticationSession](#aswebauthenticationsession) or [WKWebView](#wkwebview). > We recommend you do not use [WKWebView](#wkwebview) unless there are no other options. We recommend you do not use [WKWebView](#wkwebview) unless there are no other options. ### ASWebAuthenticationSession ASWebAuthenticationSession is an Apple-provided API that allows apps to perform web-based authentication using the system’s default browser (Safari). It presents a secure, single sign-on (SSO) experience without requiring users to leave the app. ASWebAuthenticationSession uses Safari’s existing session data to facilitate authentication. The app receives the necessary tokens (e.g. access and refresh tokens) after the user successfully authenticates. While the session with Safari is isolated, meaning Safari’s cookies are not accessible to the native app context, ReachFive can provide the session cookie necessary to authenticate your webviews if you activate "Include SSO cookie in token endpoint response". See how the flow works ![flow ASWebAuthenticationSession](../_images/flows/flow_ASWebAuthenticationSession.jpeg) You can use the [webviewLogin](../webviewLogin.html) method for this approach. - When your users authenticate through your website (in Safari) and use your mobile iOS app to navigate through other native screens. - When you want your users to leverage the Safari session on other mobile apps. - When wanting to strictly adhere to OAuth and Apple security standards. When you want a seamless and integrated experience. ### WKWebView WKWebView is a web view component that allows developers to embed web content within their app. This can be used to present a web-based login form directly within the app. > OAuth and Apple security standards discourage using this approach as it uses insecure communication channels. See how the flow works ![flow WKWebView](../_images/flows/flow_WKWebView.jpeg) You can use the [loadLoginWebview](../loadLoginWebview.html) method for this approach. - When your users authenticate with your website through webviews and use your mobile iOS app to navigate through other native screens or webviews. - If your users typically authenticate on your website first and use a hybrid mobile app approach to navigate screens, this approach is not recommended. - If you want to adhere to security standards ## Key terms [ASWebAuthenticationSession](#aswebauthenticationsession) ASWebAuthenticationSession is an Apple-provided API that allows apps to perform web-based authentication using the system’s default browser (Safari). Hybrid mobile app A mobile app that embeds web content where the user needs to be authenticated to navigate. [Native mobile app](#you-want-to-authenticate-users-natively-within-your-ios-app) A mobile app that relies only on screens built using native context, without any external web context. Webview A view that allows developers to embed web content directly within their applications. The primary component used for this purpose in modern iOS development is `WKWebView`, which is part of the WebKit framework. [WKWebView](#wkwebview) WKWebView is a web view component that allows developers to embed web content within their app. This can be used to present a web-based login form directly within the app. --- # iOS SDK error response URL: /sdk-ios/reference/errors.html This page contains information on how errors are formatted and the error types you may encounter while using the iOS SDK. > This is a comprehensive list and therefore, not all errors present in the table may apply to the iOS SDK. Error format for SDK ```json { "message": "", (1) "code": "", (2) "exception": "", (3) "data": { "error_id": "2hNBbvYecw", (4) "error_description": "Invalid email or password", (5) "error_message_key": "error.invalidEmailOrPassword", (6) "error": "invalid_grant", (7) "error_user_msg": "Invalid email or password" (8) } } ``` - (1) The error message. - (2) The HTTP status code. For WebAuthn, instead of an HTTP status code, the `code` comes from the underlying WebAuthn library. - (3) A string showing any exceptions. - (4) The `error_id` is auto-generated for each error. - (5) The `error_description` contains the message associated with the `error_message_key`. - (6) The `error_message_key` contains the error key which is typically `error.`. - (7) The `error` is the general error category. - (8) The `error_user_msg` is the user-friendly message based on the `error_description`. ## Purse Identity errors The table below contains the error key (_first column_) and the error message (_second column_) for Purse Identity errors. ##### error.invalidEmailOrPassword `Invalid email or password` ##### error.invalidPhoneNumberOrPassword `Invalid phone number or password` ##### error.invalidOldPassword `Invalid old password` ##### error.updateSamePassword `Password should be different from old password` ##### error.notHaveOldPassword `Not have old password` ##### error.email.notFound `Email not found {0}` ##### error.email.required `Email is required` ##### error.email.alreadyInUse `Email already in use` ##### error.phoneNumber `The phone number is invalid` ##### error.phoneNotFound `No account found with phone number {0}` ##### error.phoneNumberAlreadyInUse `Another account with the same phone number already exists` ##### error.invalidVerificationCode `Invalid verification code` ##### error.expiredVerificationCode `Expired verification code` ##### error.accountBlockedAfterMultipleLoginAttempts `Your account is locked for {lock_duration} minutes due to multiple consecutive failed login attempts. You can unlock it now by resetting your password by clicking on 'Forgot Password'.` ##### error.socialAccountAlreadyInUse `Another user is already linked to this {0} account` ##### error.socialAccountEmailAlreadyInUse `The email address associated with this {0} account is already used by an other account` ##### error.socialAccountPhoneNumberAlreadyInUse `The phone number associated with this {0} account is already used by an other account` ##### error.socialAccountPhoneNumberUnverified `` The phone number associated with this `{0}` account is unverified for the profile ID: `{1}` `` ##### error.socialAccountEmailUnverified `The email address associated with this {0} account is unverified for the profile ID: {1}` ##### error.invalidForm `Invalid form` ##### error.unexpected `An unexpected error occurred. Please try again later.` ##### error.path.missing `This field is required` ##### error.emptyPayload `Empty payload` ##### error.requestDeserialization `Cannot deserialize the request body` ##### error.accessDenied `Access denied` ##### error.password.policy `Password requirements not met` ##### error.password.weak `Password too weak` ##### error.password.length `Minimum length is {0}` ##### error.password.max.length `Maximum length is {0}` ##### error.password.special.characters `Minimum special characters required is {0}` ##### error.password.lowercase.characters `Minimum lowercase characters required is {0}` ##### error.password.uppercase.characters `Minimum uppercase characters required is {0}` ##### error.password.digit.characters `Minimum digit characters required is {0}` ##### error.custom\_identifier.notFound `Custom identifier not found valeur du custom_identifier` ##### error.hostedpages.auth `Authentication` ##### error.hostedpages.authFailure `Authentication failed:` ##### error.hostedpages.emailConfirmation `Email confirmation` ##### error.hostedpages.emailConfirmationFailure `Email confirmation failed:` ##### error.hostedpages.emailVerified `Your email is now verified.` ##### error.hostedpages.goHome `Go home` ##### error.hostedpages.passwordEdit `Edit password` ##### error.hostedpages.passwordEditFailure `Password edition failed:` ##### error.hostedpages.passwordReset `Reset password` ##### error.hostedpages.passwordResetFailure `Password reset failed:` ##### error.hostedpages.passwordSuccessfullyChanged `Your password has been successfully changed! You will be redirected in a few seconds …` ##### error.hostedpages.passwordless `Passwordless` ##### error.hostedpages.passwordlessFailure `Passwordless failed:` ##### error.hostedpages.webauthnDevices `Registered Devices` ##### error.hostedpages.webauthnDevicesFailure `Backing up your devices failed` ##### error.hostedpages.thankYou `Thank you!` ##### error.hostedpages.redirectUrl.invalid `Invalid redirect URL` ##### error.hostedpages.redirectUrl.notWhitelisted `URL not whitelisted` ##### error.hostedpages.returnTo.notWhitelisted `Return to URL not whitelisted` ##### error.hostedpages.invalidConfiguration `Invalid configuration` ##### error.hostedpages.clientNotFound `Couldn''t find hosted pages client` ##### error.hostedpages.oidc.relyingPartyNeedsPermission `{0} needs your permission to access your {0} account.` ##### error.hostedpages.oidc.thisWillAllowRelyingParty `This will allow {0} to:` ##### error.hostedpages.oidc.accessYourScope `View your {0}` ##### error.account.contextPath.notFound `No account found with contextPath [{0}]` ##### error.account.notFound `Account not found` ##### error.account.notExistAnymore `This account does not exist anymore.` ##### error.account.settingsId.missing `Missing account settings id` ##### error.account.id.notFound `No account found with id [{0}]` ##### error.account.externalId.notFound `No account found with external_id [{0}]` ##### error.account.email.notFound `No account found with email [{0}]` ##### error.account.id.required `Missing account id` ##### error.account.id.alreadyExists `An account already exists with the same id` ##### error.account.ids.invalid `Invalid account ids` ##### error.account.alreadyExists `Account already exists` ##### error.account.accessDenied `You have no access to any account` ##### error.account.noAccessSpecified `No global role nor account access specified` ##### error.account.sourceNotFound `Source Account [{0}] not found` ##### error.account.destinationNotFound `Destination Account [{0}] not found` ##### error.account.esHostNotFound `Cannot find ES host for cluster [{0}]` ##### error.account.alreadyActivated `This account have already been activated` ##### error.account.unknown `Unknown account` ##### error.account.anonymization.notAuthorized `Anonymization not authorized on this account` ##### error.account.name.alreadyExists `Account {0} ({0}) already exists` ##### error.account.inMaintenance `Account {0} is in maintenance` ##### error.account.temporarilySuspended `Your account has been disabled for security reasons. Please reset your password by clicking the link sent by email or SMS or contact the site administrator to reactivate it. You can receive a new password reset link by clicking on "Forgot Password".` ##### error.account.permanentlySuspended `Your account has been disabled for security reasons. Please contact the site administrator to reactivate it.` ##### error.cluster.unknown `Unknown cluster` ##### error.missingBody `Missing body` ##### error.userAccessRequired `User access required` ##### error.unknownTask `Unknown task` ##### error.notFound `Not found` ##### error.featureNotEnabled `This feature is not enabled` ##### error.credentialsInvalid `Invalid client credentials` ##### error.phoneNumberOrEmailRequired `A valid phone number or email is mandatory` ##### error.criteriaPhoneOrEmailOnly `Only one criteria is allowed: phone or email` ##### error.tooManyAttempts `Too many attempts` ##### error.invalidDataType `Invalid data type` ##### error.sortField.invalid `Invalid sort field` ##### error.parsingFieldSelection `Field selection parsing error: Unexpected char at {0}` ##### error.resultWindowTooLarge `Result window is too large. See export API for a more efficient way to extract a large dataset.` ##### error.userEmail.notFound `Unable to find the user {0} email` ##### error.invalidEventName `Invalid event name` ##### error.decodeTokenIncorrectSecret `Failed to decode token due to incorrect secret` ##### error.resource.notFound `No resource found at ''{0}'' for method {0}` ##### error.identifier.mustBeValidEmail `The identifier must be a valid email.` ##### error.identifier.mustBeValidEmailOrPhoneNumber `The identifier must be a valid email or a valid phone number.` ##### error.interest.usedCantBeDeleted `Interest can''t be deleted while it is used in a segment` ##### error.openGraphTags.fetchFailed `Could not fetch open graph tags` ##### error.emailVerification.notConfigured `Verification email settings not configured` ##### error.requestBody.parameters.required `Parameters must be passed in the request body` ##### error.requestToken.notDelivered `No request token delivered by {0}` ##### error.webhook.key.alreadyExists `Webhook key already exists.` ##### error.pub-sub-hook.key.alreadyExists `Pub/Sub hook key already exists.` ##### error.email.signup.notConfigured `Signup email not configured` ##### error.filter.invalid `Invalid filter: {0}` ##### error.filter.argumentOnField.invalid `Invalid filter: invalid argument on field ''{0}''` ##### error.filter.operator.invalid `Invalid filter: invalid operator associated with field ''{0}''` ##### error.filter.boolean.invalid `Invalid filter: boolean value expected with field ''{0}''` ##### error.objectStorageTransfer.clientNotFound `Could not get ObjectStorageTransfer client from protocol: {0} with settings: {0}` ##### error.objectStorageTransfer.upload `Could not upload data: {0}` ##### error.objectStorageTransfer.couldNotDelete `Could not delete data: {0}` ##### error.customField.invalid `Invalid custom field type` ##### error.customField.notFound `Custom field not found` ##### error.index.accountType.notFound `Account index type not found` ##### error.index.type.notFound `Index type not found` ##### error.index.template.notFound `Index template not found` ##### error.index.notFound `Index not found` ##### error.database.update `Unable to update database for account {0}` ##### error.accessToken.missing `Access token missing` ##### error.accessToken.expired `Access token expired` ##### error.accessToken.invalid `Invalid access token` ##### error.accessToken.freshness `Access token is not fresh enough.` ##### error.accessToken.unexpected `Unexpected token response: ({0}) {0}` ##### error.accessToken.scope.required `The token does not contain the required scope: {0}` ##### error.accessToken.scope.insufficient `Scope insufficient. Expected: [{0}]` ##### error.state.missing `Missing state` ##### error.state.invalid `Invalid state` ##### error.email.invalid `Invalid email` ##### error.idToken.expired `ID token expired` ##### error.idToken.invalid `Invalid id token` ##### error.idToken.invalidIssuer `Invalid id token issuer` ##### error.idToken.invalidAudience `Invalid id token audience` ##### error.idToken.invalidNonce `Invalid id token nonce` ##### error.authn.mfa.tkn.invalidFactor `Invalid authentication token type` ##### error.authn.mfa.stepup.unavailable `This action is unavailable` ##### error.authn.mfa.sms.unavailable `This action is not available` ##### error.authn.mfa.stepup.unavailable `This action is unavailable` ##### error.authn.mfa.stepup.invalidToken `Invalid token` ##### error.authn.mfa.stepup.expiredToken `Expired token` ##### error.mfa.noLiteOnly `A lite profile cannot register a mfa credential` ##### error.oidc.authorize.access\_denied.authServer `The request has been denied by the server.` ##### error.oidc.authorize.access\_denied.user `The request has been denied by the user.` ##### error.oidc.authorize.consent\_required `Consent is required by the user.` ##### error.oidc.authorize.complete.missingRequest `Missing request form parameter.` ##### error.oidc.authCode.missing `Missing authorization code` ##### error.pkce.unsupportedAlgo `Unsupported PKCE algo {0}` ##### error.pkce.codeVerifier.required `code_verifier is required` ##### error.pkce.challenges.required `code_challenge and code_challenge_method are mandatory for this client.` ##### error.pkce.implicitFlow.forbidden `Implicit flow is forbidden when PKCE is enforced.` ##### error.pkce.request.notFound `Request pkce id not found` ##### error.pkce.request.emptyCodeChallenge `Empty code_challenge.` ##### error.pkce.request.invalidCodeChallenge `code_challenge must be between 43 and 128 characters long.` ##### error.pkce.request.invalidOrExpired `PKCE code invalid or expired` ##### error.client.implicitFlow.forbidden `Implicit flow forbidden for this client.` ##### error.client.notFound `The client could not be found.` ##### error.client.notIdentity `Not a first-party identity client` ##### error.client.notFirstParty `Not a first-party identity client` ##### error.client.notThirdParty `Not a third-party identity client` ##### error.client.nameEmpty `Empty client name.` ##### error.client.clientIdEmpty `Empty client ID.` ##### error.client.redirectUrlNotAllowed `The redirect url is not allowed.` ##### error.client.allowed\_callback\_urls.forbidden `allowed_callback_urls field not allowed on management client.` ##### error.client.unauthorizedAPI `This client is not authorized to use Management API.` ##### error.client.unauthorizedScope `This client is not allowed to use the requested scope(s): {0}` ##### error.client.refreshToken.notEnabled `Refresh tokens cannot be enabled if no authentication method is required and PKCE is not enabled.` ##### error.client.refreshToken.identityClientOnly `Refresh tokens are available only for identity clients.` ##### error.client.consentPageSettings.empty `Empty consent page settings.` ##### error.client.rsaKeyPair.jwtAlgorithmNotAllowed `RSA key pair management action unauthorized for non RS256 JWT algorithm: {0}.` ##### error.client.thirdparty.mustEnforceScope `Third-party clients must enforce scope.` ##### error.client.thirdparty.noFullWrite `Third-party clients cannot request the full_write scope.` ##### error.client.thirdparty.noLoginUrl `Third-party clients cannot have login URLs.` ##### error.clientSecret.missing `Missing client secret` ##### error.clientSecret.invalid `Invalid client secret` ##### error.clientId.missing `Missing client id` ##### error.provider.unknown `Unknown provider` ##### error.provider.unknownWithName `Unknown provider: {0}` ##### error.provider.notSupported `Provider {0} is not supported.` ##### error.provider.notSupportedForFakeLogins `Provider {0} not supported for fake logins` ##### error.provider.authcode.missing `''provider_authcode'' param missing` ##### error.provider.twitterError `Twitter error: {0}` ##### error.provider.token.missing `''provider_token'' parameter missing` ##### error.provider.secret.missing `''provider_secret'' parameter missing` ##### error.provider.requestToken.notFound `No request token delivered by {0}` ##### error.provider.profileLoading `Error during {0} profile loading: status={0} and body={0}` ##### error.provider.tokenOrCode.required `One of ''provider_token'' or ''provider_code'' parameter is required.` ##### error.provider.callback.unexpected `[{0}] Unexpected oauth callback: {0}` ##### error.provider.identity.notFound `Identity provider {0} not found` ##### error.provider.mailRu.noProfile `Mailru profile retrieving failed.` ##### error.provider.unexpectedResponse `Unexpected {0} response` ##### error.facebook.accessToken.invalid `Invalid OAuth access token.` ##### error.facebook.accessToken.expired `Access token expired` ##### error.facebook.authCode.alreadyUsed `Authorization code already used` ##### error.facebook.authCode.expired `Authorization code expired` ##### error.facebook.authCode.invalid.expired `Authorization code invalid or expired` ##### error.facebook.authCode.invalid `Authorization code invalid` ##### error.facebook.mustBeAdmin `You must be admin or developer of your Facebook application to use this feature.` ##### error.facebook.audienceExportFail `Audience export failed` ##### error.facebook.termsOfService.notAccepted `Terms of service of your ads account have not been accepted.` ##### error.azureAd.noAccessToken `No access token delivered by Azure AD: [{0}] {0}` ##### error.invalidFilter.boolean `Invalid filter: boolean value expected with field ''{0}''` ##### error.invalidFilter.invalidOperator `Invalid filter: invalid operator associated with field ''{0}''` ##### error.role.notAllowedAsGlobal `Role {0} is not allowed as a global role` ##### error.role.notAllowedAsAccount `Role {0} is not allowed as an account role` ##### error.roles.notAllowedAsAccount `Roles [{0}] are not allowed as account roles` ##### error.user.notFound `User not found` ##### error.user.alreadyHasGlobalAccess `User already has global access.` ##### error.user.alreadyLinked `User is already linked to your account.` ##### error.user.resource.accessNotGranted `You are not granted to access this resource` ##### error.audience.notFound `Audience not found` ##### error.webhook.key.notFound `Webhook key does not exist.` ##### error.pub-sub-hook.key.notFound `Pub/Sub hook key does not exist.` ##### error.interest.notFound `Interest not found` ##### error.interest.ids.notFound `Interests {0} not found` ##### error.twilio.notConfigured `Twilio not configured` ##### error.smtp.notConfigured `SMTP provider not configured` ##### error.smtpProvider.notConfigured `Email [{0}] not configured` ##### error.sms.passwordReset `Password reset SMS not configured` ##### error.sms.accountSuspension `Account suspension SMS not configured` ##### error.sms.verificationNotConfigured `Verification SMS not configured` ##### error.sms.passwordlessTemplate.notConfigured `Passwordless template not configured for SMS` ##### error.passwordless.email.notConfigured `Passwordless email not configured` ##### error.passwordless.sms.notConfigured `Passwordless SMS not configured` ##### error.emailService.sendNotConfigured `Found no valid ''{0}'' configuration to send email` ##### error.emailService.templateNotConfigured `Email [{0} - {0}] not configured` ##### error.emailService.template.invalid `Invalid template [{0} - {0}]: {0}` ##### error.emailService.redirectUrlMissing `Missing redirect url in ''{0}'' configuration` ##### error.emailService.templateDisabled `Template ''{0}'' is disabled` ##### error.responseType.unsupported `Unsupported response type` ##### error.job.notFound `Job not found` ##### error.job.definitionTypeChange `Job definition''s type can''t be changed, create a new job` ##### error.job.couldNotCancelNonRunning `Could not cancel a non running job. Current status: {0}` ##### error.job.notConfigured `Job type {0} not configured` ##### error.job.settings.invalid `Settings are invalid for job {0}` ##### error.auth.header.missing `Missing authorization header` ##### error.auth.header.invalid `Invalid authentication header` ##### error.auth.header.notExpected `Authorization header not expected` ##### error.auth.method.unexpected `Unexpected authentication method: {0}` ##### error.session.expired `Session expired` ##### error.token.expired `Token expired` ##### error.token.alreadyUsed `Token already used` ##### error.token.clientId.invalid `Token client id is invalid` ##### error.token.notAssociatedWithClient `The access token is not associated with this client` ##### error.freshLogin.required `Fresh login required` ##### error.user.notExistAnymore `This user does not exist anymore.` ##### error.refreshToken.expired `Refresh token expired` ##### error.refreshToken.revoked `Revoked refresh token` ##### error.authCode.expired `Authorization code expired` ##### error.authCode.alreadyUsed `Authorization code already used` ##### error.redirectUri.missingParam `Missing ''redirect_uri'' param` ##### error.redirectUri.invalid `Invalid redirect uri` ##### error.token.invalid `Invalid token` ##### error.redirectUri.missing `Missing ''redirect_uri'' param` ##### error.email.updateNotConfigured `Email update verification not configured` ##### error.emailOrPhoneNumber.required `Email or phone number is required` ##### error.acs.sendEvent `ACS: Failed to send event using email: {0} and url: {0}, got {0}` ##### error.acs.exchangeJwt `ACS: Failed to exchange jwt for an accessToken. ClientId: {0}` ##### error.acs.failed `ACS failed: {0}` ##### error.dialogInsight.userId.missing `Missing user Id in the My Dialog Insight merge response` ##### error.dialogInsight.sendEmailStatus `Can''t read My Dialog Insight sendEmail status response` ##### error.consent.notFound `Consent not found` ##### error.consent.date.invalid `Consent date of ''{0}'' is not valid` ##### error.consent.key.inexistent `Consent ''{0}'' is not valid doesn''t exist` ##### error.consent.version.id.invalid `Consent version ID of ''{0}'' is not valid` ##### error.consent.version.language.invalid `Consent version language of ''{0}'' is not valid` ##### error.consent.archived.cannotBeUpdated `Archived consent ''{0}'' cannot be updated` ##### error.consent.archived.cannotBeGranted `Archived consent ''{0}'' cannot be granted` ##### error.consent.type.required `Consent type is mandatory for granted consents` ##### error.consent.key.alreadyUse `Consent key ''{0}'' is already in use` ##### error.consent.default.language.required `The translation of the version ''{0}'' in the account''s default language ({0}) is required` ##### error.consent.group.nature.immutability `Consent’s nature (group | standalone) is set at creation time and can''t be modified afterward` ##### error.consent.group.invalid.associated.keys `Consent group defined with invalid associated consents keys: {0}` ##### error.feature.notAvailable `This feature is not available` ##### error.feature.notEnabled `This feature is not enabled` ##### error.recommendation.notFound `Recommendation not found` ##### error.scope.insufficient `Scope insufficient. Requested values not validated by the user: [{0}]` ##### error.scope.unknown `Unknown scope value(s): {0}` ##### error.scope.missing `Missing scope: {0}` ##### error.phoneNumber.invalid `The phone number is invalid` ##### error.loginAs.noSettings `No settings for login-as feature` ##### error.validation.url `Must be a valid URL.` ##### error.validation.uri `Must be a valid URI.` ##### error.oidc.grants.clientNotFound `No grant exists for this client ID` ##### error.profile.defaultAddress.onlyOne `Only a single address can be a default address` ##### error.profile.defaultAddress.required `A default address is required` ##### error.profile.consents.invalid `Invalid consents` ##### error.profile.phoneNumber.invalid `Invalid phone number` ##### error.profile.emailOrPhoneNumber.shouldBePresent `valid email or phoneNumber should be present` ##### error.profile.multipleMatching `Multiple matching profiles found: {0}` ##### error.profile.externalIdMismatch `External ID mismatch.` ##### error.profile.unifiedIdMismatch `Unified ID mismatch.` ##### error.profile.tooManyMatching `Too many matching profile: {0}` ##### error.profile.ids.identical `The two user ids are identical` ##### error.profile.identity.notFound `Identity {0} not found` ##### error.profile.identity.illegalState `Profile does not have the proper identification configured (email or phone)` ##### error.profile.identity.missingEmail `Profile does not have an email address configured` ##### error.profile.identity.missingPhoneNumber `Profile does not have a phone number configured` ##### error.profile.identifier.atLeastOne.required `At least one identifier (external_id, email, phone number or provider ID) is required` ##### error.profile.identity.unlink.notAuthorized `Local identity unlink is not authorized.` ##### error.profile.provider.unlink.notAuthorized `Local provider unlink is not authorized.` ##### error.profile.identifier.invalid `No valid identifier. An unique identifier (email{0}, unified ReachFive ID or external ID) should be provided.` ##### error.lite.accounts.alreadyExist `2 Lite accounts already exist` ##### error.profile.lite.unifiedId.invalid `Invalid unified ID provided: no matching existing profile with ID {0}` ##### error.profile.lite.tooManyMatching `Too many matching lite profile: {0}` ##### error.profile.lite.multipleMatching `Multiple matching lite profiles found: {0}` ##### error.profile.lite.identifier.invalid `Invalid lite profile identifier(s). A lite profile can''t add identifiers if the profile has already one identifier.` ##### error.profile.lite.id.notFound `Unable to find the Lite Profile with id: {0}` ##### error.profile.lite.unableUpdateWithoutUnifiedId `Unable to update a LiteProfile without unifiedId` ##### error.profile.lite.unableFindWithUnifiedId `Unable to find a LiteProfile with the unifiedId: {0}` ##### error.profile.lite.identifiers.invalid `liteProfileInvalidIdentifiers` ##### error.profile.ageFilter.forbiddenOperation `Invalid filter: ''{0}'' operator not authorized with field ''age''` ##### error.profile.ageFilter.withInt `Invalid filter: integer value expected with field ''age''` ##### error.profile.unknownProfileFilter `You are not allowed to filter with this fields: {0}` ##### error.profile.emailModificationImpossible `An existing email cannot be modified with this endpoint` ##### error.profile.phoneNumberModificationImpossible `An existing phone number cannot be modified with this endpoint` ##### error.profile.cannotDecipher `Cannot decipher the hash` ##### error.profile.identifiersNotVerified ``Can’t synchronize because the identifier of the `target` profile isn’t verified`` ##### error.profile.timestampOutdated `Can’t synchronize because the target profile has already updated since synchronization attempt` ##### error.consoleUser.thirdPartyAlreadyUsed `A ReachFive account linked to the same third-party account already exists` ##### error.consoleUser.deleted `Your account have been deleted. Please ask to your team to be granted access again.` ##### error.consoleUser.alreadyActivated `Your account have already been activated.` ##### error.consoleUser.accessRevoked `Your access have been revoked. Please ask to your team to be granted access again.` ##### error.consoleUser.noSocialLogin `Unknown account. To enable social login access to an existing account, configure it in your account settings.` ##### error.emailMessagingService.required `Email is required` ##### error.emailMessagingService.sendFailed `Email sending failed` ##### error.emailMessagingService.serviceUnavailable `The email provider is currently unavailable` ##### error.smsMessagingService.noPhoneNumber `Can''t send SMS. Empty phone number for the profile {0}` ##### error.smsMessagingService.noTemplate.updatePhone `Update phone number template not configured` ##### error.smsMessagingService.noTemplate.updatePassword `Update password template not configured` ##### error.es.resharding.incorrectNumberOfIndex `Incorrect number of index for alias {0} ({0} instead of 1)` ##### error.webauthn.friendlyNameAlreadyAssociated `Friendly name ''{0}'' already associated with another device.` ##### error.webauthn.credentialsNotFound `Your account is not associated with the provided credentials.` ##### error.crypto.magento.invalidHashFormat `Invalid Magento hash format` ##### error.crypto.magento.invalidAlgorithm `Invalid Magento hashing algorithm version: {0}` ##### error.crypto.magento.emptyVersionsList `Empty Magento algorithm versions list` ##### error.unverifiedLogin `Unverified identifier account` `User message is typically:` `Unverified identifier account. To login, please verify your identifier with the email or the SMS that you received.` ##### error.invalidLoginType `Invalid login type. Occurs when an unapproved identifier attempts to log in.` `You cannot authenticate using {0}` ##### error.requestUri.invalidOrExpired ``The provided `request_uri` is expired or does not exist.`` ``An `invalid_request` error typically with an `error_user_msg` such as:`` `"The authorization session has expired. Please try again."` ---