Custom nonce support for backend verification (Supabase, Firebase, custom OIDC)#6
Conversation
📝 WalkthroughWalkthroughThis PR adds nonce-based backend verification support for the Google Sign-In plugin. It introduces three new public methods for nonce-enabled sign-in flows, implements internal nonce hashing and generation logic, adds the Gradle wrapper script, and includes documentation describing the nonce verification workflow. Changes
Sequence DiagramsequenceDiagram
participant Client as Client App
participant GodotGoogleSignIn as GodotGoogleSignIn
participant NonceHandler as Nonce Handler
participant GoogleSignIn as Google Sign-In API
participant Backend as Backend Server
Client->>GodotGoogleSignIn: signInWithNonce(rawNonce)
GodotGoogleSignIn->>NonceHandler: hashNonce(rawNonce)
NonceHandler-->>GodotGoogleSignIn: hashedNonce (SHA-256)
GodotGoogleSignIn->>GoogleSignIn: startSignIn(hashedNonce)
GoogleSignIn-->>GodotGoogleSignIn: idToken
GodotGoogleSignIn-->>Client: idToken
Client->>Backend: verify(idToken, rawNonce)
Backend->>NonceHandler: hashNonce(rawNonce)
Backend-->>Client: verification result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Closes #5 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
plugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt (1)
98-101: Consider validating that rawNonce is non-empty.The method accepts any String including empty strings. An empty or very short nonce would produce a valid SHA-256 hash but would defeat the security purpose of the nonce (replay protection). Consider adding validation:
🛡️ Optional: Add nonce validation
`@UsedByGodot` fun signInWithNonce(rawNonce: String) { + if (rawNonce.isBlank()) { + emitSignal(signInFailedSignal.name, "rawNonce must not be empty") + return + } signInInternal(rawNonce) }Similar validation could be added to
signInWithAccountChooserWithNonceandsignInWithGoogleButtonWithNonce.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt` around lines 98 - 101, Validate that the incoming rawNonce is non-empty (and optionally meets a minimum length) before calling signInInternal; in signInWithNonce check rawNonce.trim().isNotEmpty() and if not, log or throw a clear error and return without calling signInInternal. Apply the same validation pattern to signInWithAccountChooserWithNonce and signInWithGoogleButtonWithNonce to ensure empty/too-short nonces are rejected consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@plugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt`:
- Around line 337-341: The hashNonce function currently calls
rawNonce.toByteArray() which relies on the platform default charset; change it
to use an explicit charset (e.g., StandardCharsets.UTF_8) when converting
rawNonce to bytes so hashing is consistent across devices and JVM locales—update
hashNonce to obtain bytes with rawNonce.toByteArray(StandardCharsets.UTF_8)
before passing to MessageDigest.getInstance("SHA-256").digest(...) and keep the
existing hex folding logic unchanged.
---
Nitpick comments:
In
`@plugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt`:
- Around line 98-101: Validate that the incoming rawNonce is non-empty (and
optionally meets a minimum length) before calling signInInternal; in
signInWithNonce check rawNonce.trim().isNotEmpty() and if not, log or throw a
clear error and return without calling signInInternal. Apply the same validation
pattern to signInWithAccountChooserWithNonce and signInWithGoogleButtonWithNonce
to ensure empty/too-short nonces are rejected consistently.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d819d4e1-fad3-4d5d-9f92-27f69fb1c53c
📒 Files selected for processing (4)
README.mdaddons/GodotGoogleSignIn/bin/release/GodotGoogleSignIn-release.aarplugin/gradlewplugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt
| private fun hashNonce(rawNonce: String): String { | ||
| val bytes = rawNonce.toByteArray() | ||
| val md = MessageDigest.getInstance("SHA-256") | ||
| val digest = md.digest(bytes) | ||
| val digest = MessageDigest.getInstance("SHA-256").digest(bytes) | ||
| return digest.fold("") { str, it -> str + "%02x".format(it) } | ||
| } |
There was a problem hiding this comment.
Specify charset explicitly for consistent hashing across platforms.
toByteArray() without a charset argument uses the platform's default encoding, which can vary across JVMs and locales. This could cause the hash to differ between devices, leading to nonce verification failures on the backend.
🔧 Proposed fix
private fun hashNonce(rawNonce: String): String {
- val bytes = rawNonce.toByteArray()
+ val bytes = rawNonce.toByteArray(Charsets.UTF_8)
val digest = MessageDigest.getInstance("SHA-256").digest(bytes)
return digest.fold("") { str, it -> str + "%02x".format(it) }
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@plugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt`
around lines 337 - 341, The hashNonce function currently calls
rawNonce.toByteArray() which relies on the platform default charset; change it
to use an explicit charset (e.g., StandardCharsets.UTF_8) when converting
rawNonce to bytes so hashing is consistent across devices and JVM locales—update
hashNonce to obtain bytes with rawNonce.toByteArray(StandardCharsets.UTF_8)
before passing to MessageDigest.getInstance("SHA-256").digest(...) and keep the
existing hex folding logic unchanged.
There was a problem hiding this comment.
Pull request overview
This PR adds opt-in custom raw-nonce variants to the three sign-in flows so callers can perform backend ID-token verification (Supabase, Firebase, custom OIDC) where the backend needs the raw nonce that corresponds to the hashed nonce claim in the ID token. The internal generateNonce() is refactored to delegate to a new hashNonce(rawNonce) helper, and three new @UsedByGodot methods (signInWithNonce, signInWithAccountChooserWithNonce, signInWithGoogleButtonWithNonce) wrap private *Internal methods that accept a nullable raw nonce. README is updated with the new API rows and a new "Backend Verification with Nonce" section including a GDScript example.
Changes:
- Add three nonce-accepting sign-in methods and refactor existing flows to share
*Internalhelpers that hash the supplied raw nonce instead of generating one. - Extract a
hashNonce()helper fromgenerateNonce()for SHA-256 hex hashing. - Document the new API and a Supabase-style backend verification flow in
README.md.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| plugin/src/main/kotlin/com/niquewrld/casino/googlesignin/GodotGoogleSignIn.kt | Adds signIn*WithNonce variants and *Internal helpers; refactors nonce generation to reuse hashNonce. |
| README.md | Documents the new methods and adds a backend-verification-with-nonce guide and example. |
| plugin/gradlew | Adds a gradlew script that is the standard Gradle wrapper template but with the upstream copyright header replaced by a personal/company copyright — unrelated to this PR. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # © 2026 Uche Ogbuji (uche@oori.dev), Oori Data LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # https://www.apache.org/licenses/LICENSE-2.0 |
Proposed & tested fix for #5
Summary by CodeRabbit
Release Notes
New Features
Documentation