lukas-clarke / eight_sleep

Home Assistant Eight Sleep integration that works with Eight Sleep's new API and OAUTH2
MIT License
62 stars 11 forks source link

Auth request failed with status code: 401 #26

Open Gtwizzy opened 2 months ago

Gtwizzy commented 2 months ago

Just started having an issue with the integration this morning. I've reloaded HA and even rolled back to a previous backup up and still nothing seems to allow the integration to connect.

I'm wondering if Eight Sleep has gotten wind of requests being made from an "unknown source" to their server and they've blocked all traffic. Or if its just me that's experiencing the issue.

mwalling commented 2 months ago

Me too. šŸ˜­

BDubz20 commented 2 months ago

Same here. App is functional

lukas-clarke commented 2 months ago

I'm not seeing this issue (yet?). I won't have time to take a look this week, but may be able to over the weekend.

Just to confirm, when setting up or reloading the integration, the pod is connected and not in away mode?

Nezz commented 2 months ago

Same issue here, it started happening 4 hours ago. The pod is connected and not in away mode.

I deleted the existing integration and tried to set it up again. It fails with "Credentials are invalid".

julianrinaldi commented 2 months ago

Same for me. I finally realized there was a way to get this working again with this integration last week. And spent a bunch of time on setting up different automations. And now they've likely blocked it again. I love my Eight mattress, but if it ever needs to be replaced I'm not sure I would buy one again if they're going to keep doing things like this. So annoying. It has been one of my most useful things to automate.

adamksmith commented 2 months ago

So I did some tinkering tonight and this is what I found:

They have added tighter validation around the device making the request, so the header of "Android App" is no longer valid, I had to pull the header off my phone to fake it. They have also re-enabled/added tighter validation around the requirement of clientId and clientSecret. I was able to get HA to talk to the API once more when I changed the user-agent constant and added the clientId and clientSecret for my phones session.

MarcCA commented 2 months ago

I got it back working as well by adding username, password, client_id and client_secret in the eight.py file @adamksmith were you able to get it running even without username and password ?

Gtwizzy commented 2 months ago

I'm not seeing this issue (yet?). I won't have time to take a look this week, but may be able to over the weekend.

Just to confirm, when setting up or reloading the integration, the pod is connected and not in away mode?

Pod is definitely connected and not in away mode. Seems there's a larger issue at play regarding authentication having been tightened by Eight Sleep.

Thanks for your continued updates and support on this integration BTW. A huge amount of us rely on the talents and skills of people like yourself who are willing to put in the time and effort to build out these kinds of connections for us. I know that a lot of this kind of development comes from people crowbarring the development of these kinds of things into precious moments of personal time with little to no monetary reward.

So again, Thank you

f1dgj commented 2 months ago

I have the same, tried reloading etc but it's not working. I have no clue what my clientid and secret would be and can't find anything to create these with eight.

adamksmith commented 2 months ago

As I have time today I might take a stab at rotating the headers as they make changes on their backend. Make no real promises on getting something out this week as well.

In regards to clientId and clientSecret its not something explicitly shown to the end user, I've always been getting it with Fiddler doing packet captures on my phone so unfortunately your results may vary there in the interim.

mwalling commented 2 months ago

Finally had time to poke. I don't think the situation is that dire; I think they're just now checking the client_secret.

For example, these two requests worked when playing in HTTPie:

POST /v1/tokens HTTP/1.1
Content-Length: x
Content-Type: application/json
Host: auth-api.8slp.net
User-Agent: HTTPie

{
    "client_id": "0894c7f33bb94800a03f1f4df13a4f38",
    "client_secret": "x I got this from pointing my iPhone at mitmweb",
    "grant_type": "password",
    "password": "x",
    "username": "x"
}
GET /v2/users/x/routines HTTP/1.1
Authorization: Bearer x
Host: app-api.8slp.net
User-Agent: HTTPie

But this request fails with a 401:

POST /v1/tokens HTTP/1.1
Content-Length: x
Content-Type: application/json
Host: auth-api.8slp.net
User-Agent: HTTPie

{
    "client_id": "0894c7f33bb94800a03f1f4df13a4f38",
    "client_secret": "ASDF",
    "grant_type": "password",
    "password": "x",
    "username": "x"
}

Updating the client secret in eight.py, everything works like a charm for me. I've got feelings about sharing the secret, at least until we know more about it (a bored and malicious version of me would make the secret derived from the username/password and device fingerprint. Definitely more important than getting the auto-pilot adjustment timeline back in the app, but I'm not šŸ§‚).

