Skip to content

Commit

Permalink
Use AuthenticationService to sign in instead of SFSafariViewController
Browse files Browse the repository at this point in the history
  • Loading branch information
DRSchlaubi committed Oct 20, 2023
1 parent 38b3d19 commit 7b6a851
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 96 deletions.
1 change: 0 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion app/android/src/main/java/AppActivity.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package dev.schlaubi.tonbrett.app.android

import android.net.Uri
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import dev.schlaubi.tonbrett.app.MobileTonbrettApp
import dev.schlaubi.tonbrett.app.ProvideImageLoader
import dev.schlaubi.tonbrett.app.api.AppContext
import dev.schlaubi.tonbrett.app.api.LocalContext
import dev.schlaubi.tonbrett.app.api.ProvideContext
import dev.schlaubi.tonbrett.app.api.tokenKey

Expand All @@ -28,7 +33,10 @@ class AppActivity : AppCompatActivity() {
ProvideContext(context) {
ProvideImageLoader {
UpdateAwareAppScope(activity = this) {
MobileTonbrettApp(token)
MobileTonbrettApp(token) { url ->
val intent = CustomTabsIntent.Builder().build()
intent.launchUrl(this@AppActivity, Uri.parse(url))
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions app/ios/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.3;
Expand Down Expand Up @@ -436,7 +436,7 @@
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.3;
Expand Down
37 changes: 35 additions & 2 deletions app/ios/iosApp/ComposeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,52 @@ import shared

struct ComposeView: UIViewControllerRepresentable {
let receivedToken: String?
let onAuth: (String) -> Void

func makeUIViewController(context: Context) -> some UIViewController {
MainKt.MainUiViewController(receivedToken: receivedToken)
MainKt.MainUiViewController(receivedToken: receivedToken, onAuth: onAuth)
}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
}

struct ContentView: View {
let receivedToken: String?
let onAuth: (String) async -> Void
@Environment(\.webAuthenticationSession) private var webAuthenticationSession

var body: some View {
ComposeView(receivedToken: receivedToken)
ComposeView(receivedToken: receivedToken, onAuth: signIn)
.ignoresSafeArea(.keyboard) // Compose has own keyboard handler
.preferredColorScheme(.dark) // there is no light theme YET or ever
}

func signIn(url: String) {
Task {
do {
let urlWithToken = try await webAuthenticationSession.authenticate(
using: URL(string: url)!,
callbackURLScheme: "tonbrett",
preferredBrowserSession: nil
)

let token = urlWithToken.queryParameters!["token"]!

await onAuth(token)
} catch {
print("Unexpected error: \(error).")
}
}
}
}

extension URL {
public var queryParameters: [String: String]? {
guard
let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else { return nil }
return queryItems.reduce(into: [String: String]()) { (result, item) in
result[item.name] = item.value
}
}
}
33 changes: 9 additions & 24 deletions app/ios/iosApp/iosAppApp.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import SwiftUI
import shared
import FirebaseCore
import Foundation
import AuthenticationServices

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
Expand All @@ -22,32 +24,15 @@ struct TonbrettApp: App {
VStack {
ProgressView()
}.fullScreenCover(isPresented: $loadApp, content: {
ComposeView(receivedToken: token)
}).onOpenURL(perform: { incomingUrl in
if(incomingUrl.scheme == "tonbrett" && incomingUrl.host == "login") {
let token = incomingUrl.queryParameters!["token"]!
self.loadApp = false
self.token = token
Task {
try? await Task.sleep(nanoseconds: 1_000_000_000)
loadApp = true
}
}
ContentView(receivedToken: token, onAuth: onAuth)
})
}
}
}




extension URL {
public var queryParameters: [String: String]? {
guard
let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else { return nil }
return queryItems.reduce(into: [String: String]()) { (result, item) in
result[item.name] = item.value
}

func onAuth(token: String) async {
loadApp = false
self.token = token
try? await Task.sleep(nanoseconds: 1_000_000_000)
loadApp = true
}
}
5 changes: 3 additions & 2 deletions app/ios/src/appleMain/kotlin/Main.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import androidx.compose.ui.window.ComposeUIViewController
import com.liftric.kvault.KVault
import dev.schlaubi.tonbrett.app.MobileTonbrettApp
import dev.schlaubi.tonbrett.app.api.ProvideContext
import platform.UIKit.UIViewController

@Suppress("FunctionName", "unused")
fun MainUiViewController(receivedToken: String?): UIViewController {
fun MainUiViewController(receivedToken: String?, onAuth: (url: String) -> Unit): UIViewController {
var onPresent: (UIViewController) -> Unit = {}
val context = object : AppleAppContext() {
override fun present(viewController: UIViewController) = onPresent(viewController)

}
val controller = ComposeUIViewController {
ProvideContext(context) {
MobileTonbrettApp(receivedToken)
MobileTonbrettApp(receivedToken, onAuth)
}
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,35 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import cafe.adriel.lyricist.LocalStrings
import dev.schlaubi.tonbrett.app.api.LocalContext
import dev.schlaubi.tonbrett.app.api.getUrl
import dev.schlaubi.tonbrett.app.util.InAppBrowser
import dev.schlaubi.tonbrett.client.href
import dev.schlaubi.tonbrett.common.Route

@Composable
fun MobileTonbrettApp(receivedToken: String? = null) {
fun MobileTonbrettApp(receivedToken: String? = null, onAuth: (url: String) -> Unit) {
val sessionExpired = remember { mutableStateOf(false) }
val context = LocalContext.current
var showLogin by remember { mutableStateOf(false) }
if (showLogin) {
showLogin = false

fun authorize() {
val url = href(Route.Auth(Route.Auth.Type.MOBILE_APP), getUrl())
InAppBrowser(url)
} else if (receivedToken != null || context.isSignedIn || sessionExpired.value) {
onAuth(url)
}

if (receivedToken != null || context.isSignedIn || sessionExpired.value) {
if (receivedToken != null) {
sessionExpired.value = false
context.token = receivedToken
}
context.resetApi()

SideEffect {
context.withReAuthroize {
showLogin = true
}
context.withReAuthroize(::authorize)
}
TonbrettApp(sessionExpired)
} else {
Expand All @@ -57,9 +53,7 @@ fun MobileTonbrettApp(receivedToken: String? = null) {
} else {
Text(strings.pleaseSignIn)
}
Button({
showLogin = true
}) {
Button(::authorize) {
Icon(Icons.Default.OpenInBrowser, null)
Text(strings.signInWithDiscord)
}
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {

allprojects {
group = "dev.schlaubi.tonbrett"
version = "1.14.37"
version = "1.14.38"

repositories {
mavenCentral()
Expand Down

0 comments on commit 7b6a851

Please sign in to comment.