malmeloo / hass-FindMy

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

Trusted device 2FA #1

Open guniv opened 3 weeks ago

guniv commented 3 weeks 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 3 weeks 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 6 days 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 5 days 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 5 days 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 5 days 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 days 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 days 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 days 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 days 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 days 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.