malmeloo / hass-FindMy

Custom Home Assistant integration for Apple's FindMy network.
GNU General Public License v3.0
4 stars 0 forks source link

Trusted device 2FA #1

Closed guniv closed 3 months ago

guniv commented 5 months ago

Gave this a shot today setting up on my Home Assistant. Barely know what I am doing with this stuff but this integration is really exciting to me. If I can just use this instead of running an entire MacOS virtual machine I'd be very pleased.

I set up an anisette server in docker and entered the URL and Apple login info and received the following error:

Traceback (most recent call last):
  File "/config/custom_components/findmy/config_flow.py", line 97, in async_step_login
    await self._account.login(info["email"], info["password"])
  File "/usr/local/lib/python3.12/site-packages/findmy/reports/account.py", line 350, in login
    new_state = await self._gsa_authenticate(username, password)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/findmy/reports/account.py", line 524, in _gsa_authenticate
    raise UnhandledProtocolError(msg)
findmy.util.errors.UnhandledProtocolError: Unknown auth value: trustedDeviceSecondaryAuth
malmeloo commented 5 months ago

Trusted device 2FA has been implemented in the library a few months ago which should fix this error, but this repo is a code dump from before that time. I likely won't have a lot of time in the foreseeable future to actually update this unfortunately, but I'll leave this open as a reminder. This integration is currently not in a usable state yet, anyway. Summer vacation, hopefully :-)

thisiscam commented 4 months ago

This repo looks very promising and seems like it's a few (hundred) lines of code away from a functional HA AirTag tracker component?

One question: how often does the 2FA login expire? It would be a headache to have to re-authenticate manually every week, IMO.

malmeloo commented 4 months ago

I don't think it expires as long as the anisette data stays the same. Username / password will be saved by the component, and reauthentication will skip 2FA when you're using the same anisette data. In theory, that data should be static.

There might be a time limit enforced by Apple, but if so it has to be quite long. People have successfully used FindMy.py for extended periods of time (weeks, months) without having to redo 2FA. So far, the mobileme login was the first to expire, which can also be refreshed without 2FA, so I don't foresee any issues.

thisiscam commented 4 months ago

Oh that's good to hear! I just coded up a simple script based on the real_airtag.py. I added a MQTT device tracker and let the script update the GPS coordinates every 15 mins, it works like a charm! This approach adds some complexity but completely avoids the need to write a custom component.

Do you know if Apple have any restrictions on the polling frequency?

thisiscam commented 4 months ago

Also, do you have suggestion over if I should repeatedly authenticate with Apple every polling cycle, or I should keep the connection "alive" (maybe until it times out)?

malmeloo commented 4 months ago

Oh that's good to hear! I just coded up a simple script based on the real_airtag.py. I added a MQTT device tracker and let the script update the GPS coordinates every 15 mins, it works like a charm! This approach adds some complexity but completely avoids the need to write a custom component.

Do you know if Apple have any restrictions on the polling frequency?

I don't know if there's any rate limiting, but once every 15 minutes should be fine. I've hammered it much more than that during testing.

Also, do you have suggestion over if I should repeatedly authenticate with Apple every polling cycle, or I should keep the connection "alive" (maybe until it times out)?

Don't reauthenticate, that sounds like a sure way to get blocked. Use the library's dump() and load() methods on AppleAccount to save and load internal state to/from a JSON object, it will be more efficient.

thisiscam commented 4 months ago

Don't reauthenticate, that sounds like a sure way to get blocked. Use the library's dump() and load() methods on AppleAccount to save and load internal state to/from a JSON object, it will be more efficient.

Thanks for the tip! I'm using get_account_sync from the login helper and I think it does exactly what you describe.

For some reason though, I can only use my day-use apple id to fetch the reports. I tried a dev account I've had for years but it just reports that I cannot login to the com.apple.mobileme. Does the account have to be linked to the AirTag somehow (e.g. if I use account X to fetch the reports using the library, does the AirTag needs to be initially paired on a machine that was logged-in by X)?

malmeloo commented 4 months ago

Oh yes, in that case it should be fine. The account does not have to be linked, but have you ever added a device to your account? I believe that is a hard requirement, though I'm not 100% certain.

thisiscam commented 4 months ago

Oh yes, in that case it should be fine. The account does not have to be linked, but have you ever added a device to your account? I believe that is a hard requirement, though I'm not 100% certain.

Like, at least one Apple device needs to have the account logged in?

malmeloo commented 4 months ago

It needs to have had a device attached to it at some point, I think. At least, that's what I found during my limited testing; new accounts don't work, but my very old one does. I believe there is some kind of account trust mechanism involved behind the scenes.

malmeloo commented 3 months ago

Trusted device 2FA was implemented, the login flow and location fetching should now also work. See instructions in the README if you want to pre-alpha test ;-)

guniv commented 3 months ago

What private keys are you referring to in the readme?

malmeloo commented 3 months ago

The private key as generated by OpenHaystack. Official Apple accessories are not (yet) supported by the integration, but the library does support them, so it's on the roadmap.

thisiscam commented 3 months ago

The private key as generated by OpenHaystack. Official Apple accessories are not (yet) supported by the integration, but the library does support them, so it's on the roadmap.

Can't wait for this feature! My homebrew solution based on MQTT works but would be great if I can get rid of the dedicated VM.

IMO, the integration should provide both the crowdsourcing tracking and the BLE tracking (perhaps as two device_trackers in HA). Something to consider!

malmeloo commented 3 months ago

That was my intention! I'll be focusing on the network aspect first, but it would be really cool to have an all-in-one solution.