Skip to content

feat: update app to beta version with tracking authorization and impr…#552

Merged
felix-schultz merged 1 commit intoalphafrom
dev
Apr 3, 2026
Merged

feat: update app to beta version with tracking authorization and impr…#552
felix-schultz merged 1 commit intoalphafrom
dev

Conversation

@felix-schultz
Copy link
Copy Markdown
Member

…oved release notes

@felix-schultz felix-schultz merged commit 64120e8 into alpha Apr 3, 2026
13 of 16 checks passed
@codacy-production
Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

TIP This summary will be updated as you push new changes. Give us feedback

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements App Tracking Transparency (ATT) for the iOS desktop app, adding a Tauri command to retrieve authorization status and integrating it with PostHog for privacy-compliant tracking. It also updates the app version to 0.1.1, includes necessary iOS entitlements for Wasmtime, and refreshes the release information in the swimlanes configuration. Key feedback includes ensuring the tracking check fails closed for better privacy compliance, addressing a race condition where PostHog might start capturing before the authorization check completes, and using idiomatic Rust types when interfacing with Objective-C.

const status = await invoke<string>("get_tracking_authorization_status");
return status === "authorized";
} catch {
return true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The isTrackingAuthorized function currently defaults to true if the tracking status check fails. For better privacy compliance (e.g., GDPR, App Store guidelines), it is recommended to "fail-closed" and return false if the authorization status cannot be determined or if the IPC call fails.

Suggested change
return true;
return false;

Comment on lines +39 to +45
isTrackingAuthorized().then((authorized) => {
if (!authorized) {
posthog.opt_out_capturing();
} else {
posthog.opt_in_capturing();
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This implementation has two potential issues:

  1. Race Condition: posthog.init (called earlier in the effect) starts capturing immediately by default. Since isTrackingAuthorized() is asynchronous, some events might be sent before posthog.opt_out_capturing() is invoked. It is safer to initialize PostHog with opt_out_capturing_by_default: true and then explicitly call opt_in_capturing() here if authorized.
  2. Session Updates: This check only runs once when the provider mounts. If the user grants permission via the system prompt after the app has started, PostHog will remain opted-out for the rest of the session. Consider re-checking the status when the window gains focus or using a listener to react to authorization changes.

) -> Result<String, TauriFunctionError> {
#[cfg(target_os = "ios")]
{
let status: u32 = unsafe {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The trackingAuthorizationStatus method on ATTrackingManager returns an NSUInteger, which corresponds to usize in Rust (64-bit on iOS). While the current enum values (0-3) fit in a u32, using usize is more idiomatic and type-safe when interfacing with Objective-C via objc2.

Suggested change
let status: u32 = unsafe {
let status: usize = unsafe {

Comment on lines 36 to +44
enable_heatmaps: true,
});

isTrackingAuthorized().then((authorized) => {
if (!authorized) {
posthog.opt_out_capturing();
} else {
posthog.opt_in_capturing();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: A race condition allows PostHog to capture events before the asynchronous tracking authorization check completes, violating user privacy settings on iOS.
Severity: CRITICAL

Suggested Fix

Ensure tracking authorization is confirmed before initializing PostHog. Move the posthog.init() call to execute only after the isTrackingAuthorized() promise successfully resolves with a status that permits tracking.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: apps/desktop/app/provider.tsx#L36-L44

Potential issue: In the `PHProvider` component, PostHog is initialized synchronously
with `posthog.init()`, which can start capturing events immediately. However, the user's
tracking authorization is checked asynchronously via `isTrackingAuthorized()`. This
creates a race condition where events may be captured and sent before the authorization
check completes. For iOS users who have denied tracking, this violates App Tracking
Transparency (ATT) because their data is sent before `opt_out_capturing()` is called.
Furthermore, if the `invoke("get_tracking_authorization_status")` call fails,
authorization defaults to `true`, enabling tracking incorrectly.

Did we get this right? 👍 / 👎 to inform future reviews.

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