Conversation
WalkthroughThis update introduces native Apple Sign In support for iOS devices in the application. It adds the necessary Tauri plugin, updates configuration and capability files, and extends the login and signup pages to support Apple authentication when running on iOS within a Tauri environment. Platform detection logic is improved across several components to ensure Apple Sign In is only presented on supported devices. Additional documentation and type definitions are included to guide integration and provide type safety. The update also refactors some authentication callback logic for better modularity and upgrades frontend dependencies. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App (Tauri iOS)
participant Apple Plugin
participant Backend
User->>App (Tauri iOS): Clicks "Sign in with Apple"
App (Tauri iOS)->>Apple Plugin: Invoke native Apple Sign In
Apple Plugin->>User: Show Apple Sign In dialog
User->>Apple Plugin: Authenticate with Apple ID
Apple Plugin->>App (Tauri iOS): Return AppleCredential
App (Tauri iOS)->>Backend: Send AppleCredential for authentication
Backend-->>App (Tauri iOS): Respond with session/token
App (Tauri iOS)-->>User: Redirect to next page
Possibly related PRs
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
PR Summary
Implemented Sign in with Apple functionality for iOS in the Maple project, adding native authentication capabilities while maintaining existing OAuth flows.
- Added
tauri-plugin-sign-in-with-applev1.0.0 in/frontend/src-tauri/Cargo.tomlwith corresponding capabilities indefault.jsonandmobile-ios.json - Created comprehensive documentation at
/frontend/src-tauri/apple-sign-in-info.mddetailing integration steps and pending backend work - Added platform-specific Apple Sign In UI components in login/signup routes with iOS-only visibility
- Modified
/frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlementsfor proper Apple Sign In permissions - Updated
/frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxprojto use manual code signing with specific provisioning profile
11 file(s) reviewed, 4 comment(s)
Edit PR Review Bot Settings | Greptile
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
frontend/src-tauri/capabilities/mobile-ios.json (1)
13-21: Open‑URL wildcard may be overly permissive
"opener:allow-open-url"allows any path underhttp://localhost:5173/*andhttps://trymaple.ai/*.• For production builds consider removing the
httporigin entirely and/or scoping thehttpsorigin to just the OAuth callback path.
• If development needshttp://localhost:5173, make sure this file is NOT shipped in release builds (or gate it behind a dev‑only capability).frontend/src-tauri/apple-sign-in-info.md (1)
24-29: Minor grammar / wording nitpick“configured correctly to Sign in with Apple” reads better than “configured correctly for”.
-3. Ensure your Apple Developer account is configured correctly for Sign in with Apple +3. Ensure your Apple Developer account is configured correctly to use Sign in with Apple🧰 Tools
🪛 LanguageTool
[uncategorized] ~28-~28: The preposition ‘to’ seems more likely in this position.
Context: ...veloper account is configured correctly for Sign in with Apple ## Resources - [App...(AI_HYDRA_LEO_REPLACE_FOR_TO)
frontend/src/routes/login.tsx (1)
39-53: Guard plugin call behind a Tauri check
getPlatformType()(previouslytype()) throws when the plugin is missing – e.g., when the page is rendered in a plain browser during local dev. Consider short‑circuiting whenawait isTauri()returnsfalseto avoid needless exception spam.frontend/src/routes/signup.tsx (1)
39-53: Consider skipping platform detection when not in TauriSame reasoning as the login page: wrap the platform query with an
await isTauri()check to avoid exceptions in web builds.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
frontend/src-tauri/Cargo.lockis excluded by!**/*.lockfrontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxprojis excluded by!**/gen/**frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlementsis excluded by!**/gen/**
📒 Files selected for processing (9)
frontend/src-tauri/Cargo.toml(1 hunks)frontend/src-tauri/apple-sign-in-info.md(1 hunks)frontend/src-tauri/capabilities/default.json(1 hunks)frontend/src-tauri/capabilities/mobile-ios.json(1 hunks)frontend/src-tauri/src/lib.rs(3 hunks)frontend/src/components/icons/Apple.tsx(1 hunks)frontend/src/routes/desktop-auth.tsx(2 hunks)frontend/src/routes/login.tsx(5 hunks)frontend/src/routes/signup.tsx(5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
frontend/src/routes/login.tsx (3)
frontend/src/components/AuthMain.tsx (1)
AuthMain(11-44)frontend/src/components/AlertDestructive.tsx (1)
AlertDestructive(5-15)frontend/src/components/icons/Apple.tsx (1)
Apple(3-21)
frontend/src/routes/signup.tsx (3)
frontend/src/components/AuthMain.tsx (1)
AuthMain(11-44)frontend/src/components/AlertDestructive.tsx (1)
AlertDestructive(5-15)frontend/src/components/icons/Apple.tsx (1)
Apple(3-21)
🪛 LanguageTool
frontend/src-tauri/apple-sign-in-info.md
[uncategorized] ~28-~28: The preposition ‘to’ seems more likely in this position.
Context: ...veloper account is configured correctly for Sign in with Apple ## Resources - [App...
(AI_HYDRA_LEO_REPLACE_FOR_TO)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: build-macos (universal-apple-darwin)
- GitHub Check: build-ios
- GitHub Check: build-linux
- GitHub Check: Cloudflare Pages
🔇 Additional comments (11)
frontend/src-tauri/Cargo.toml (1)
32-32:Details
✅ Verification successful
Dependency addition looks good.
The
tauri-plugin-sign-in-with-appledependency has been correctly added to support Apple authentication functionality.
🌐 Web query:
Is tauri-plugin-sign-in-with-apple 1.0.0 the latest version available?💡 Result:
Based on the latest available information from the official Rust package registry (crates.io), the most recent version of the tauri-plugin-sign-in-with-apple crate is 1.0.0. There are no indications from the registry that a newer version has been published as of now1.
Citations:
- 1: https://crates.io/crates/tauri-plugin-sign-in-with-apple
- 2: https://tauri.app/distribute/sign/macos/
- 3: https://tauri.app/distribute/sign/ios/
- 4: tauri-apps/tauri#9518
- 5: https://tauri.app/v1/guides/distribution/sign-macos/
- 6: https://tauri.app/release/tauri-bundler/v1.0.0-rc.0/
- 7: https://v2.tauri.app/distribute/app-store/
- 8: https://v2.tauri.app/blog/tauri-20/
- 9: https://v2.tauri.app/distribute/macos-application-bundle/
- 10: https://v2.tauri.app/blog/tauri-1-0/
Dependency addition approved: tauri-plugin-sign-in-with-apple v1.0.0
- File – frontend/src-tauri/Cargo.toml (line 32):
tauri-plugin-sign-in-with-apple = "1.0.0"
• Verified that v1.0.0 is the latest version available on crates.io.No further changes required.
frontend/src/components/icons/Apple.tsx (1)
1-21: SVG component implementation is clean and follows best practices.The Apple icon component is well-structured with proper prop handling and styling flexibility through the use of
currentColorand props spreading.frontend/src-tauri/capabilities/default.json (1)
21-22: Permission correctly added for Apple Sign In functionality.The "sign-in-with-apple:default" permission has been properly added to the capabilities configuration, which is required for the Tauri plugin to function correctly.
frontend/src-tauri/src/lib.rs (3)
4-4: Plugin import correctly added.The import for the Sign In with Apple plugin is properly placed with other plugin imports.
25-25: Plugin correctly initialized for desktop builds.The Apple Sign In plugin is properly initialized in the desktop build configuration.
198-198: Plugin correctly initialized for mobile builds.The Apple Sign In plugin is properly initialized in the mobile build configuration.
frontend/src/routes/desktop-auth.tsx (2)
19-19: Provider validation correctly updated to include Apple.Apple has been properly added as a supported authentication provider in the validation check.
55-61: Authentication flow for Apple Sign In handled appropriately.The implementation correctly handles Apple Sign In differently from OAuth-based providers, recognizing that it should be handled natively on iOS.
The console log and redirect approach makes sense for the current implementation stage.
Consider verifying if this is the intended user experience for Apple authentication on desktop environments:
- Will desktop users also be able to use Apple Sign In?
- If not, should there be clearer messaging to users on desktop platforms?
frontend/src-tauri/capabilities/mobile-ios.json (2)
2-4: Verify schema path & platform identifier casing
- The
$schemavalue ("../gen/schemas/mobile-schema.json") must point to a real file, otherwise IDE validation will break silently.- Some tooling (and even Tauri itself) expects lower‑case platform identifiers (
"ios"). Please double‑check that"iOS"is accepted; otherwise use"ios".
23-24: Good to see Apple capability explicitly declaredDeclaring
"sign-in-with-apple:default"here keeps the permission surface minimal. 👍frontend/src/routes/login.tsx (1)
171-208:Details
❓ Verification inconclusive
Confirm payload shape for Apple plugin
According to
tauri-plugin-sign-in-with-appledocs the command accepts the payload directly, not nested underpayload. If left as‑is you may get “invalid request body” errors at runtime.-const result = await invoke("plugin:sign-in-with-apple|get_apple_id_credential", { - payload: { - scope: ["email", "fullName"], - state: "apple-signin-state", - options: { debug: true } - } -}); +const result = await invoke("plugin:sign-in-with-apple|get_apple_id_credential", { + scope: ["email", "fullName"], + state: "apple-signin-state", + options: { debug: true } +});Please verify against the crate’s README.
🌐 Web query:
tauri-plugin-sign-in-with-apple get_apple_id_credential invoke payload shape💡 Result:
Shape of the
invokePayload fortauri-plugin-sign-in-with-apple'sget_apple_id_credentialThe direct shape of the payload for invoking
get_apple_id_credentialin thetauri-plugin-sign-in-with-appleis not explicitly documented in the search results provided. Neither the plugin’s crate page nor the related GitHub discussions8 outline the function signature or the expected payload schema for this specific invoke command.Inferred Payload Structure
Given Tauri plugin conventions and standard Sign In with Apple (SIWA) flows, we can make a reasoned inference:
- Tauri plugin command invocations typically expect a payload as a JSON object, containing any parameters required by the Rust-side command. If no parameters are required, an empty object
{}is usually sent.- The SIWA flow generally requires you to specify the scopes (like
name) and, optionally, a nonce or client-specific information.Likely Payload Shape
A typical payload for a Sign in with Apple request, by analogy to other SIWA implementations and Tauri plugin convention, might look like:
{ "scopes": ["email", "name"], "nonce": "optional-random-string" }Fields:
scopes: an array of strings indicating which user info you are requesting (common values:"email","name").nonce: (optional) a string to mitigate replay attacks (if your backend requires it).Example Tauri Invoke
await window.__TAURI__.invoke('plugin:sign-in-with-apple|get_apple_id_credential', { scopes: ['email', 'name'], nonce: 'your-nonce-value' });
- If the command takes no parameters, you can invoke with an empty object or omit the payload.
How Commands Are Structured in Tauri Plugins
- Plugins register commands that are accessible via
window.__TAURI__.invoke('plugin:myplugin|my_command', payload).- The expected payload is defined by the Rust handler function signature (see Tauri plugin conventions).
What to Do if the Schema Is Unclear
- If you have access to the Rust source or TypeScript definitions of the plugin, check there for a
get_apple_id_credentialhandler and its input struct.- If the plugin is implemented as a passthrough to the Apple API via Swift/Objective-C, it will most likely expose the same parameter shapes as the native
ASAuthorizationAppleIDRequest.
Summary Table: Expected Payload
Field Type Required Example Description scopes array of string Yes ["email", "name"] User info fields requested nonce string Optional "randomstring" Nonce for security (if used by your backend)
Conclusion
- The exact payload shape is not documented in the provided sources.
- The standard practice for Tauri plugins suggests a JSON object with fields matching the parameters for Apple ID credential requests, most likely including at least
scopesas an array.- If in doubt, inspect the plugin’s Rust/TypeScript definitions or check runtime errors for payload hints.
References:
- tauri-plugin-sign-in-with-apple on crates.io
- Tauri Plugins documentation
- Awesome Tauri resources
- GitHub discussion
Citations:
- 1: https://crates.io/crates/tauri-plugin-sign-in-with-apple
- 2: tauri-apps/tauri#9518
- 3: https://tauri.app/v1/guides/distribution/sign-macos/
- 4: https://tauri.app/distribute/sign/macos/
- 5: https://tauri.app/v1/guides/features/plugin/
- 6: https://v2.tauri.app/distribute/sign/ios/
- 7: tauri-apps/tauri#8693
- 8: https://github.com/tauri-apps/awesome-tauri
- 9: https://v2.tauri.app/blog/tauri-20/
- 10: https://www.youtube.com/watch?v=dMJKXUFxD0Y
Verify payload structure for Sign In with Apple plugin
I didn’t find any official docs showing a nested
payloadobject—Tauri plugins expect the invoke parameters at the top level. Please check the plugin’s handler signature in your localnode_modules(or the Rust crate) to confirm.
- File:
frontend/src/routes/login.tsx–handleAppleLogininvocationSuggested diff:
- const result = await invoke("plugin:sign-in-with-apple|get_apple_id_credential", { - payload: { - scope: ["email", "fullName"], - state: "apple-signin-state", - options: { debug: true } - } - }); + const result = await invoke("plugin:sign-in-with-apple|get_apple_id_credential", { + scope: ["email", "fullName"], + state: "apple-signin-state", + options: { debug: true } + });Please verify against the plugin’s Rust/TypeScript definitions to ensure you’re using the correct parameter names and nesting.
ba1e2e2 to
463728b
Compare
Deploying maple with
|
| Latest commit: |
d9ecdde
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://02e2016e.maple-ca8.pages.dev |
| Branch Preview URL: | https://ios-auth.maple-ca8.pages.dev |
463728b to
8d7aded
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
frontend/src-tauri/apple-sign-in-info.md (5)
6-10: Include Cargo.toml snippet for plugin setupConsider adding a code snippet showing how to add the
tauri-plugin-sign-in-with-appledependency infrontend/src-tauri/Cargo.tomlfor easier onboarding:[dependencies] tauri-plugin-sign-in-with-apple = "1.0.0"
11-15: Link to frontend component implementationsFor better navigation, hyperlink or reference the paths to
routes/login.tsx,routes/signup.tsx, andcomponents/icons/Apple.tsxwhere the Apple Sign In logic is implemented.
16-23: Anchor future backend work to an issue trackerTo ensure follow‑through on backend integration, link this section to a GitHub issue or ticket where the token verification and account management tasks will be tracked.
24-29: Minor grammar refinementRephrase “configured correctly for Sign in with Apple” to “configured correctly to support Sign in with Apple” for improved clarity.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~28-~28: The preposition ‘to’ seems more likely in this position.
Context: ...veloper account is configured correctly for Sign in with Apple ## Resources - [App...(AI_HYDRA_LEO_REPLACE_FOR_TO)
30-32: Expand resources with plugin repository linkOptionally add the Tauri plugin’s GitHub repository for direct reference:
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
frontend/src-tauri/Cargo.lockis excluded by!**/*.lockfrontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlementsis excluded by!**/gen/**
📒 Files selected for processing (9)
frontend/src-tauri/Cargo.toml(1 hunks)frontend/src-tauri/apple-sign-in-info.md(1 hunks)frontend/src-tauri/capabilities/default.json(1 hunks)frontend/src-tauri/capabilities/mobile-ios.json(1 hunks)frontend/src-tauri/src/lib.rs(3 hunks)frontend/src/components/icons/Apple.tsx(1 hunks)frontend/src/routes/desktop-auth.tsx(2 hunks)frontend/src/routes/login.tsx(5 hunks)frontend/src/routes/signup.tsx(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
- frontend/src-tauri/Cargo.toml
- frontend/src-tauri/capabilities/default.json
- frontend/src-tauri/src/lib.rs
- frontend/src/routes/desktop-auth.tsx
- frontend/src-tauri/capabilities/mobile-ios.json
- frontend/src/components/icons/Apple.tsx
- frontend/src/routes/signup.tsx
- frontend/src/routes/login.tsx
🧰 Additional context used
🪛 LanguageTool
frontend/src-tauri/apple-sign-in-info.md
[uncategorized] ~28-~28: The preposition ‘to’ seems more likely in this position.
Context: ...veloper account is configured correctly for Sign in with Apple ## Resources - [App...
(AI_HYDRA_LEO_REPLACE_FOR_TO)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: build-linux
- GitHub Check: build-macos (universal-apple-darwin)
- GitHub Check: build-ios
- GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
frontend/src-tauri/apple-sign-in-info.md (2)
1-2: Clear and descriptive titleThe heading succinctly conveys the integration purpose and platform context.
3-5: Overview is concise and focusedThis section effectively introduces the iOS-specific Apple Sign In integration. No changes needed.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
frontend/src-tauri/apple-sign-in-info.md (1)
1-102: Remove this documentation file as previously requestedWhile this is comprehensive and well-written documentation on the Apple Sign In integration, there was a previous request from AnthonyRonning to remove this file. Consider moving this valuable content to the project's main documentation system instead of keeping it in the source code repository.
frontend/src/routes/signup.tsx (2)
13-13:⚠️ Potential issueAlias the
typeimport to avoid the reserved‑word collisionThe
typeidentifier collides with the TypeScript keywordtype, which can trip up tooling and ESLint rules and hurts readability. A previous review already raised this for the login page; please apply the same alias fix here as well.-import { type } from "@tauri-apps/plugin-os"; +import { type as getPlatformType } from "@tauri-apps/plugin-os";…and update the call site (
await getPlatformType()).
181-190:⚠️ Potential issueFlatten the payload when invoking the Apple plugin
Wrapping the arguments in a
payloadobject prevents the plugin from seeing them, as the Tauri invoke API spreads the second argument directly into the Rust command.
This was pointed out in a previous review but is still present.- const result = await invoke<AppleCredential>( - "plugin:sign-in-with-apple|get_apple_id_credential", - { - payload: { - scope: ["email", "fullName"], - state: "apple-signup-state", - options: { debug: true } - } - } - ); +const result = await invoke<AppleCredential>( + "plugin:sign-in-with-apple|get_apple_id_credential", + { + scope: ["email", "fullName"], + state: "apple-signup-state", + options: { debug: true } + } +);
🧹 Nitpick comments (1)
frontend/src/routes/signup.tsx (1)
87-155: Consider extracting a helper to build & opendesktopAuthUrlThe GitHub, Google, and Apple branches duplicate the same logic for:
- Building the URL with an optional
selected_plan- Invoking the opener plugin with identical error handling
A small utility (e.g.,
openDesktopAuth(provider: string)) would reduce repetition and the chance of inconsistent behaviour.Also applies to: 227-242
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
frontend/bun.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
frontend/package.json(1 hunks)frontend/src-tauri/apple-sign-in-info.md(1 hunks)frontend/src/components/Marketing.tsx(1 hunks)frontend/src/components/icons/Apple.tsx(1 hunks)frontend/src/routes/auth.$provider.callback.tsx(4 hunks)frontend/src/routes/desktop-auth.tsx(2 hunks)frontend/src/routes/login.tsx(5 hunks)frontend/src/routes/pricing.tsx(1 hunks)frontend/src/routes/signup.tsx(5 hunks)frontend/src/types/apple-sign-in.d.ts(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- frontend/package.json
- frontend/src/types/apple-sign-in.d.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- frontend/src/components/icons/Apple.tsx
- frontend/src/routes/desktop-auth.tsx
- frontend/src/routes/login.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (11)
frontend/src/components/Marketing.tsx (1)
203-212: Improved platform detection for safer cross-environment operationThe added Tauri environment check ensures that platform-specific APIs are only called in appropriate contexts. This is a good defensive programming practice that will prevent potential runtime errors when the app runs in a web browser.
frontend/src/routes/pricing.tsx (1)
155-164: Consistent platform detection implementation across componentsThis change follows the same pattern as in Marketing.tsx, creating a consistent approach to platform detection throughout the application. The Tauri environment check prevents potential runtime errors when accessing platform-specific APIs in non-Tauri environments.
frontend/src/routes/auth.$provider.callback.tsx (8)
20-21: Added Apple provider formattingGood addition to the provider formatting function to support the new Apple Sign In integration.
31-31: Updated hook destructuring to include Apple callback handlerProperly updated to include the Apple-specific callback handler from the OpenSecret hook.
35-84: Improved code organization with extracted helper functionsExcellent refactoring to extract the shared authentication success and error handling logic into separate helper functions. This reduces code duplication and improves maintainability.
99-115: Added Apple-specific user data handlingGood implementation of Apple-specific user data parsing from URL parameters. The code includes proper error handling and logging, with clear comments explaining that Apple only sends user data on first sign-in.
120-129: Refactored provider-specific callback processingThe refactored code now clearly handles each provider with specific callback handlers while maintaining a consistent structure. The addition of explicit error handling for unsupported providers is a good defensive programming practice.
132-133: Using the extracted helper function for successful authReplacing inline code with the extracted helper function improves readability and maintainability.
136-136: Using the extracted helper function for error handlingReplacing inline code with the extracted helper function improves readability and maintainability.
147-147: Updated dependency arrayCorrectly updated the effect dependency array to include the new
handleAppleCallbackdependency, ensuring the effect reruns if this callback changes.frontend/src/routes/signup.tsx (1)
162-168:plugin-osmay not return the literal string"ios"– verify the value
await type()(orgetPlatformType()after aliasing) typically returns platform triples such asaarch64-apple-ios,x86_64-apple-darwin,windows, etc.
A strict equality check against"ios"risks a false‑negative, forcing iOS devices down the desktop/web branch.Recommend a substring check instead:
- isIOSDevice = platform === "ios"; + isIOSDevice = /ios/i.test(platform);Please confirm the exact values returned by the plugin for your targets.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
frontend/src/routes/signup.tsx (4)
13-13: Fix import alias to avoid type conflictsThe
typeimport from@tauri-apps/plugin-osshould be aliased to avoid conflicts with the TypeScripttypekeyword.-import { type } from "@tauri-apps/plugin-os"; +import { type as getPlatformType } from "@tauri-apps/plugin-os";Also remember to update line 55 to use the renamed function:
- const platform = await type(); + const platform = await getPlatformType();
199-212: Flatten the payload for Apple Sign-In invocationThe Tauri
invokeAPI spreads its second-argument object directly into the native command. Wrapping parameters in apayloadkey will prevent the plugin from accessing them.const result = await invoke<AppleCredential>( "plugin:sign-in-with-apple|get_apple_id_credential", { - payload: { - scope: ["email", "fullName"], - state, - nonce, - // Disable debug mode in production - options: { - debug: false - } - } + scope: ["email", "fullName"], + state, + nonce, + // Disable debug mode in production + options: { + debug: false + } } );
187-257: Add loading state management to prevent multiple sign-in requestsThe Apple sign-in handler should manage the loading state to prevent multiple concurrent requests if the user clicks rapidly.
const handleAppleSignup = async () => { + if (isLoading) return; + setIsLoading(true); try { // Existing code... } catch (error) { console.error("Failed to initiate Apple signup:", error); setError("Failed to initiate Apple signup. Please try again."); + } finally { + setIsLoading(false); } };
275-280: Add disabled state to the Apple buttonThe Apple button should respect the
isLoadingstate to prevent multiple clicks during authentication.{isIOS && ( - <Button onClick={handleAppleSignup} className="w-full"> + <Button onClick={handleAppleSignup} className="w-full" disabled={isLoading}> <Apple className="mr-2 h-4 w-4" /> Sign up with Apple </Button> )}
🧹 Nitpick comments (1)
frontend/src/routes/signup.tsx (1)
262-262: Consider different title for sign-up method errorsYou're using "Note" as the title for errors during sign-up method selection, but "Error" for form submission errors. Consider using consistent terminology.
-{error && <AlertDestructive title="Note" description={error} />} +{error && <AlertDestructive title="Error" description={error} />}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
frontend/bun.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
.gitignore(1 hunks)frontend/package.json(3 hunks)frontend/src-tauri/Cargo.toml(1 hunks)frontend/src-tauri/src/lib.rs(2 hunks)frontend/src/routes/login.tsx(5 hunks)frontend/src/routes/signup.tsx(5 hunks)
✅ Files skipped from review due to trivial changes (1)
- .gitignore
🚧 Files skipped from review as they are similar to previous changes (4)
- frontend/src-tauri/Cargo.toml
- frontend/package.json
- frontend/src-tauri/src/lib.rs
- frontend/src/routes/login.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
frontend/src/routes/signup.tsx (3)
frontend/src/components/AuthMain.tsx (1)
AuthMain(11-44)frontend/src/components/AlertDestructive.tsx (1)
AlertDestructive(5-15)frontend/src/components/icons/Apple.tsx (1)
Apple(3-16)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: build-ios
- GitHub Check: build-macos (universal-apple-darwin)
- GitHub Check: build-linux
- GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
frontend/src/routes/signup.tsx (2)
38-68: LGTM: Platform detection is well implementedThe platform detection logic is thorough and properly structured:
- First checks if running in a Tauri environment
- Only if in Tauri, checks the platform type
- Includes appropriate error handling
- Properly initializes the state to false by default
This ensures the Apple sign-in button only appears on iOS devices running the Tauri app.
10-14: LGTM: New imports support Apple Sign-In functionalityThe added imports support the new Apple Sign-In functionality:
- Apple icon component for the button
- OS type detection for platform-specific rendering
- UUID generation for secure state and nonce values
These are all necessary for implementing the Apple authentication flow.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (4)
frontend/src/routes/signup.tsx (4)
276-281: 🛠️ Refactor suggestionAdd disabled state to Apple Sign-In button
The Apple Sign-In button should be disabled when
isLoadingis true to prevent multiple concurrent sign-in attempts, consistent with the email sign-up button.{isIOS && ( - <Button onClick={handleAppleSignup} className="w-full"> + <Button onClick={handleAppleSignup} className="w-full" disabled={isLoading}> <Apple className="mr-2 h-4 w-4" /> Sign up with Apple </Button> )}
200-213:⚠️ Potential issueFlatten the payload for Apple Sign-In invocation
The Tauri
invokeAPI spreads its second-argument object directly into the native command. Wrapping parameters in apayloadkey will prevent the plugin from receiving them correctly.Apply this diff to fix the payload structure:
const result = await invoke<AppleCredential>( "plugin:sign-in-with-apple|get_apple_id_credential", { - payload: { scope: ["email", "fullName"], state, nonce, // Disable debug mode in production options: { debug: false } - } } );
13-13:⚠️ Potential issueFix the TypeScript naming clash with Tauri import
The
typeimport from@tauri-apps/plugin-osconflicts with the TypeScripttypekeyword, which could cause confusion and potential issues.Apply this diff to fix the import name clash:
-import { type } from "@tauri-apps/plugin-os"; +import { type as getPlatformType } from "@tauri-apps/plugin-os";Then update the function call at line 56:
- const platform = await type(); + const platform = await getPlatformType();
188-258: 🛠️ Refactor suggestionAdd loading state handling to Apple Sign-Up flow
Unlike the email sign-up flow, the Apple handler does not set or check the
isLoadingstate, which could lead to multiple concurrent sign-in dialogs if a user taps the button repeatedly.Apply this diff to add loading state management:
const handleAppleSignup = async () => { + if (isLoading) return; + setIsLoading(true); try { // Only iOS supports native Apple Sign In console.log("[OAuth] Initiating native Sign in with Apple for iOS"); try { // Generate random UUIDs for state and nonce const state = uuidv4(); const nonce = uuidv4(); // Invoke the Apple Sign in plugin // This will show the native Apple authentication UI const result = await invoke<AppleCredential>( "plugin:sign-in-with-apple|get_apple_id_credential", { payload: { scope: ["email", "fullName"], state, nonce, // Disable debug mode in production options: { debug: false } } } ); console.log("[OAuth] Apple Sign-In result:", result); // Format the response for the API const appleUser = { user_identifier: result.user, identity_token: result.identityToken, email: result.email, given_name: result.fullName?.givenName, family_name: result.fullName?.familyName }; // Send to backend via SDK try { await os.handleAppleNativeSignIn(appleUser, ""); // Redirect after successful signup if (selected_plan) { navigate({ to: "/pricing", search: { selected_plan } }); } else { navigate({ to: next || "/" }); } } catch (backendError) { console.error("[OAuth] Backend processing failed:", backendError); setError( backendError instanceof Error ? backendError.message : "Failed to process Apple authentication" ); } } catch (error) { console.error("[OAuth] Failed to authenticate with Apple:", error); const errorMessage = error instanceof Error ? `Apple Sign In error: ${error.message}` : "Failed to authenticate with Apple. Please try again."; setError(errorMessage); } } catch (error) { console.error("Failed to initiate Apple signup:", error); setError("Failed to initiate Apple signup. Please try again."); } + finally { + setIsLoading(false); + } };
🧹 Nitpick comments (2)
frontend/src/routes/signup.tsx (2)
263-263: Consider consistent error alert titlesThe error alert here uses "Note" as the title, while the one at line 295 uses "Error". Consider using consistent terminology for similar components.
-{error && <AlertDestructive title="Note" description={error} />} +{error && <AlertDestructive title="Error" description={error} />}
208-210: Consider environment-based debug settingYou're hardcoding
debug: falsebut have a comment about disabling it in production. Consider making this value conditional based on the environment for better development experience.// Disable debug mode in production options: { - debug: false + debug: process.env.NODE_ENV !== 'production' }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
frontend/bun.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
.gitignore(1 hunks)frontend/package.json(3 hunks)frontend/src-tauri/Cargo.toml(1 hunks)frontend/src-tauri/src/lib.rs(2 hunks)frontend/src/routes/login.tsx(5 hunks)frontend/src/routes/signup.tsx(5 hunks)frontend/src/types/apple-sign-in.d.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- frontend/src/types/apple-sign-in.d.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- .gitignore
- frontend/src-tauri/Cargo.toml
- frontend/package.json
- frontend/src-tauri/src/lib.rs
- frontend/src/routes/login.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
frontend/src/routes/signup.tsx (3)
frontend/src/types/apple-sign-in.d.ts (1)
AppleCredential(4-13)frontend/src/components/AlertDestructive.tsx (1)
AlertDestructive(5-15)frontend/src/components/icons/Apple.tsx (1)
Apple(3-16)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: build-ios
- GitHub Check: build-macos (universal-apple-darwin)
- GitHub Check: build-linux
- GitHub Check: Cloudflare Pages
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
frontend/src/routes/signup.tsx (3)
13-13:⚠️ Potential issueIncorrect import statement for the OS plugin type
The import is using
typewhich clashes with TypeScript's keyword. This will cause confusion and potential errors in your code.Apply this fix:
-import { type } from "@tauri-apps/plugin-os"; +import { type as getPlatformType } from "@tauri-apps/plugin-os";And update line 58 to use the aliased import:
- const platform = await type(); + const platform = await getPlatformType();
207-220:⚠️ Potential issueFix nested payload structure in Apple Sign-In invocation
The Tauri
invokeAPI expects parameters at the top level. Wrapping them in apayloadobject will prevent the plugin from accessing them correctly.Apply this diff:
const result = await invoke<AppleCredential>( "plugin:sign-in-with-apple|get_apple_id_credential", { - payload: { - scope: ["email", "fullName"], - state, - nonce: hashedNonce, // Send the hashed nonce to Apple - // Disable debug mode in production - options: { - debug: false - } - } + scope: ["email", "fullName"], + state, + nonce: hashedNonce, // Send the hashed nonce to Apple + // Disable debug mode in production + options: { + debug: false + } } );
190-266: 🛠️ Refactor suggestionAdd loading state management to Apple sign-up flow
Unlike the email sign-up path, the Apple handler doesn't manage the loading state. This could lead to multiple concurrent sign-in attempts if a user taps repeatedly.
Apply this diff:
const handleAppleSignup = async () => { + if (isLoading) return; + setIsLoading(true); try { // Only iOS supports native Apple Sign In console.log("[OAuth] Initiating native Sign in with Apple for iOS"); try { // ...implementation... } catch (error) { // ...error handling... } } catch (error) { console.error("Failed to initiate Apple signup:", error); setError("Failed to initiate Apple signup. Please try again."); + } finally { + setIsLoading(false); } };Also update the Apple button to be disabled when loading:
- {isIOS && ( - <Button onClick={handleAppleSignup} className="w-full"> + {isIOS && ( + <Button onClick={handleAppleSignup} className="w-full" disabled={isLoading}> <Apple className="mr-2 h-4 w-4" /> Sign up with Apple </Button> )}
🧹 Nitpick comments (3)
frontend/src/routes/signup.tsx (3)
195-232: Consider storing the nonce in component stateThe
rawNonceis generated inside the function and later used for backend authentication. If the component re-renders between these operations, the nonce value could be lost.Consider moving this to component state:
function SignupPage() { // ...existing state... + const [appleNonce, setAppleNonce] = useState<string | null>(null); const handleAppleSignup = async () => { try { // ... // Generate random UUIDs for state and nonce const state = uuidv4(); const rawNonce = uuidv4(); + setAppleNonce(rawNonce); // ...rest of implementation... // Format the response for the API const appleUser = { // ... - nonce: rawNonce // Pass the original raw nonce to backend + nonce: appleNonce // Pass the stored nonce to backend };
254-261: Simplify error handling structureThe nested try-catch blocks make the code harder to follow. Consider streamlining the error handling.
You could simplify the error handling structure:
const handleAppleSignup = async () => { + if (isLoading) return; + setIsLoading(true); try { // Only iOS supports native Apple Sign In console.log("[OAuth] Initiating native Sign in with Apple for iOS"); - try { - // Implementation... - } catch (error) { - console.error("[OAuth] Failed to authenticate with Apple:", error); - const errorMessage = - error instanceof Error - ? `Apple Sign In error: ${error.message}` - : "Failed to authenticate with Apple. Please try again."; - setError(errorMessage); - } + // Implementation without nested try/catch... + } catch (error) { console.error("Failed to initiate Apple signup:", error); - setError("Failed to initiate Apple signup. Please try again."); + setError( + error instanceof Error + ? `Apple Sign In error: ${error.message}` + : "Failed to authenticate with Apple. Please try again." + ); + } finally { + setIsLoading(false); } };
216-216: Ensure debug mode is disabled for productionThe debug option is set to false, which is correct for production. However, consider making this a configurable value based on environment.
Consider using an environment variable:
options: { - debug: false + debug: import.meta.env.DEV // Automatically true in development, false in production }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
frontend/bun.lockis excluded by!**/*.lock
📒 Files selected for processing (3)
frontend/package.json(3 hunks)frontend/src/routes/login.tsx(5 hunks)frontend/src/routes/signup.tsx(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- frontend/package.json
- frontend/src/routes/login.tsx
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: build-macos (universal-apple-darwin)
- GitHub Check: build-ios
- GitHub Check: build-linux
- GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
frontend/src/routes/signup.tsx (3)
43-71: Good platform detection implementationThe platform detection logic correctly:
- Checks if running in Tauri environment before trying to use platform APIs
- Handles potential errors during platform detection
- Sets iOS state only when needed
271-271: Good improvement to error displayShowing the error alert at the top of the sign-up method selection improves user experience by making error messages more visible.
284-289: Good conditional rendering of Apple sign-upThe Apple sign-up button is correctly shown only on iOS devices, which is appropriate since Apple Sign In is only supported natively on iOS.
However, update the button to be disabled during loading operations:
-<Button onClick={handleAppleSignup} className="w-full"> +<Button onClick={handleAppleSignup} className="w-full" disabled={isLoading}>
Summary by CodeRabbit
New Features
Documentation
Chores
Refactor
Style
Types