Skip to content

Apple Auth start#58

Merged
AnthonyRonning merged 6 commits intomasterfrom
ios-auth
May 2, 2025
Merged

Apple Auth start#58
AnthonyRonning merged 6 commits intomasterfrom
ios-auth

Conversation

@AnthonyRonning
Copy link
Contributor

@AnthonyRonning AnthonyRonning commented Apr 21, 2025

Summary by CodeRabbit

  • New Features

    • Added native Apple Sign In support for iOS users in the login and signup flows.
    • Introduced an Apple Sign In button, conditionally shown on iOS devices.
    • Included a new Apple icon for use in the UI.
  • Documentation

    • Added a comprehensive guide for integrating and configuring Sign in with Apple, covering both native iOS and web OAuth flows.
  • Chores

    • Updated dependencies and permissions to support Apple Sign In integration.
    • Added new configuration files for iOS capabilities and permissions.
    • Improved platform detection logic for iOS across multiple components.
  • Refactor

    • Modularized authentication callback handling for better maintainability.
  • Style

    • Enhanced error alert placement on login and signup screens for improved user feedback.
  • Types

    • Introduced TypeScript definitions for Apple Sign In credentials.

@coderabbitai
Copy link

coderabbitai bot commented Apr 21, 2025

Walkthrough

This 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

File(s) Change Summary
frontend/src-tauri/Cargo.toml Added tauri-plugin-sign-in-with-apple dependency.
frontend/src-tauri/apple-sign-in-info.md New documentation detailing Apple Sign In integration for iOS and web, including setup, flows, and troubleshooting.
frontend/src-tauri/capabilities/default.json Appended "sign-in-with-apple:default" permission to default permissions array.
frontend/src-tauri/capabilities/mobile-ios.json New iOS-specific capability file defining permissions for Sign In with Apple and allowed URLs.
frontend/src-tauri/src/lib.rs Conditionally initialized the tauri_plugin_sign_in_with_apple plugin for iOS non-desktop targets in the Tauri app builder.
frontend/src/components/icons/Apple.tsx New React component rendering an Apple SVG icon, exported for use in UI.
frontend/src/routes/login.tsx Added native Apple Sign In for iOS in Tauri; updated logic, state, and UI to support Apple login method.
frontend/src/routes/signup.tsx Added Apple as a sign-up method for iOS in Tauri; updated logic, state, and UI accordingly.
frontend/package.json Upgraded @opensecret/react dependency from 1.2.0 to 1.3.1; added uuid and @types/uuid dependencies.
frontend/src/components/Marketing.tsx
frontend/src/routes/pricing.tsx
Updated platform detection logic to check for Tauri environment before determining iOS platform.
frontend/src/routes/auth.$provider.callback.tsx Refactored OAuth callback handler to modularize success and error handling, and added explicit provider checks.
frontend/src/types/apple-sign-in.d.ts Added TypeScript interface AppleCredential for Apple Sign In plugin response.
.gitignore Added ignore pattern for .claude/settings.local.json.

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
Loading

Possibly related PRs

  • Upgrade to opensecret 1.2.0 #46: Upgraded @opensecret/react dependency from version 1.2.0 to 1.3.1 and added uuid package, related to dependency management in the frontend.

Poem

🍏
A rabbit hopped in with a shiny new treat,
Apple Sign In for iOS—how neat!
With plugins and icons and platform checks too,
Now logging in is easy for you.
Docs and types keep things tight,
While OAuth flows are handled right.
Maple just got sweeter—enjoy every byte!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-apple v1.0.0 in /frontend/src-tauri/Cargo.toml with corresponding capabilities in default.json and mobile-ios.json
  • Created comprehensive documentation at /frontend/src-tauri/apple-sign-in-info.md detailing 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.entitlements for proper Apple Sign In permissions
  • Updated /frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj to use manual code signing with specific provisioning profile

11 file(s) reviewed, 4 comment(s)
Edit PR Review Bot Settings | Greptile

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 under http://localhost:5173/* and https://trymaple.ai/*.

• For production builds consider removing the http origin entirely and/or scoping the https origin to just the OAuth callback path.
• If development needs http://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() (previously type()) throws when the plugin is missing – e.g., when the page is rendered in a plain browser during local dev. Consider short‑circuiting when await isTauri() returns false to avoid needless exception spam.

frontend/src/routes/signup.tsx (1)

39-53: Consider skipping platform detection when not in Tauri

Same 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

📥 Commits

Reviewing files that changed from the base of the PR and between ac8fa4b and ba1e2e2.