If anyone wants to cross-check and see if I'm being paranoid, the sha256 of my client_secret is 85ec9c8f43e42ee2b1c86620a546cc02f9778914d6dbc8c23cbe57558109aed7

~From a Home Assistant integration point of view, I think client_id and client_secret should be user configs. That way, if we get into a game of whack-a-mole with them, it doesn't require Lukas to cut a new release.~ This already exists

MarcCA commented 2 months ago

@mwalling I can confirm that it matches the same client secret (start with f ends with 6) I used which I got by checking the traffic via Fiddler from my iOS app. So it should work for everyone. I Only can imagine that the iOS and Android apps have different client secrets which wouldn't matter anyway.

mwalling commented 2 months ago
    .line 79
    new-instance v3, Lorg/json/JSONObject;

    invoke-direct {v3}, Lorg/json/JSONObject;-><init>()V
    :try_end_22
    .catch Ljava/lang/Exception; {:try_start_5 .. :try_end_22} :catch_75

    :try_start_22
    const-string v4, "client_id"

    const-string v5, "0894c7f33bb94800a03f1f4df13a4f38"

    .line 81
    invoke-virtual {v3, v4, v5}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;

    const-string v4, "client_secret"

    const-string v5, "f0954a3ed5763ba3d06834c73731a32f15f168f47d4f164751275def86db0c76"

    .line 82
    invoke-virtual {v3, v4, v5}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;

    const-string v4, "grant_type"

šŸ™ƒ They don't even try... guess its fair game.

adamksmith commented 2 months ago

Yup can totally confirm I was overthinking it, my bad... tried what was posted and it works...

ucito commented 2 months ago

I also try the data from mwalling and the pod is connected again with ha

thank you!

Nipal33 commented 2 months ago

Thank you guys ! Works again. This community is amazing :D

Nezz commented 2 months ago

@lukas-clarke Should we change the client_id and client_secret to be the values in @mwalling's comment by default?

I guess people who don't encounter this issue are the ones who manually set these values.

lukas-clarke commented 2 months ago

@Nezz, I plan on adding a list of "known" client IDs and secrets. And for the integration to go through the list to find one that works if the client Id/secret aren't set on initial config. I should be able to make that change this weekend.

We also can keep a GitHub "thread" open so if this happens again, people can use the fields in the setup for the integration to get it to work, without having to wait for changes to the code.

I'm not sure why this is affecting some users but not others. Even if someone manually configured their client Id & secret, previously they were all the same so even manual configs would have broken at this. Maybe this depends on what OS you use for the app. Are the people seeing this issue all iOS users?

mwalling commented 2 months ago

@lukas-clarke My phone is iOS, but the values I pulled from mitmproxy when using my iPhone to log in match the values I pulled from the decompiled .apk, so they seem to be using the same client_id/client_secret for both platforms.

Nezz commented 2 months ago

Are the people seeing this issue all iOS users?

I left the client ID and secret empty, so the integration defaulted to using ASDF as the secret: https://github.com/lukas-clarke/eight_sleep/blob/8c2ddebf7e1a40d3659efff8568e9b3457a6c9d2/custom_components/eight_sleep/pyEight/eight.py#L52-L55

lukas-clarke commented 2 months ago

Oh yes, I recall now. The auth command would work with any string as the client secret. Since they have changed it to requiring a string, it makes sense that those who configured their client string wouldn't be seeing this issue.

ucito commented 2 months ago

I also had these problems and I am an android user

jschulman commented 2 months ago

at 8p CST, I'm using the client_secret provided above and getting invalid credentials. I also checked and they updated the iOS app today.

neildsb commented 2 months ago

deleted and added back integration and used @mwalling client details, its working fine, BTW I am using an android app and phone

jschulman commented 2 months ago

at 8p CST, I'm using the client_secret provided above and getting invalid credentials. I also checked and they updated the iOS app today.

Rebooting home assistant resolved this. Iā€™m back in business. Thanks.

michaeldjjohnson commented 2 months ago

No matter how much I try, this no longer works for me. E-mail and password used to work just fine and now just says "Credentials are invalid"

Do you have any suggestions please?

grantnedwards commented 2 months ago

Yeah this works, I used my own client credentials from mitmweb and just checked, i'm able to log in and set up Eight Sleep in Home Assistant now. Ty again @mwalling

I used iOS and also pointed it to mitmweb to gather the POST json info

lukas-clarke commented 2 months ago

Created a release with the know client_secret