Skip to content

Commit

Permalink
feat(auth): add signInWithOAuth (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
grdsdev committed Apr 12, 2024
1 parent 3b74720 commit 1290bcf
Show file tree
Hide file tree
Showing 14 changed files with 468 additions and 102 deletions.
12 changes: 8 additions & 4 deletions Examples/Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
793E03092B2CED5D00AC7DED /* Contants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793E03082B2CED5D00AC7DED /* Contants.swift */; };
793E030B2B2CEDDA00AC7DED /* ActionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793E030A2B2CEDDA00AC7DED /* ActionState.swift */; };
793E030D2B2DAB5700AC7DED /* SignInWithApple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793E030C2B2DAB5700AC7DED /* SignInWithApple.swift */; };
7940E3152B36187A0089BEE1 /* GoogleSignInWithWebFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7940E3142B36187A0089BEE1 /* GoogleSignInWithWebFlow.swift */; };
79401F332BC6FEAE004C9C0F /* SignInWithOAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79401F322BC6FEAE004C9C0F /* SignInWithOAuth.swift */; };
79401F352BC708C8004C9C0F /* UIViewControllerWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79401F342BC708C8004C9C0F /* UIViewControllerWrapper.swift */; };
794C61D62BAD1E12000E6B0F /* UserIdentityList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794C61D52BAD1E12000E6B0F /* UserIdentityList.swift */; };
794EF1222955F26A008C9526 /* AddTodoListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794EF1212955F26A008C9526 /* AddTodoListView.swift */; };
794EF1242955F3DE008C9526 /* TodoListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794EF1232955F3DE008C9526 /* TodoListRow.swift */; };
Expand Down Expand Up @@ -83,7 +84,8 @@
793E03082B2CED5D00AC7DED /* Contants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contants.swift; sourceTree = "<group>"; };
793E030A2B2CEDDA00AC7DED /* ActionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionState.swift; sourceTree = "<group>"; };
793E030C2B2DAB5700AC7DED /* SignInWithApple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInWithApple.swift; sourceTree = "<group>"; };
7940E3142B36187A0089BEE1 /* GoogleSignInWithWebFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSignInWithWebFlow.swift; sourceTree = "<group>"; };
79401F322BC6FEAE004C9C0F /* SignInWithOAuth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInWithOAuth.swift; sourceTree = "<group>"; };
79401F342BC708C8004C9C0F /* UIViewControllerWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerWrapper.swift; sourceTree = "<group>"; };
794C61D52BAD1E12000E6B0F /* UserIdentityList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentityList.swift; sourceTree = "<group>"; };
794EF1212955F26A008C9526 /* AddTodoListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTodoListView.swift; sourceTree = "<group>"; };
794EF1232955F3DE008C9526 /* TodoListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoListRow.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -221,6 +223,7 @@
79E2B55B2B97A2310042CD21 /* UIApplicationExtensions.swift */,
797EFB672BABD90500098D6B /* Stringfy.swift */,
79B1C80D2BAC017C00D991AA /* AnyJSONView.swift */,
79401F342BC708C8004C9C0F /* UIViewControllerWrapper.swift */,
);
path = Examples;
sourceTree = "<group>";
Expand Down Expand Up @@ -258,9 +261,9 @@
79AF047E2B2CE207008761AD /* AuthWithEmailAndPassword.swift */,
79AF04832B2CE408008761AD /* AuthWithMagicLink.swift */,
793E030C2B2DAB5700AC7DED /* SignInWithApple.swift */,
7940E3142B36187A0089BEE1 /* GoogleSignInWithWebFlow.swift */,
79E2B5542B9788BF0042CD21 /* GoogleSignInSDKFlow.swift */,
79C9B8E42BBB16C0003AD942 /* SignInAnonymously.swift */,
79401F322BC6FEAE004C9C0F /* SignInWithOAuth.swift */,
);
path = Auth;
sourceTree = "<group>";
Expand Down Expand Up @@ -486,6 +489,8 @@
796298992AEBBA77000AA957 /* MFAFlow.swift in Sources */,
79AF04862B2CE586008761AD /* Debug.swift in Sources */,
79AF04842B2CE408008761AD /* AuthWithMagicLink.swift in Sources */,
79401F352BC708C8004C9C0F /* UIViewControllerWrapper.swift in Sources */,
79401F332BC6FEAE004C9C0F /* SignInWithOAuth.swift in Sources */,
79B1C80E2BAC017C00D991AA /* AnyJSONView.swift in Sources */,
79E2B5552B9788BF0042CD21 /* GoogleSignInSDKFlow.swift in Sources */,
793E03092B2CED5D00AC7DED /* Contants.swift in Sources */,
Expand All @@ -504,7 +509,6 @@
795640602954AE140088A06F /* AuthController.swift in Sources */,
79AF047F2B2CE207008761AD /* AuthWithEmailAndPassword.swift in Sources */,
795640622955AD2B0088A06F /* HomeView.swift in Sources */,
7940E3152B36187A0089BEE1 /* GoogleSignInWithWebFlow.swift in Sources */,
793895CA2954ABFF0044F2B8 /* ExamplesApp.swift in Sources */,
797EFB682BABD90500098D6B /* Stringfy.swift in Sources */,
797EFB6C2BABE1B800098D6B /* FileObjectDetailView.swift in Sources */,
Expand Down
10 changes: 7 additions & 3 deletions Examples/Examples/Auth/AuthView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ struct AuthView: View {
case emailAndPassword
case magicLink
case signInWithApple
case googleSignInWebFlow
case signInWithOAuth
case signInWithOAuthUsingUIKit
case googleSignInSDKFlow
case signInAnonymously

Expand All @@ -21,7 +22,8 @@ struct AuthView: View {
case .emailAndPassword: "Auth with Email & Password"
case .magicLink: "Auth with Magic Link"
case .signInWithApple: "Sign in with Apple"
case .googleSignInWebFlow: "Google Sign in (Web Flow)"
case .signInWithOAuth: "Sign in with OAuth flow"
case .signInWithOAuthUsingUIKit: "Sign in with OAuth flow (UIKit)"
case .googleSignInSDKFlow: "Google Sign in (GIDSignIn SDK Flow)"
case .signInAnonymously: "Sign in Anonymously"
}
Expand Down Expand Up @@ -50,7 +52,9 @@ extension AuthView.Option: View {
case .emailAndPassword: AuthWithEmailAndPassword()
case .magicLink: AuthWithMagicLink()
case .signInWithApple: SignInWithApple()
case .googleSignInWebFlow: GoogleSignInWithWebFlow()
case .signInWithOAuth: SignInWithOAuth()
case .signInWithOAuthUsingUIKit: UIViewControllerWrapper(SignInWithOAuthViewController())
.edgesIgnoringSafeArea(.all)
case .googleSignInSDKFlow: GoogleSignInSDKFlow()
case .signInAnonymously: SignInAnonymously()
}
Expand Down
41 changes: 0 additions & 41 deletions Examples/Examples/Auth/GoogleSignInWithWebFlow.swift

This file was deleted.

122 changes: 122 additions & 0 deletions Examples/Examples/Auth/SignInWithOAuth.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//
// SignInWithOAuth.swift
// Examples
//
// Created by Guilherme Souza on 10/04/24.
//

import AuthenticationServices
import Supabase
import SwiftUI

struct SignInWithOAuth: View {
let providers = Provider.allCases

@State var provider = Provider.allCases[0]
@Environment(\.webAuthenticationSession) var webAuthenticationSession

var body: some View {
VStack {
Picker("Provider", selection: $provider) {
ForEach(providers) { provider in
Text("\(provider)").tag(provider)
}
}

Button("Start Sign-in Flow") {
Task {
do {
try await supabase.auth.signInWithOAuth(
provider: provider,
redirectTo: Constants.redirectToURL,
launchFlow: { @MainActor url in
try await webAuthenticationSession.authenticate(
using: url,
callbackURLScheme: Constants.redirectToURL.scheme!
)
}
)
} catch {
debug("Failed to sign-in with OAuth flow: \(error)")
}
}
}
}
}
}

final class SignInWithOAuthViewController: UIViewController, UIPickerViewDataSource,
UIPickerViewDelegate
{
let providers = Provider.allCases
var provider = Provider.allCases[0]

let providerPicker = UIPickerView()
let signInButton = UIButton(type: .system)

override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}

func setupViews() {
view.backgroundColor = .white

providerPicker.dataSource = self
providerPicker.delegate = self
view.addSubview(providerPicker)
providerPicker.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
providerPicker.centerXAnchor.constraint(equalTo: view.centerXAnchor),
providerPicker.centerYAnchor.constraint(equalTo: view.centerYAnchor),
providerPicker.widthAnchor.constraint(equalToConstant: 200),
providerPicker.heightAnchor.constraint(equalToConstant: 100),
])

