Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

myedenred now requires 2FA token to be inserted #8

Open
taduo opened this issue Jul 17, 2024 · 21 comments
Open

myedenred now requires 2FA token to be inserted #8

taduo opened this issue Jul 17, 2024 · 21 comments

Comments

@taduo
Copy link

taduo commented Jul 17, 2024

The integration does not work anymore because myedenred has implemented 2FA.

2024-07-17 11:11:29.619 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up myedenred platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 366, in _async_setup_platform
    await asyncio.shield(awaitable)
  File "/config/custom_components/myedenred/sensor.py", line 42, in async_setup_entry
    token = await api.login(config["username"], config["password"])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/myedenred/api/myedenred.py", line 38, in login
    return json['data']['token']
           ~~~~~~~~~~~~^^^^^^^^^
KeyError: 'token'
@netsoft-ruidias
Copy link
Owner

yes, it looks like that...
I have also received some login confirmation emails, I will wait to see if there is anything that can be done

@Guergeiro
Copy link

Yes, also happening to me!

@andregoncrod
Copy link

Same here can you check it?

2024-07-17 14:20:02.278 DEBUG (MainThread) [custom_components.myedenred.config_flow] Starting async_step_user... 2024-07-17 14:20:06.294 WARNING (MainThread) [homeassistant.components.camera] Updating xiaomi_cloud_map_extractor camera took longer than the scheduled update interval 0:00:05 2024-07-17 14:20:09.531 DEBUG (MainThread) [custom_components.myedenred.config_flow] Starting async_step_user... 2024-07-17 14:20:09.532 DEBUG (MainThread) [custom_components.myedenred.api.myedenred] Logging in... 2024-07-17 14:20:10.556 DEBUG (MainThread) [custom_components.myedenred.api.myedenred] Done logging in. 2024-07-17 14:20:10.557 ERROR (MainThread) [custom_components.myedenred.config_flow] 'token'

@andregoncrod
Copy link

They need to have an area to create token to communicate with theirs API. Because i think the solution to request the MFA code to HA user is not a solution.

@joaovitoriasilva
Copy link

Hello,

From what I can see there is the following initial request:

{
   "data": {
   	"challengeId": <5 digit code>,
   	"challengeMessage": "Foi enviado um código de confirmação.",
   	"resendTries": 3
   }
}
  • Also two cookies are received that I can't understand why.

After the first request succeeds what happens is:

{
	"authenticationMfaProcessId": <5 digit code in the first request>,
	"challengeId": <5 digit code in the first request>,
	"challengeMessage": "Foi enviado um código de confirmação.",
	"password": <user password>,
	"resendTries": 3,
	"token": <2FA token received in email>,
	"userId": <user_email>
}
  • If the response server is 200 the response contains the auth token

@netsoft-ruidias can you replicate this flow in your plugin?

@andregoncrod
Copy link

Hello @joaovitoriasilva ,
I think this may not be a solution because with each request you will need a new MFA code. Therefore, you cannot be asking to HA user for a code with every request or every time the authentication token expires. The best thing would be to try talk to them to see if it is possible to have users authentication only via API without MFA or with other auth process (via token).

@joaovitoriasilva
Copy link

@andregoncrod yep you are right. I just checked (again) and in fact there is no logic of access+refresh token returned, only the short lived access token is returned.
That is a shame, this could be better implemented.

I highly doubt contacting them is gonna resolve anything.

@netsoft-ruidias
Copy link
Owner

Hello @joaovitoriasilva
I came here to tell you the same as @andregoncrod.
As you can imagine, without access to the email it's not possible to replicate the flow, and having a human introducing the challenge with each request is not a viable solution.

It's hard for me to understand how this company even thinks about closing a service like this.
By using the API (or the website) it is not possible to make transactions, you can only see the statement and not much more, in other words, there is no danger of someone stealing your money...

This is a disservice to theire customers/users...

@rodriguestiago0
Copy link

rodriguestiago0 commented Jul 23, 2024

Hey,

check my last commit. It will solve the issue without adding 2FA.

rodriguestiago0/myedenred-actual@e658d79

Thanks

@netsoft-ruidias
Copy link
Owner

@rodriguestiago0 SUPER 💯

I'll add that logic to my code,
but it will take me some time to do so, as I have no availablility right now...

