Skip to content

Add Find My Friends support for newer macOS - #824

Open
qayshp wants to merge 5 commits into
BlueBubblesApp:developmentfrom
qayshp:codex/findmy-friends-upstream
Open

Add Find My Friends support for newer macOS#824
qayshp wants to merge 5 commits into
BlueBubblesApp:developmentfrom
qayshp:codex/findmy-friends-upstream

Conversation

@qayshp

@qayshp qayshp commented Jul 15, 2026

Copy link
Copy Markdown

Summary

  • add a dedicated Find My private-API client for Friends on macOS 15 and later
  • preserve the existing Friends behavior on older supported macOS releases
  • route targeted requests only to the helper for the correct host process
  • normalize helper responses into the existing Friends API and socket-event shape
  • retain complete helper snapshots while protecting newer cached locations
  • embed and verify a universal Intel/Apple Silicon helper artifact

This branch is based directly on the current upstream development branch, as required by CONTRIBUTING.md.

Platform behavior

  • macOS 11 through 13: use the existing Messages helper
  • macOS 14: retain the existing Find My app refresh fallback
  • macOS 15 and later: use the dedicated com.apple.findmy helper

The dedicated helper starts when Private API and Open FindMy App on Startup are enabled. Automation requests occur when the Find My feature is used.

Reliability and payload handling

  • targeted private-API requests cannot leak to a different connected helper
  • complete snapshots remove stale handles; partial snapshots only update returned handles
  • malformed nonempty snapshots cannot erase the cache
  • newer cached coordinates are not replaced by older helper data
  • payloads are rebuilt from an explicit public-field allowlist
  • null locations remain null instead of becoming (0, 0)
  • newline-delimited socket input handles fragmented, coalesced, split-UTF-8, and oversized messages
  • disabled dylib plugins do not terminate unmanaged applications during shutdown
  • the committed helper checksum, architectures, and install name are checked before each server build

Validation

  • npm run test:findmy passes, including platform routing, cache replacement, fallback, normalization, framing, and process-selection coverage
  • TypeScript, Prettier, and ESLint for every changed TypeScript file pass
  • the helper artifact verification and production webpack compilation pass under Node 20/npm 10
  • unsigned Intel and Apple Silicon packages build successfully with Xcode
  • Find My loaded the packaged helper with SHA-256 99e5e9596c0c095f08f5083353053d77fbf458e54727f8160dabe3873c4fa39a
  • authenticated GET/refresh/GET calls against the development-based package all returned HTTP 200 with 8 Friends records and no private/debug fields
  • location availability followed Find My runtime state: an earlier run returned 5 coordinate-bearing and 3 null-location records; the final fresh-process check returned the same 8 friends with null current locations
  • repository-wide lint still reports pre-existing failures in unrelated upstream files; all files changed by this PR pass lint

The current upstream development production bundle minifies its newest TypeORM migration class to t, which prevents a normally minimized package from completing startup. The live API smoke test therefore used the same package with webpack minimization disabled. This PR does not modify the migration or webpack configuration.

A signed release should repeat the Automation smoke test in appResources/private-api/README.md, because this development machine has no signing identity and TCC grants are tied to application identity.

Companion helper PR: BlueBubblesApp/bluebubbles-helper#65

@qayshp qayshp left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Maintainer review: the overall direction is plausible, but I would not merge this yet. The packaged binary architecture, feature opt-in, startup permission behavior, and async error handling need to be fixed first. Please also add focused tests for the route/cache/private-API fallback behavior and document the supported macOS versions and CPU architectures. Because this server change depends on BlueBubblesApp/bluebubbles-helper#65, the artifact/release contract between the two PRs should be explicit and reproducible.

Comment thread packages/server/src/server/api/privateApi/modes/dylibPlugins/FindMyDylibPlugin.ts Outdated
Comment thread packages/server/src/server/api/privateApi/modes/dylibPlugins/FindMyDylibPlugin.ts Outdated
Comment thread packages/server/src/server/api/privateApi/modes/dylibPlugins/FindMyDylibPlugin.ts Outdated
Comment thread packages/server/src/server/index.ts Outdated

@qayshp qayshp left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Second maintainer-style pass on 6604e511: I do not see a remaining blocking finding in the updated diff.

