diff --git a/docs/custom-flows/add-email.mdx b/docs/custom-flows/add-email.mdx index 02a65fa66d..9214f1ecd2 100644 --- a/docs/custom-flows/add-email.mdx +++ b/docs/custom-flows/add-email.mdx @@ -161,72 +161,71 @@ The following example demonstrates how to build a custom user interface that all import ClerkSDK struct AddEmailView: View { - @State private var email = "" - @State private var code = "" - @State private var isVerifying = false - // Create a reference to the email address that we'll be creating - @State private var newEmailAddress: EmailAddress? + @State private var email = "" + @State private var code = "" + @State private var isVerifying = false + // Create a reference to the email address that we'll be creating + @State private var newEmailAddress: EmailAddress? + + var body: some View { + if newEmailAddress?.verification?.status == .verified { + Text("Email added!") + } - var body: some View { - - if newEmailAddress?.verification?.status == .verified { - Text("Email added!") - } - - if isVerifying { - TextField("Enter code", text: $code) - Button("Verify") { - Task { await verifyCode(code) } - } - } else { - TextField("Enter email address", text: $email) - Button("Continue") { - Task { await createEmail(email) } - } - } + if isVerifying { + TextField("Enter code", text: $code) + Button("Verify") { + Task { await verifyCode(code) } + } + } else { + TextField("Enter email address", text: $email) + Button("Continue") { + Task { await createEmail(email) } + } } + } } extension AddEmailView { - func createEmail(_ email: String) async { - do { - guard let user = Clerk.shared.user else { return } - - // Add an unverified email address to user - self.newEmailAddress = try await user.createEmailAddress(email) - - guard let newEmailAddress = self.newEmailAddress else { return } - - // Send the user an email with the verification code - try await newEmailAddress.prepareVerification(strategy: .emailCode) - - // Set to true to display second form - // and capture the OTP code - isVerifying = true - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func createEmail(_ email: String) async { + do { + guard let user = Clerk.shared.user else { return } + + // Add an unverified email address to user + self.newEmailAddress = try await user.createEmailAddress(email) + + guard let newEmailAddress = self.newEmailAddress else { return } + + // Send the user an email with the verification code + try await newEmailAddress.prepareVerification(strategy: .emailCode) + + // Set to true to display second form + // and capture the OTP code + isVerifying = true + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verifyCode(_ code: String) async { - do { - guard let newEmailAddress else { return } - - // Verify that the code entered matches the code sent to the user - self.newEmailAddress = try await newEmailAddress.attemptVerification(strategy: .emailCode(code: code)) - - // If the status is not complete, check why. User may need to - // complete further steps. - dump(self.newEmailAddress?.verification?.status) - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verifyCode(_ code: String) async { + do { + guard let newEmailAddress else { return } + + // Verify that the code entered matches the code sent to the user + self.newEmailAddress = try await newEmailAddress.attemptVerification(strategy: .emailCode(code: code)) + + // If the status is not complete, check why. User may need to + // complete further steps. + dump(self.newEmailAddress?.verification?.status) + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` diff --git a/docs/custom-flows/add-phone.mdx b/docs/custom-flows/add-phone.mdx index 37ead8a96a..6622c31a81 100644 --- a/docs/custom-flows/add-phone.mdx +++ b/docs/custom-flows/add-phone.mdx @@ -160,72 +160,71 @@ The following example demonstrates how to build a custom user interface that all import ClerkSDK struct AddPhoneView: View { - @State private var phone = "" - @State private var code = "" - @State private var isVerifying = false - // Create a reference to the phone number that we'll be creating - @State private var newPhoneNumber: PhoneNumber? - - var body: some View { - - if newPhoneNumber?.verification?.status == .verified { - Text("Phone added!") - } - - if isVerifying { - TextField("Enter code", text: $code) - Button("Verify") { - Task { await verifyCode(code) } - } - } else { - TextField("Enter phone number", text: $phone) - Button("Continue") { - Task { await createPhone(phone) } - } - } + @State private var phone = "" + @State private var code = "" + @State private var isVerifying = false + // Create a reference to the phone number that we'll be creating + @State private var newPhoneNumber: PhoneNumber? + + var body: some View { + if newPhoneNumber?.verification?.status == .verified { + Text("Phone added!") } + + if isVerifying { + TextField("Enter code", text: $code) + Button("Verify") { + Task { await verifyCode(code) } + } + } else { + TextField("Enter phone number", text: $phone) + Button("Continue") { + Task { await createPhone(phone) } + } + } + } } extension AddPhoneView { - func createPhone(_ phone: String) async { - do { - guard let user = Clerk.shared.user else { return } - - // Add an unverified phone number to user - self.newPhoneNumber = try await user.createPhoneNumber(phone) - - guard let newphoneNumber = self.newPhoneNumber else { return } - - // Send the user an sms message with the verification code - try await newphoneNumber.prepareVerification() - - // Set to true to display second form - // and capture the OTP code - isVerifying = true - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func createPhone(_ phone: String) async { + do { + guard let user = Clerk.shared.user else { return } + + // Add an unverified phone number to user + self.newPhoneNumber = try await user.createPhoneNumber(phone) + + guard let newphoneNumber = self.newPhoneNumber else { return } + + // Send the user an sms message with the verification code + try await newphoneNumber.prepareVerification() + + // Set to true to display second form + // and capture the OTP code + isVerifying = true + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verifyCode(_ code: String) async { - do { - guard let newPhoneNumber else { return } - - // Verify that the code entered matches the code sent to the user - self.newPhoneNumber = try await newPhoneNumber.attemptVerification(code: code) - - // If the status is not complete, check why. User may need to - // complete further steps. - dump(self.newPhoneNumber?.verification?.status) - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verifyCode(_ code: String) async { + do { + guard let newPhoneNumber else { return } + + // Verify that the code entered matches the code sent to the user + self.newPhoneNumber = try await newPhoneNumber.attemptVerification(code: code) + + // If the status is not complete, check why. User may need to + // complete further steps. + dump(self.newPhoneNumber?.verification?.status) + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` diff --git a/docs/custom-flows/email-password-mfa.mdx b/docs/custom-flows/email-password-mfa.mdx index 989800d7eb..425491d7c4 100644 --- a/docs/custom-flows/email-password-mfa.mdx +++ b/docs/custom-flows/email-password-mfa.mdx @@ -579,73 +579,73 @@ This guide will walk you through how to build a custom email/password sign-in fl import ClerkSDK struct MFASignInView: View { - @State private var email = "" - @State private var password = "" - @State private var code = "" - @State private var displayTOTP = false - - var body: some View { - if displayTOTP { - TextField("Code", text: $code) - Button("Verify") { - Task { await verify(code: code) } - } - } else { - TextField("Email", text: $email) - SecureField("Password", text: $password) - Button("Next") { - Task { await submit(email: email, password: password) } - } - } + @State private var email = "" + @State private var password = "" + @State private var code = "" + @State private var displayTOTP = false + + var body: some View { + if displayTOTP { + TextField("Code", text: $code) + Button("Verify") { + Task { await verify(code: code) } + } + } else { + TextField("Email", text: $email) + SecureField("Password", text: $password) + Button("Next") { + Task { await submit(email: email, password: password) } + } } + } } extension MFASignInView { - func submit(email: String, password: String) async { - do { - // Start the sign-in process. - let signIn = try await SignIn.create(strategy: .identifier(email, password: password)) - - switch signIn.status { - case .needsSecondFactor: - // Handle user submitting email and password and swapping to TOTP form. - displayTOTP = true - default: - // If the status is not needsSecondFactor, check why. User may need to - // complete different steps. - dump(signIn.status) - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func submit(email: String, password: String) async { + do { + // Start the sign-in process. + let signIn = try await SignIn.create(strategy: .identifier(email, password: password)) + + switch signIn.status { + case .needsSecondFactor: + // Handle user submitting email and password and swapping to TOTP form. + displayTOTP = true + default: + // If the status is not needsSecondFactor, check why. User may need to + // complete different steps. + dump(signIn.status) + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verify(code: String) async { - do { - // Access the in progress sign in stored on the client object. - guard let inProgressSignIn = Clerk.shared.client?.signIn else { return } - - // Attempt the TOTP or backup code verification. - let signIn = try await inProgressSignIn.attemptSecondFactor(for: .totp(code: code)) - - switch signIn.status { - case .complete: - // If sign-in process is complete, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signIn.status) - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verify(code: String) async { + do { + // Access the in progress sign in stored on the client object. + guard let inProgressSignIn = Clerk.shared.client?.signIn else { return } + + // Attempt the TOTP or backup code verification. + let signIn = try await inProgressSignIn.attemptSecondFactor(for: .totp(code: code)) + + switch signIn.status { + case .complete: + // If sign-in process is complete, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signIn.status) + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` diff --git a/docs/custom-flows/email-password.mdx b/docs/custom-flows/email-password.mdx index caa733259f..53abd2111a 100644 --- a/docs/custom-flows/email-password.mdx +++ b/docs/custom-flows/email-password.mdx @@ -519,72 +519,72 @@ This guide will walk you through how to build a custom email/password sign-up an import ClerkSDK struct EmailPasswordSignUpView: View { - @State private var email = "" - @State private var password = "" - @State private var code = "" - @State private var isVerifying = false - - var body: some View { - if isVerifying { - // Display the verification form to capture the OTP code - TextField("Enter your verification code", text: $code) - Button("Verify") { - Task { await verify(code: code) } - } - } else { - // Display the initial sign-up form to capture the email and password - TextField("Enter email address", text: $email) - SecureField("Enter password", text: $password) - Button("Next") { - Task { await submit(email: email, password: password) } - } - } + @State private var email = "" + @State private var password = "" + @State private var code = "" + @State private var isVerifying = false + + var body: some View { + if isVerifying { + // Display the verification form to capture the OTP code + TextField("Enter your verification code", text: $code) + Button("Verify") { + Task { await verify(code: code) } + } + } else { + // Display the initial sign-up form to capture the email and password + TextField("Enter email address", text: $email) + SecureField("Enter password", text: $password) + Button("Next") { + Task { await submit(email: email, password: password) } + } } + } } extension EmailPasswordSignUpView { - func submit(email: String, password: String) async { - do { - // Start the sign-up process using the email and password provided - let signUp = try await SignUp.create(strategy: .standard(emailAddress: email, password: password)) - - // Send the user an email with the verification code - try await signUp.prepareVerification(strategy: .emailCode) - - // Set 'isVerifying' true to display second form - // and capture the OTP code - isVerifying = true - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func submit(email: String, password: String) async { + do { + // Start the sign-up process using the email and password provided + let signUp = try await SignUp.create(strategy: .standard(emailAddress: email, password: password)) + + // Send the user an email with the verification code + try await signUp.prepareVerification(strategy: .emailCode) + + // Set 'isVerifying' true to display second form + // and capture the OTP code + isVerifying = true + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verify(code: String) async { - do { - // Access the in progress sign up stored on the client - guard let inProgressSignUp = Clerk.shared.client?.signUp else { return } - - // Use the code the user provided to attempt verification - let signUp = try await inProgressSignUp.attemptVerification(.emailCode(code: code)) - - switch signUp.status { - case .complete: - // If verification was completed, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signUp.status) - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verify(code: String) async { + do { + // Access the in progress sign up stored on the client + guard let inProgressSignUp = Clerk.shared.client?.signUp else { return } + + // Use the code the user provided to attempt verification + let signUp = try await inProgressSignUp.attemptVerification(.emailCode(code: code)) + + switch signUp.status { + case .complete: + // If verification was completed, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signUp.status) + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` @@ -967,40 +967,40 @@ This guide will walk you through how to build a custom email/password sign-up an import ClerkSDK struct EmailPasswordSignInView: View { - @State private var email = "" - @State private var password = "" - - var body: some View { - TextField("Enter email address", text: $email) - SecureField("Enter password", text: $password) - Button("Sign In") { - Task { await submit(email: email, password: password) } - } + @State private var email = "" + @State private var password = "" + + var body: some View { + TextField("Enter email address", text: $email) + SecureField("Enter password", text: $password) + Button("Sign In") { + Task { await submit(email: email, password: password) } } + } } extension EmailPasswordSignInView { - func submit(email: String, password: String) async { - do { - // Start the sign-in process using the email and password provided - let signIn = try await SignIn.create(strategy: .identifier(email, password: password)) - - switch signIn.status { - case .complete: - // If sign-in process is complete, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signIn.status) - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func submit(email: String, password: String) async { + do { + // Start the sign-in process using the email and password provided + let signIn = try await SignIn.create(strategy: .identifier(email, password: password)) + + switch signIn.status { + case .complete: + // If sign-in process is complete, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signIn.status) + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` diff --git a/docs/custom-flows/email-sms-otp.mdx b/docs/custom-flows/email-sms-otp.mdx index d2c9106212..e31c956dc6 100644 --- a/docs/custom-flows/email-sms-otp.mdx +++ b/docs/custom-flows/email-sms-otp.mdx @@ -365,68 +365,68 @@ This guide will walk you through how to build a custom SMS OTP sign-up and sign- import ClerkSDK struct SMSOTPSignUpView: View { - @State private var phoneNumber = "" - @State private var code = "" - @State private var isVerifying = false - - var body: some View { - if isVerifying { - TextField("Enter your verification code", text: $code) - Button("Verify") { - Task { await verify(code: code) } - } - } else { - TextField("Enter phone number", text: $phoneNumber) - Button("Continue") { - Task { await submit(phoneNumber: phoneNumber) } - } - } + @State private var phoneNumber = "" + @State private var code = "" + @State private var isVerifying = false + + var body: some View { + if isVerifying { + TextField("Enter your verification code", text: $code) + Button("Verify") { + Task { await verify(code: code) } + } + } else { + TextField("Enter phone number", text: $phoneNumber) + Button("Continue") { + Task { await submit(phoneNumber: phoneNumber) } + } } + } } extension SMSOTPSignUpView { - func submit(phoneNumber: String) async { - do { - // Start the sign-up process using the phone number method. - let signUp = try await SignUp.create(strategy: .standard(phoneNumber: phoneNumber)) - - // Start the verification - a SMS message will be sent to the - // number with a one-time code. - try await signUp.prepareVerification(strategy: .phoneCode) - - // Set isVerifying to true to display second form and capture the OTP code. - isVerifying = true - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func submit(phoneNumber: String) async { + do { + // Start the sign-up process using the phone number method. + let signUp = try await SignUp.create(strategy: .standard(phoneNumber: phoneNumber)) + + // Start the verification - a SMS message will be sent to the + // number with a one-time code. + try await signUp.prepareVerification(strategy: .phoneCode) + + // Set isVerifying to true to display second form and capture the OTP code. + isVerifying = true + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verify(code: String) async { - do { - // Access the in progress sign up stored on the client object. - guard let inProgressSignUp = Clerk.shared.client?.signUp else { return } - - // Use the code provided by the user and attempt verification. - let signUp = try await inProgressSignUp.attemptVerification(.phoneCode(code: code)) - - switch signUp.status { - case .complete: - // If verification was completed, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signUp.status) - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verify(code: String) async { + do { + // Access the in progress sign up stored on the client object. + guard let inProgressSignUp = Clerk.shared.client?.signUp else { return } + + // Use the code provided by the user and attempt verification. + let signUp = try await inProgressSignUp.attemptVerification(.phoneCode(code: code)) + + switch signUp.status { + case .complete: + // If verification was completed, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signUp.status) + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` @@ -829,68 +829,68 @@ This guide will walk you through how to build a custom SMS OTP sign-up and sign- import ClerkSDK struct SMSOTPSignInView: View { - @State private var phoneNumber = "" - @State private var code = "" - @State private var isVerifying = false - - var body: some View { - if isVerifying { - TextField("Enter your verification code", text: $code) - Button("Verify") { - Task { await verify(code: code) } - } - } else { - TextField("Enter phone number", text: $phoneNumber) - Button("Continue") { - Task { await submit(phoneNumber: phoneNumber) } - } - } + @State private var phoneNumber = "" + @State private var code = "" + @State private var isVerifying = false + + var body: some View { + if isVerifying { + TextField("Enter your verification code", text: $code) + Button("Verify") { + Task { await verify(code: code) } + } + } else { + TextField("Enter phone number", text: $phoneNumber) + Button("Continue") { + Task { await submit(phoneNumber: phoneNumber) } + } } + } } extension SMSOTPSignInView { - func submit(phoneNumber: String) async { - do { - // Start the sign-in process using the phone number method. - let signIn = try await SignIn.create(strategy: .identifier(phoneNumber)) - - // Send the OTP code to the user. - try await signIn.prepareFirstFactor(for: .phoneCode) - - // Set isVerifying to true to display second form - // and capture the OTP code. - isVerifying = true - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func submit(phoneNumber: String) async { + do { + // Start the sign-in process using the phone number method. + let signIn = try await SignIn.create(strategy: .identifier(phoneNumber)) + + // Send the OTP code to the user. + try await signIn.prepareFirstFactor(for: .phoneCode) + + // Set isVerifying to true to display second form + // and capture the OTP code. + isVerifying = true + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verify(code: String) async { - do { - // Access the in progress sign in stored on the client object. - guard let inProgressSignIn = Clerk.shared.client?.signIn else { return } - - // Use the code provided by the user and attempt verification. - let signIn = try await inProgressSignIn.attemptFirstFactor(for: .phoneCode(code: code)) - - switch signIn.status { - case .complete: - // If verification was completed, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signIn.status) - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verify(code: String) async { + do { + // Access the in progress sign in stored on the client object. + guard let inProgressSignIn = Clerk.shared.client?.signIn else { return } + + // Use the code provided by the user and attempt verification. + let signIn = try await inProgressSignIn.attemptFirstFactor(for: .phoneCode(code: code)) + + switch signIn.status { + case .complete: + // If verification was completed, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signIn.status) + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` diff --git a/docs/custom-flows/forgot-password.mdx b/docs/custom-flows/forgot-password.mdx index 3e3490af8b..6878029be1 100644 --- a/docs/custom-flows/forgot-password.mdx +++ b/docs/custom-flows/forgot-password.mdx @@ -160,107 +160,106 @@ For the sake of this guide, this example is written for Next.js App Router but i import ClerkSDK struct ForgotPasswordView: View { - @ObservedObject private var clerk = Clerk.shared - @State private var email = "" - @State private var code = "" - @State private var newPassword = "" - @State private var isVerifying = false + @ObservedObject private var clerk = Clerk.shared + @State private var email = "" + @State private var code = "" + @State private var newPassword = "" + @State private var isVerifying = false - var body: some View { + var body: some View { + switch clerk.client?.signIn?.status { + case .needsFirstFactor: + if isVerifying { + TextField("Enter your code", text: $code) + Button("Verify") { + Task { await verify(code: code) } + } + } else { + Button("Forgot password?") { + Task { await sendResetCode() } + } + } + + case .needsSecondFactor: + Text("2FA is required, but this UI does not handle that") + + case .needsNewPassword: + SecureField("New password", text: $newPassword) + Button("Set new password") { + Task { await setNewPassword(password: newPassword) } + } - switch clerk.client?.signIn?.status { - case .needsFirstFactor: - if isVerifying { - TextField("Enter your code", text: $code) - Button("Verify") { - Task { await verify(code: code) } - } - } else { - Button("Forgot password?") { - Task { await sendResetCode() } - } - } - - case .needsSecondFactor: - Text("2FA is required, but this UI does not handle that") - - case .needsNewPassword: - SecureField("New password", text: $newPassword) - Button("Set new password") { - Task { await setNewPassword(password: newPassword) } - } - - default: - if let session = clerk.session { - Text("Active Session: \(session.id)") - } else { - TextField("Email", text: $email) - Button("Continue") { - Task { await createSignIn(email: email) } - } - } + default: + if let session = clerk.session { + Text("Active Session: \(session.id)") + } else { + TextField("Email", text: $email) + Button("Continue") { + Task { await createSignIn(email: email) } } + } } + } } extension ForgotPasswordView { - func createSignIn(email: String) async { - do { - // Start the sign in process - try await SignIn.create(strategy: .identifier(email)) - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func createSignIn(email: String) async { + do { + // Start the sign in process + try await SignIn.create(strategy: .identifier(email)) + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func sendResetCode() async { - do { - // Access the in progress sign in stored on the client object. - guard let inProgressSignIn = clerk.client?.signIn else { return } - - // Send the password reset code to the user's email - try await inProgressSignIn.prepareFirstFactor(for: .resetPasswordEmailCode) - - // Set isVerifying to true to capture the OTP code. - isVerifying = true - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func sendResetCode() async { + do { + // Access the in progress sign in stored on the client object. + guard let inProgressSignIn = clerk.client?.signIn else { return } + + // Send the password reset code to the user's email + try await inProgressSignIn.prepareFirstFactor(for: .resetPasswordEmailCode) + + // Set isVerifying to true to capture the OTP code. + isVerifying = true + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func verify(code: String) async { - do { - // Access the in progress sign in stored on the client object. - guard let inProgressSignIn = clerk.client?.signIn else { return } - - // Verify the code sent to the user's email - try await inProgressSignIn.attemptFirstFactor(for: .resetPasswordEmailCode(code: code)) - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func verify(code: String) async { + do { + // Access the in progress sign in stored on the client object. + guard let inProgressSignIn = clerk.client?.signIn else { return } + + // Verify the code sent to the user's email + try await inProgressSignIn.attemptFirstFactor(for: .resetPasswordEmailCode(code: code)) + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } - func setNewPassword(password: String) async { - do { - // Access the in progress sign in stored on the client object. - guard let inProgressSignIn = clerk.client?.signIn else { return } - - // Reset the user's password. - // Upon successful reset, the user will be signed in - try await inProgressSignIn.resetPassword(.init(password: password, signOutOfOtherSessions: true)) - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling - dump(error) - } + func setNewPassword(password: String) async { + do { + // Access the in progress sign in stored on the client object. + guard let inProgressSignIn = clerk.client?.signIn else { return } + + // Reset the user's password. + // Upon successful reset, the user will be signed in + try await inProgressSignIn.resetPassword(.init(password: password, signOutOfOtherSessions: true)) + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling + dump(error) } + } } ``` diff --git a/docs/custom-flows/oauth-connections.mdx b/docs/custom-flows/oauth-connections.mdx index 04511c9a48..9db03b02a3 100644 --- a/docs/custom-flows/oauth-connections.mdx +++ b/docs/custom-flows/oauth-connections.mdx @@ -159,62 +159,61 @@ When using OAuth, the sign-up and sign-in flows are equivalent. import ClerkSDK struct OAuthView: View { - - var body: some View { - // Render a button for each supported OAuth provider - // you want to add to your app. This example uses only Google. - Button("Sign In with Google") { - Task { await signInWithOAuth(provider: .google) } - } + var body: some View { + // Render a button for each supported OAuth provider + // you want to add to your app. This example uses only Google. + Button("Sign In with Google") { + Task { await signInWithOAuth(provider: .google) } } + } } extension OAuthView { - func signInWithOAuth(provider: SocialProvider) async { - do { - // Start the sign-in process using the selected OAuth provider. - let signIn = try await SignIn.create(strategy: .social(provider)) - - // Start the OAuth process - let externalAuthResult = try await signIn.authenticateWithRedirect() - - // It is common for users who are authenticating with OAuth to use - // a sign-in button when they mean to sign-up, and vice versa. - // Clerk will handle this transfer for you if possible. - // Therefore, an ExternalAuthResult can contain either a SignIn or SignUp. - - // Check if the result of the OAuth was a sign in - if let signIn = externalAuthResult?.signIn { - switch signIn.status { - case .complete: - // If sign-in process is complete, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signIn.status) - } - } - - // Check if the result of the OAuth was a sign up - if let signUp = externalAuthResult?.signUp { - switch signUp.status { - case .complete: - // If sign-up process is complete, navigate the user as needed. - dump(Clerk.shared.session) - default: - // If the status is not complete, check why. User may need to - // complete further steps. - dump(signUp.status) - } - } - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling. - dump(error) + func signInWithOAuth(provider: SocialProvider) async { + do { + // Start the sign-in process using the selected OAuth provider. + let signIn = try await SignIn.create(strategy: .social(provider)) + + // Start the OAuth process + let externalAuthResult = try await signIn.authenticateWithRedirect() + + // It is common for users who are authenticating with OAuth to use + // a sign-in button when they mean to sign-up, and vice versa. + // Clerk will handle this transfer for you if possible. + // Therefore, an ExternalAuthResult can contain either a SignIn or SignUp. + + // Check if the result of the OAuth was a sign in + if let signIn = externalAuthResult?.signIn { + switch signIn.status { + case .complete: + // If sign-in process is complete, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signIn.status) } + } + + // Check if the result of the OAuth was a sign up + if let signUp = externalAuthResult?.signUp { + switch signUp.status { + case .complete: + // If sign-up process is complete, navigate the user as needed. + dump(Clerk.shared.session) + default: + // If the status is not complete, check why. User may need to + // complete further steps. + dump(signUp.status) + } + } + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling. + dump(error) } + } } ``` diff --git a/docs/custom-flows/sign-out.mdx b/docs/custom-flows/sign-out.mdx index 74e0e1c343..d0e4562a73 100644 --- a/docs/custom-flows/sign-out.mdx +++ b/docs/custom-flows/sign-out.mdx @@ -127,31 +127,31 @@ Please note that the sign-out flow only deactivates the current session. Other v import ClerkSDK struct SignOutView: View { - @ObservedObject private var clerk = Clerk.shared - - var body: some View { - if let session = clerk.session { - Text("Active Session: \(session.id)") - Button("Sign out") { - Task { await signOut() } - } - } else { - Text("You are signed out") - } + @ObservedObject private var clerk = Clerk.shared + + var body: some View { + if let session = clerk.session { + Text("Active Session: \(session.id)") + Button("Sign out") { + Task { await signOut() } + } + } else { + Text("You are signed out") } + } } extension SignOutView { - func signOut() async { - do { - try await clerk.signOut() - } catch { - // See https://clerk.com/docs/custom-flows/error-handling - // for more info on error handling. - dump(error) - } + func signOut() async { + do { + try await clerk.signOut() + } catch { + // See https://clerk.com/docs/custom-flows/error-handling + // for more info on error handling. + dump(error) } + } } ```