please be patient

@rodriguestiago0
Copy link

    async def login(self, userID, pin, appVersion):
        """Issue LOGIN request."""
        try:
            params = { 'appVersion': appVersion, 'appType': 'IOS', 'channel': 'MOBILE' }
            _LOGGER.debug("Logging in...")
            async with self.websession.post(
                API_LOGIN_URL, 
                params = params,
                headers = { "Content-Type": "application/json", "User-Agent": "EdenRED/3748 CFNetwork/1496.0.7 Darwin/23.5.0"},
                json={"userId":userID,"password":pin, "appVersion", appVersion, "appType": "IOS"}
            ) as res:
                if res.status == 200 and res.content_type == "application/json":
                    json = await res.json()
                    _LOGGER.debug("Done logging in.")
                    return json['data']['token']
                raise Exception("Could not retrieve token for user, login failed")
        except aiohttp.ClientError as err:
            _LOGGER.error(err)

@netsoft-ruidias
Copy link
Owner

Hey @rodriguestiago0

I was looking at your code and your solution will not work for this component, unfortunately.

Your code depends on knowing the userId which is a GUID we get by looking at the APP's http traffic.
This is not a simple operation and is not within the reach of the vast majority of Home Assistant users.

For now, I will not move forward with the solution, although I may consider alternatives for the future.
Such as, finding an alternative to obtain the GUID that does not involve installing software and traffic inspection techniques that are not simple to perform.

If you have new ideas/suggestions please share.
I appreciated the help

@rodriguestiago0
Copy link

rodriguestiago0 commented Jul 24, 2024

The token is a JWT.

If you authenticate using https://www.myedenred.pt/edenred-customer/v2/authenticate/default?appVersion=4.1.0&appType=IOS&channel=MOBILE

With username and password

{
  "userId": "email",
  "appVersion": "4.1.0",
  "rememberMe": true,
  "password": "password",
  "appType": "IOS",
  "channel": "MOBILE"
}

and then send the 2FA on https://www.myedenred.pt/edenred-customer/v2/authenticate/default/challenge?appVersion=4.1.0&appType=IOS&channel=MOBILE

with

{
  "rememberMe": true,
  "userId": "email",
  "channel": "MOBILE",
  "appVersion": "4.1.0",
  "appType": "IOS",
  "password": "password",
  "authenticationMfaProcessId": <token>,
  "token": "<token>"
}

you will get an JWT token. Parse that token and the userID will be on sub field

@netsoft-ruidias
Copy link
Owner

you will get an JWT token. Parse that token and the userID will be on sub field

Already tried that yesterday, didn't worked 🤔
I'll give it another try, then...

@rodriguestiago0
Copy link

you need to authenticate as mobile user and not a desktop user. The URL I used are using the mobile signature and not the APP

@netsoft-ruidias
Copy link
Owner

I noticed a curious fact

Yesterday I tried logging in normally through the webApp/Portal and after obtaining the token, I parsed it and tried the Login as in your example, using the sub as userId.

It didn't work and returned the error: "Credenciais inválidas. Por favor, tente novamente."

Today I tried your sample, via Postman.
The only thing that changed the appType and appVersion in the payload.
In your example it is "IOS" and "4.1.0", respectively
In my case yesterday was "PORTAL" and "1.0"

After doing with your data and getting the token, I noticed that the sub values are different in both cases.

This leads me to think the sub maybe different depending on the channel that is used, as my APP is Android, logging in with my PIN does not work.

So what I have to find out now, are the real values ​​for android, probably { "appType": "Android", "appVersion": "????" }

I'll give it a try on this

@rodriguestiago0
Copy link

Send the app version of your app. Check the app details page

@rodriguestiago0
Copy link

Is Android or ANDROID?

@netsoft-ruidias
Copy link
Owner

It's "ANDROID" and the appVersion is the same as IOS.

The possible values for appType are: [BACKOFFICE, PORTAL, IOS, ANDROID] (they have a leak 🛡️)

@FlyProg
Copy link

FlyProg commented Nov 25, 2024

Hello to all, someone use this addon with Home Assistant last version ? Because I use and after the last update I have issues with 2fa. Someone have some solution ?

@mapb1990
Copy link

mapb1990 commented Dec 5, 2024

same problem here

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

No branches or pull requests

8 participants