The earlier blockers are addressed: the embedded helper is universal and checked before builds; Find My injection is gated by Private API, the startup setting, and macOS 15+; helper requests are routed only to com.apple.findmy; injection failures are observed; stop/restart now waits for the injection loop; helper responses are normalized without inventing (0, 0); and TCP input now buffers fragmented/coalesced JSON lines while preserving UTF-8 characters split across packets.

Validation on the exact packaged PR build passed: GET Friends, POST refresh, and GET Friends all returned HTTP 200 with 8 records; 5 had coordinate pairs and 3 had no current location. The Find My process loaded the dylib from the packaged checkout, and the refresh logs had no timeout, partial-response, framing, parse, or transaction errors.

Non-blocking test gaps remain around PrivateApiService process-target selection and FindMyInterface.refreshFriends behavior for no client, empty partial responses, and fallback failures. The focused normalization/framing tests plus the live run cover the main path, but those branches should gain isolated tests when this project has a suitable service-level harness.

Local packaging caveat: the unsigned test app did not inherit a System Events Automation grant, so hiding Find My/Messages logged TCC warnings. That did not affect helper registration or the Friends API. A signed release-candidate smoke test should confirm the intended Automation prompt and hide behavior.

@qayshp qayshp left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Final maintainer pass on a6f7d864: the remaining service-level gaps from my previous review are now covered.

The tests exercise exact private-API process selection, unknown and destroyed targets, broadcast behavior, no-helper fallback, empty partial responses, usable partial responses, complete empty responses, and both helper and fallback failures. An empty partial helper response now preserves the existing cache while starting the app fallback.

I reran the focused tests, TypeScript, ESLint, Prettier, helper verification, and the production build. I also restarted Find My under the packaged app; the replacement process loaded the packaged dylib, registered as com.apple.findmy, and the Android-facing refresh returned HTTP 200 with 8 records, 5 with coordinates and 3 without.

I do not see another code change needed before merge. The remaining release check is the signed-package Automation smoke test now documented in the private-API README. I could not execute that identity-specific check because this machine has no code-signing identity; the unsigned package still passed the helper and API path.

@qayshp qayshp left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Final maintainer-style pass after synchronizing with upstream/master:

I found one merge-blocking regression in the previous revision: it replaced the existing Friends path on older supported macOS releases instead of adding the macOS 15 path alongside it. Commit 434f382 fixes that with one platform policy: macOS 11-13 use the Messages helper, macOS 14 retains the app fallback, and macOS 15+ targets Find My.

I also tightened the response boundary to an explicit allowlist, made complete snapshots remove stale handles without overwriting newer cached locations, and protected the cache from malformed snapshots. The expanded tests cover those cases and the platform matrix.

The branch is current with upstream/master, the changed files pass TypeScript/ESLint/Prettier checks, the production build succeeds, and the exact packaged app returned HTTP 200 for GET/refresh/GET with all 8 Friends records. The latest runtime had no current coordinates, while an earlier run of the same artifact returned 5; this matches transient Find My data rather than an API failure.

I do not see another actionable code finding before maintainer review. The only repository-level caveat is that full lint remains red in unrelated pre-existing upstream files.

@qayshp
qayshp force-pushed the codex/findmy-friends-upstream branch from 434f382 to e0759ee Compare July 22, 2026 02:28
@qayshp
qayshp changed the base branch from master to development July 22, 2026 02:28

@qayshp qayshp left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Branch-target correction after checking both repositories' contribution guides:

The server guide explicitly requires pull requests to target development. I rebuilt this branch directly on the current upstream/development tip, preserved the development-only private-API socket restart guard while resolving overlaps, force-pushed the clean five-commit feature history, and changed this PR's base from master to development.

The retargeted PR is mergeable and now reports a clean merge state. Friends tests, type checking, changed-file ESLint/Prettier, helper verification, and webpack compilation pass. The development-based runtime registered both com.apple.MobileSMS and com.apple.findmy helpers to their correct sockets; authenticated GET/refresh/GET each returned HTTP 200 with all 8 Friends records.

One upstream-only validation caveat is documented in the PR body: the current development production minimizer renames its newest TypeORM migration to t, so the live package used minimization disabled. This branch does not touch migration or webpack configuration.

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