⛔ Files ignored due to path filters (3)
  • frontend/src-tauri/Cargo.lock is excluded by !**/*.lock
  • frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj is excluded by !**/gen/**
  • frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlements is 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-apple dependency 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:


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 currentColor and 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:

  1. Will desktop users also be able to use Apple Sign In?
  2. 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

  1. The $schema value ("../gen/schemas/mobile-schema.json") must point to a real file, otherwise IDE validation will break silently.
  2. 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 declared

Declaring "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-apple docs the command accepts the payload directly, not nested under payload. 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 invoke Payload for tauri-plugin-sign-in-with-apple's get_apple_id_credential

The direct shape of the payload for invoking get_apple_id_credential in the tauri-plugin-sign-in-with-apple is 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 email, 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_credential handler 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 scopes as an array.
  • If in doubt, inspect the plugin’s Rust/TypeScript definitions or check runtime errors for payload hints.

1 2 5 8


References:

Citations:


Verify payload structure for Sign In with Apple plugin

I didn’t find any official docs showing a nested payload object—Tauri plugins expect the invoke parameters at the top level. Please check the plugin’s handler signature in your local node_modules (or the Rust crate) to confirm.

  • File: frontend/src/routes/login.tsx – handleAppleLogin invocation

Suggested 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.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Apr 21, 2025

Deploying maple with  Cloudflare Pages  Cloudflare Pages

Latest commit: d9ecdde
Status: ✅  Deploy successful!
Preview URL: https://02e2016e.maple-ca8.pages.dev
Branch Preview URL: https://ios-auth.maple-ca8.pages.dev

View logs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
frontend/src-tauri/apple-sign-in-info.md (5)

6-10: Include Cargo.toml snippet for plugin setup

Consider adding a code snippet showing how to add the tauri-plugin-sign-in-with-apple dependency in frontend/src-tauri/Cargo.toml for easier onboarding:

[dependencies]
tauri-plugin-sign-in-with-apple = "1.0.0"

11-15: Link to frontend component implementations

For better navigation, hyperlink or reference the paths to routes/login.tsx, routes/signup.tsx, and components/icons/Apple.tsx where the Apple Sign In logic is implemented.


16-23: Anchor future backend work to an issue tracker

To 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 refinement

Rephrase “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 link

Optionally add the Tauri plugin’s GitHub repository for direct reference:

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba1e2e2 and 8d7aded.

⛔ Files ignored due to path filters (2)
  • frontend/src-tauri/Cargo.lock is excluded by !**/*.lock
  • frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlements is 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 title

The heading succinctly conveys the integration purpose and platform context.


3-5: Overview is concise and focused

This section effectively introduces the iOS-specific Apple Sign In integration. No changes needed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
frontend/src-tauri/apple-sign-in-info.md (1)

1-102: Remove this documentation file as previously requested

While 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 issue

Alias the type import to avoid the reserved‑word collision

The type identifier collides with the TypeScript keyword type, 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 issue

Flatten the payload when invoking the Apple plugin

Wrapping the arguments in a payload object 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 & open desktopAuthUrl

The GitHub, Google, and Apple branches duplicate the same logic for:

  1. Building the URL with an optional selected_plan
  2. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7aded and 8f24af3.

⛔ Files ignored due to path filters (1)
  • frontend/bun.lock is 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 operation

The 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 components

This 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 formatting

Good addition to the provider formatting function to support the new Apple Sign In integration.


31-31: Updated hook destructuring to include Apple callback handler

Properly updated to include the Apple-specific callback handler from the OpenSecret hook.


35-84: Improved code organization with extracted helper functions

Excellent 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 handling

Good 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 processing

The 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 auth

Replacing inline code with the extracted helper function improves readability and maintainability.


136-136: Using the extracted helper function for error handling

Replacing inline code with the extracted helper function improves readability and maintainability.


147-147: Updated dependency array

Correctly updated the effect dependency array to include the new handleAppleCallback dependency, ensuring the effect reruns if this callback changes.

frontend/src/routes/signup.tsx (1)

162-168: plugin-os may not return the literal string "ios" – verify the value

await type() (or getPlatformType() after aliasing) typically returns platform triples such as aarch64-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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
frontend/src/routes/signup.tsx (4)

13-13: Fix import alias to avoid type conflicts

The type import from @tauri-apps/plugin-os should be aliased to avoid conflicts with the TypeScript type keyword.

-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 invocation

The Tauri invoke API spreads its second-argument object directly into the native command. Wrapping parameters in a payload key 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 requests

The 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 button

The Apple button should respect the isLoading state 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 errors

You'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

📥 Commits

Reviewing files that changed from the base of the PR and between d8f3cef and 64ed5cc.

⛔ Files ignored due to path filters (1)
  • frontend/bun.lock is 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 implemented

The platform detection logic is thorough and properly structured:

  1. First checks if running in a Tauri environment
  2. Only if in Tauri, checks the platform type
  3. Includes appropriate error handling
  4. 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 functionality

The 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
frontend/src/routes/signup.tsx (4)

276-281: 🛠️ Refactor suggestion

Add disabled state to Apple Sign-In button

The Apple Sign-In button should be disabled when isLoading is 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 issue

Flatten the payload for Apple Sign-In invocation

The Tauri invoke API spreads its second-argument object directly into the native command. Wrapping parameters in a payload key 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 issue

Fix the TypeScript naming clash with Tauri import

The type import from @tauri-apps/plugin-os conflicts with the TypeScript type keyword, 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 suggestion

Add loading state handling to Apple Sign-Up flow

Unlike the email sign-up flow, the Apple handler does not set or check the isLoading state, 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 titles

The 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 setting

You're hardcoding debug: false but 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

📥 Commits

Reviewing files that changed from the base of the PR and between 5c6a8a5 and a77b832.

⛔ Files ignored due to path filters (1)
  • frontend/bun.lock is 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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
frontend/src/routes/signup.tsx (3)

13-13: ⚠️ Potential issue

Incorrect import statement for the OS plugin type

The import is using type which 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 issue

Fix nested payload structure in Apple Sign-In invocation

The Tauri invoke API expects parameters at the top level. Wrapping them in a payload object 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 suggestion

Add 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 state

The rawNonce is 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 structure

The 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 production

The 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

📥 Commits

Reviewing files that changed from the base of the PR and between dda8f2e and d9ecdde.

⛔ Files ignored due to path filters (1)
  • frontend/bun.lock is 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 implementation

The 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 display

Showing 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-up

The 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}>

@AnthonyRonning AnthonyRonning merged commit 2255080 into master May 2, 2025
5 checks passed
@AnthonyRonning AnthonyRonning deleted the ios-auth branch May 2, 2025 19:51
@coderabbitai coderabbitai bot mentioned this pull request May 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant