netbrain / zwift

Easily zwift on linux
The Unlicense
265 stars 28 forks source link

Zwift password #17

Closed SirYaro closed 1 year ago

SirYaro commented 1 year ago

Hi. Every time I start zwift docker the app welcomes me with login dialog, where email is already entered, but password field is blank.

I'd like to ask if there is an option to make zwift docker auto login to my account or just not forgetting password :)

netbrain commented 1 year ago

There probably is, but I haven't found it. Feel free to check the configuration files of zwift. ($HOME/.zwift/<user>/) Maybe there is some options in ZL.inior prefs.xml regarding this.

May need to boot zwift up on a proper windows instance in order for it to generate the config required for that. Not sure. And if you find it, please let the rest of the community know about it.

SirYaro commented 1 year ago

@netbrain I found out that this is quite common problem, especially after update. People are recommending to install a tool to workaround it: https://zwifthacks.com/zwift-login/

I also found that there might be a better/native way to fix that. Some docs/posts state that credentials are stored in a really weird place (%TEMP%): "c:\Users\USERNAME\AppData\Local\Temp\Zwift\EBWebView" and then probably "Default\Login Data" (which looks like litesql) I believe saving EBWebView directory outside of container (same way as you do with configuration) have a good chance of fixing this issue.

netbrain commented 1 year ago

Did a docker diff on a running zwift container after logging in. and these are the changed files. (C for changed, and A for Added)

C /usr
C /usr/bin
A /usr/bin/nvidia-debugdump
A /usr/bin/nvidia-smi
A /usr/bin/nvidia-persistenced
C /usr/lib
C /usr/lib/x86_64-linux-gnu
A /usr/lib/x86_64-linux-gnu/libGLESv2_nvidia.so.2
A /usr/lib/x86_64-linux-gnu/libnvidia-fbc.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-glsi.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-glvkspirv.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-tls.so.535.98
A /usr/lib/x86_64-linux-gnu/libGLESv1_CM_nvidia.so.1
A /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-cfg.so.1
A /usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvoptix.so.1
A /usr/lib/x86_64-linux-gnu/libGLESv2_nvidia.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1
A /usr/lib/x86_64-linux-gnu/libGLESv1_CM_nvidia.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-cfg.so.535.98
A /usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.0
A /usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.0
A /usr/lib/x86_64-linux-gnu/libnvidia-fbc.so.1
A /usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvoptix.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-eglcore.so.535.98
A /usr/lib/x86_64-linux-gnu/libnvidia-rtcore.so.535.98
C /usr/lib/i386-linux-gnu
A /usr/lib/i386-linux-gnu/libnvidia-eglcore.so.535.98
A /usr/lib/i386-linux-gnu/libnvidia-ml.so.1
A /usr/lib/i386-linux-gnu/libEGL_nvidia.so.0
A /usr/lib/i386-linux-gnu/libGLX_nvidia.so.535.98
A /usr/lib/i386-linux-gnu/libGLESv1_CM_nvidia.so.1
A /usr/lib/i386-linux-gnu/libnvidia-tls.so.535.98
A /usr/lib/i386-linux-gnu/libnvidia-ml.so.535.98
A /usr/lib/i386-linux-gnu/libGLX_nvidia.so.0
A /usr/lib/i386-linux-gnu/libnvidia-glvkspirv.so.535.98
A /usr/lib/i386-linux-gnu/libGLESv1_CM_nvidia.so.535.98
A /usr/lib/i386-linux-gnu/libnvidia-fbc.so.1
A /usr/lib/i386-linux-gnu/libnvidia-glcore.so.535.98
A /usr/lib/i386-linux-gnu/libnvidia-glsi.so.535.98
A /usr/lib/i386-linux-gnu/libEGL_nvidia.so.535.98
A /usr/lib/i386-linux-gnu/libGLESv2_nvidia.so.2
A /usr/lib/i386-linux-gnu/libnvidia-fbc.so.535.98
A /usr/lib/i386-linux-gnu/libGLESv2_nvidia.so.535.98
C /run
A /run/user
A /run/user/1000
A /run/user/1000/pulse
C /tmp
A /tmp/.X11-unix
A /tmp/.wine-1000
A /tmp/.wine-1000/server-2d-5e16d5
A /tmp/.wine-1000/server-2d-5e16d5/lock
A /tmp/.wine-1000/server-2d-5e16d5/socket
C /etc
C /etc/ld.so.cache
A /etc/nvidia
A /etc/nvidia/nvidia-application-profiles-rc.d
C /var
C /var/cache
C /var/cache/ldconfig
C /var/cache/ldconfig/aux-cache
C /home
C /home/user
C /home/user/.cache
A /home/user/.cache/nvidia
A /home/user/.cache/nvidia/GLCache
A /home/user/.cache/nvidia/GLCache/a390a745c14bdb8c303452a45fa22098
A /home/user/.cache/nvidia/GLCache/a390a745c14bdb8c303452a45fa22098/3cb1e38a959752ff
A /home/user/.cache/nvidia/GLCache/a390a745c14bdb8c303452a45fa22098/3cb1e38a959752ff/92f74448a56b9fe6.bin
A /home/user/.cache/nvidia/GLCache/a390a745c14bdb8c303452a45fa22098/3cb1e38a959752ff/92f74448a56b9fe6.toc
C /home/user/.config
A /home/user/.config/pulse
A /home/user/.config/pulse/cookie
C /home/user/.wine
C /home/user/.wine/dosdevices
C /home/user/.wine/dosdevices/com22
C /home/user/.wine/dosdevices/com26
C /home/user/.wine/dosdevices/com27
C /home/user/.wine/dosdevices/com30
C /home/user/.wine/dosdevices/com31
C /home/user/.wine/dosdevices/com15
C /home/user/.wine/dosdevices/com17
C /home/user/.wine/dosdevices/com18
C /home/user/.wine/dosdevices/com29
C /home/user/.wine/dosdevices/com9
C /home/user/.wine/dosdevices/com24
C /home/user/.wine/dosdevices/com25
C /home/user/.wine/dosdevices/com3
C /home/user/.wine/dosdevices/com32
C /home/user/.wine/dosdevices/com5
C /home/user/.wine/dosdevices/com1
C /home/user/.wine/dosdevices/com19
C /home/user/.wine/dosdevices/com6
C /home/user/.wine/dosdevices/com7
C /home/user/.wine/dosdevices/com21
A /home/user/.wine/dosdevices/com33
C /home/user/.wine/dosdevices/com16
C /home/user/.wine/dosdevices/com2
C /home/user/.wine/dosdevices/com20
C /home/user/.wine/dosdevices/com11
C /home/user/.wine/dosdevices/com13
C /home/user/.wine/dosdevices/com14
C /home/user/.wine/dosdevices/com4
C /home/user/.wine/dosdevices/com28
C /home/user/.wine/dosdevices/com8
C /home/user/.wine/dosdevices/com10
C /home/user/.wine/dosdevices/com12
C /home/user/.wine/dosdevices/com23
C /home/user/.wine/drive_c
C /home/user/.wine/drive_c/Program Files (x86)
C /home/user/.wine/drive_c/Program Files (x86)/Zwift
A /home/user/.wine/drive_c/Program Files (x86)/Zwift/WorkoutValidationLog.txt
C /home/user/.wine/drive_c/ProgramData
C /home/user/.wine/drive_c/ProgramData/Microsoft
C /home/user/.wine/drive_c/ProgramData/Microsoft/EdgeUpdate
C /home/user/.wine/drive_c/ProgramData/Microsoft/EdgeUpdate/Log
C /home/user/.wine/drive_c/ProgramData/Microsoft/EdgeUpdate/Log/MicrosoftEdgeUpdate.log
C /home/user/.wine/drive_c/users
C /home/user/.wine/drive_c/users/user
C /home/user/.wine/drive_c/users/user/AppData
C /home/user/.wine/drive_c/users/user/AppData/Local
A /home/user/.wine/drive_c/users/user/AppData/Local/Zwift
A /home/user/.wine/drive_c/users/user/AppData/Local/Zwift/prefs.xml
C /home/user/.wine/drive_c/windows
C /home/user/.wine/drive_c/windows/Microsoft.NET
C /home/user/.wine/drive_c/windows/Microsoft.NET/Framework64
C /home/user/.wine/drive_c/windows/Microsoft.NET/Framework64/v4.0.30319
C /home/user/.wine/drive_c/windows/Microsoft.NET/Framework64/v4.0.30319/ngen_service.log
C /home/user/.wine/system.reg
C /home/user/.wine/user.reg

After looking at the contents of the zwift specific files, i really can't find any place where passwords would be stored. It might be that it doesn't save the user profile until zwift exits, so that could be tested, but i doubt it.

SirYaro commented 1 year ago

I just went to my neighbour and check zwift on his Windows computer (win10 I think). After login and login out, I found a new dir called c:\Users\tomek\AppData\Local\Temp\Zwift\EBWebView and from now on, login to zwift was automatic. Then I renamed EBWebView to EBWebView.bak

As a result, launcher asked me for my creds again. Then I renamed it back and login was automatic again.

I don't know why you did not find this dir, but it works. Creds (in form of some key or cookie etc) are stored under this path.

netbrain commented 1 year ago

Yes, but as you can see, this file is not created on the wine version of zwift, i'm not sure why. Most likely there is a condition that's not being met, causing the EBWebView to never be created.

netbrain commented 1 year ago

You easily test this yourself if you want. just add the -v flag in zwift.sh, something along the lines of -v /tmp/zwift-test:/home/user/.wine/drive_c/users/user/AppData/Local/Zwift

SirYaro commented 1 year ago

This EBWebView dir is related to Edge (I'm almost certain it's created by Edge component), so my guess would be missing browser in container or something like that. But that much you probably figure out long time ago :)

netbrain commented 1 year ago

I'm finding this one however.

./.wine/drive_c/users/user/Temp/Zwift/EBWebView

But it's not being changed in any way during login. It's a bit far fetched, but if you delete that folder, then commit a new image and try to run it with the abovementioned volume mount. then maaybe. just maybe this would work :) Don't have the time to test now tho..

quietvoid commented 1 year ago

On Windows I've only had to enter the credentials in the launcher, never after the game is launched.

I think the current entrypoint bypasses the launcher. However in Wine I haven't been able to see the launcher rendered properly.

SirYaro commented 1 year ago

You might have a point. I always wondered why start up is done this way:

echo "starting zwift..."
wine64 start ZwiftLauncher.exe
wine64 start RunFromProcess-x64.exe ZwiftLauncher.exe ZwiftApp.exe

When in theory wine64 start ZwiftLauncher.exe alone should be sufficient.

netbrain commented 1 year ago

Not sure either, these steps were blatantly stolen from other installation guides. Feel free to test any other entry points to ser how it goes.

You can run a different entry point using --entrypoint=bash for instance.

On Thu, Aug 31, 2023, 11:22 Sir_Yaro @.***> wrote:

You might have a point. I always wondered why start up is done this way:

echo "starting zwift..." wine64 start ZwiftLauncher.exe wine64 start RunFromProcess-x64.exe ZwiftLauncher.exe ZwiftApp.exe

When in theory wine64 start ZwiftLauncher.exe should be sufficient.

— Reply to this email directly, view it on GitHub https://github.com/netbrain/zwift/issues/17#issuecomment-1700677355, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACTNC34EPD6G5M6XW5DR6TXYBJTTANCNFSM6AAAAAA32OYLTQ . You are receiving this because you were mentioned.Message ID: @.***>

netbrain commented 1 year ago

Another thing you can do is run zwift with the environment variable WINEDEBUG=all, maybe you can find where the login is stored and then figure out why it isn't persisted between restarts.

Another option is to never actually remove the zwift container, but to just keep it alive and simply stop the container and start it again between rides. or maybe even just "docker pause". Will tho have to restart it for updates.

quietvoid commented 1 year ago

I tried setting up Zwift + WebView2 but it seems like quite a mess, today at least. Reading some older posts it seems people were able to use the launcher in the past, but I'm not sure if it actually ever worked.

Installing WebView2 certainly doesn't work properly or at all most of the time, and it's required for the launcher. Either the installer is stuck or the launcher is just blank where it shouldn't be.

Maybe the alternative is figuring out where the credentials are stored on a Windows install, and copying the file to the container. edit: the launcher is probably still required as it refreshes an auth token every time the game is launched. but that could be done pretty easily without it too, just have to find out how the process figures out it's already authenticated

edit2: the game launches with "C:\Program Files (x86)\Zwift\ZwiftApp.exe" --launcher_version=1.1.9 --token=JSON where --token={ ... } is a JWT like done here in zwift-offline: https://github.com/zoffline/zwift-offline/blob/3cad80ad4e66b2183625942f213a77522f90f82f/zwift_offline.py#L3635

So it's possible we can do the same as long as auth is done prior to launching. I might try to do it, but feel free to try as well :slightly_smiling_face:

I presume this is also what zwift-login is doing, but I'm not sure if its code is available (and I haven't tried getting the .ahk files).

quietvoid commented 1 year ago

I have auth working but the JSON is getting truncated somewhere and the logs show it:

[13:58:33] [ERROR] Error parsing JSON: * Line 1, Column 2
  Missing '}' or object member name

JSON: {\"access_token\":\"...
[13:58:33] Login error: Error parsing json
[13:58:34] [INFO] Telemetry enabled (batch mode)
[13:58:34] [INFO] Sending first telemetry...

It's being run like this:

wine64 start RunFromProcess-x64.exe ZwiftLauncher.exe ZwiftApp.exe '--token={...}'

Conveniently it's at exactly 999 characters but I don't know what's causing it. Could be RunFromProcess.

netbrain commented 1 year ago

Which json file is this?

On Sun, Sep 3, 2023, 16:02 quietvoid @.***> wrote:

I have auth working but the JSON is getting truncated somewhere and the logs show it:

[13:58:33] [ERROR] Error parsing JSON: * Line 1, Column 2 Missing '}' or object member name

JSON: {\"access_token\":\"... [13:58:33] Login error: Error parsing json [13:58:34] [INFO] Telemetry enabled (batch mode) [13:58:34] [INFO] Sending first telemetry...

— Reply to this email directly, view it on GitHub https://github.com/netbrain/zwift/issues/17#issuecomment-1704314601, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACTNCYGQAK3U2LJLFAT74TXYSEV7ANCNFSM6AAAAAA32OYLTQ . You are receiving this because you were mentioned.Message ID: @.***>

quietvoid commented 1 year ago

Which json file is this?

The auth JWT obtained by logging in through the authentication API, it has to be passed to ZwiftApp.exe through CLI for auto login. I should make a draft PR with the basic script, but I don't know how we'd want to configure the credentials. Could be a file in the Zwift config folder, as that's mounted as volume.

I've made a test case that reproduces the issue and it's definitely caused by RunFromProcess. Guess I'll email the author. With sample C code, when ran as children process the arg is truncated to 1009 in length. While bypassing the extra app has the full size arg.

netbrain commented 1 year ago

I see. Another option would be to create your own "runfromprocess" executable. Im guessing it simply spawns a process with a specific set of system call flags.

If you can identify how it spawns the process, the actual syscalls. Then it should be fairly straightforward to create a application that replicates that and is not limited with the arg truncation problem

On Sun, Sep 3, 2023, 16:47 quietvoid @.***> wrote:

Which json file is this?

The auth JWT obtained by logging in through the authentication API, it has to be passed to ZwiftApp.exe through CLI for auto login. I should make a draft PR with the basic script, but I don't know how we'd want to configure the credentials. Could be a file in the Zwift config folder, as that's mounted as volume.

I've made a test case that reproduces the issue and it's definitely caused by RunFromProcess. Guess I'll email the author. With sample C code, when ran as children process the arg is truncated to 1009 in length. While bypassing the extra app has the full size arg.

— Reply to this email directly, view it on GitHub https://github.com/netbrain/zwift/issues/17#issuecomment-1704325105, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACTNCYSWES6R7LZECGS4R3XYSKB5ANCNFSM6AAAAAA32OYLTQ . You are receiving this because you were mentioned.Message ID: @.***>

quietvoid commented 1 year ago

I attempted to reimplement it based on others' code (https://github.com/quietvoid/runfromprocess-rs) but it doesn't work. My test code also results in part of the argument being passed (~2000 characters at most), and the Zwift window plainly just crashes.

I think I'll just wait for an answer from Nir instead of spending more time looking into this.

edit: I've actually managed to make it work but killing ZwiftLauncher also kills the game, so it's not great. Maybe I can figure out the rest. It seems pgrep ZwiftApp.exe goes too fast and kills everything before it has a chance.

Anyways, the authentication works but the rest is really janky and the container gets stuck when Zwift is closed, so I'm not sure it's worth using until RunFromProcess can work better.

~I'm still not sure how it works in Zwift but not my test code where the arg is still seemingly limited.~ Apparently adding single quotes around the argument makes it work fine in my test case, but still not when using NirSoft's RunFromProcess.

netbrain commented 1 year ago

building new image with this feature: https://github.com/netbrain/zwift/actions/runs/6125846865

netbrain commented 1 year ago

Can confirm that autologin works on the latest zwift image. :partying_face: