feat(auth): Google sign-in across Android, iOS, and desktop#175
Open
plusmobileapps wants to merge 1 commit into
Open
feat(auth): Google sign-in across Android, iOS, and desktop#175plusmobileapps wants to merge 1 commit into
plusmobileapps wants to merge 1 commit into
Conversation
Adds a "Continue with Google" button to the auth screen that drives Supabase's signInWith(IDToken) using a platform-specific native flow: - Android: Credential Manager + googleid library - iOS: Swift bridge calling GoogleSignIn-iOS (SPM dep added in Xcode) - Desktop: system browser + loopback HTTP server (RFC 8252, with PKCE) The provider is an `expect class GoogleSignInProvider` in `client/auth/data/impl`, with each actual returning a (idToken, rawNonce) pair that SupabaseAuthenticationRepository hands to Supabase. The raw nonce → SHA-256 → ID-token-nonce-claim chain prevents replay attacks. Cancellation is modelled as `Result.success(GoogleSignInOutcome.Cancelled)` so the UI clears loading without navigating or showing an error dialog. Setup (Google Cloud client IDs, Supabase provider config, Xcode SDK install) is documented in docs/google-sign-in-setup.md. Also widens the ktfmt exclusion pattern to all `build/` outputs so newly generated BuildKonfig fields don't fail formatting checks. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
||
| @Provides | ||
| @SingleIn(AppScope::class) | ||
| fun provideGoogleSignInProvider(): GoogleSignInProvider = GoogleSignInProvider() |
There was a problem hiding this comment.
can an expect/actual function be created to create the google sign in provider? that way it can be called directly in the common main component to avoid declaring this in each platform component?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Continue with Google button to the auth screen, wired up natively on all three targets via Supabase's
signInWith(IDToken):googleidlibrarylocalhost:<random-port>(RFC 8252, with PKCE)GoogleSignInProvideris anexpect classinclient/auth/data/impl. Each actual returns a(idToken, rawNonce)pair thatSupabaseAuthenticationRepositoryhands to Supabase. Theraw nonce → SHA-256 → ID-token nonce claimchain prevents replay attacks — Supabase verifies it on its side.Cancellation is modelled as
Result.success(GoogleSignInOutcome.Cancelled)so the UI just clears the loading dialog without navigating forward or showing an error.Required setup before this works
Detailed walkthrough in
docs/google-sign-in-setup.md. The short version:local.properties— addgoogle.webClientId,google.desktopClientId,google.desktopClientSecret.https://github.com/google/GoogleSignIn-iOS, addGoogleSignInBridge.swiftto the iosApp target, addGIDClientID+ reverse-client URL scheme toInfo.plist.Until those are done, the button shows a "not configured" error on each platform — nothing else breaks.
Notable design choices
MyApplicationregisters anActivityLifecycleCallbacksthat populates aCurrentActivityHoldersingleton, so the provider can resolve a resumedActivityat call time without baking it into the DI graph lifetime.build/excluded from ktfmt — newly-generatedBuildConfig.ktfields were causingktfmtCheckto fail on a generated file. The convention plugin now skips allbuild/outputs, not just paths matchinggenerated.Test plan
./gradlew ktfmtCheck— passes./gradlew :client:auth:data:impl:compileKotlinJvm :client:auth:data:impl:compileDebugKotlinAndroid :client:auth:data:impl:compileKotlinIosSimulatorArm64— all three compile./gradlew :client:composeApp:compileKotlinJvm :client:composeApp:compileDebugKotlinAndroid :client:composeApp:compileKotlinIosSimulatorArm64— all compile./gradlew :client:auth:ui:impl:test— newAuthenticationViewModelGoogleTestcovers success / cancelled / failure casesinstallDebug→ tap "Continue with Google" → Credential Manager sheet → sign in → land on main./gradlew :client:composeApp:run→ tap "Continue with Google" → system browser opens → sign in → browser auto-closes → land on main🤖 Generated with Claude Code