signInButton.setTitle("Start Sign-in Flow", for: .normal)
signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
view.addSubview(signInButton)
signInButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signInButton.topAnchor.constraint(equalTo: providerPicker.bottomAnchor, constant: 20),
])
}

@objc func signInButtonTapped() {
Task {
do {
try await supabase.auth.signInWithOAuth(
provider: provider,
redirectTo: Constants.redirectToURL
)
} catch {
debug("Failed to sign-in with OAuth flow: \(error)")
}
}
}

func numberOfComponents(in _: UIPickerView) -> Int {
1
}

func pickerView(_: UIPickerView, numberOfRowsInComponent _: Int) -> Int {
providers.count
}

func pickerView(_: UIPickerView, titleForRow row: Int, forComponent _: Int) -> String? {
"\(providers[row])"
}

func pickerView(_: UIPickerView, didSelectRow row: Int, inComponent _: Int) {
provider = providers[row]
}
}

#Preview("SwiftUI") {
SignInWithOAuth()
}

#Preview("UIKit") {
SignInWithOAuthViewController()
}
7 changes: 6 additions & 1 deletion Examples/Examples/ExamplesApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ struct ExamplesApp: App {
let supabase = SupabaseClient(
supabaseURL: Secrets.supabaseURL,
supabaseKey: Secrets.supabaseAnonKey,
options: .init(global: .init(logger: ConsoleLogger()))
options: .init(
auth: .init(redirectToURL: Constants.redirectToURL),
global: .init(
logger: ConsoleLogger()
)
)
)

struct ConsoleLogger: SupabaseLogger {
Expand Down
26 changes: 26 additions & 0 deletions Examples/Examples/UIViewControllerWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// UIViewControllerWrapper.swift
// Examples
//
// Created by Guilherme Souza on 10/04/24.
//

import SwiftUI

struct UIViewControllerWrapper<T: UIViewController>: UIViewControllerRepresentable {
typealias UIViewControllerType = T

let viewController: T

init(_ viewController: T) {
self.viewController = viewController
}

func makeUIViewController(context _: Context) -> T {
viewController
}

func updateUIViewController(_: T, context _: Context) {
// Update the view controller if needed
}
}
Loading

0 comments on commit 1290bcf

Please sign in to comment.