darkphoenix / tolino-calibre-sync

Access to tolino cloud with Python 3 and Calibre
GNU Lesser General Public License v2.1
52 stars 6 forks source link

use_device stops working after a day #3

Open benneti opened 2 years ago

benneti commented 2 years ago

more of a question than a bug report, but is there a way to stay logged in longer using the "use_device" workaround?

darkphoenix commented 2 years ago

I've had mixed luck myself, but my current token is 11 days old and still good. I'll start keeping track of that. It's not ideal, but it seems to at least last a while. FWIW I'm using a meineBuchhandlung login, not sure if it's different for other partners - though since you can use Library Link to tie them together, maybe trying to use another to sign in is worth a shot? To be honest I have an account linked to just about every Tolino partner for debugging, and picked meineBuchhandlung pretty much at random, I haven't experimented much.

benneti commented 2 years ago

Thanks for the reply. In this case i'll try meineBuchhandlung, too. do you have an uncommited tweak of the client because i needed to tweak the tolinocloud.py file to get it to work.

(For thalia the login did not work anymore after about an hour for me)

darkphoenix commented 2 years ago

I'm honestly not sure. I shouldn't, but my local version is a bit messy as I'd tried to implement more partners and not quite finished it, so I cherry-picked the tweaks I needed for this workaround. Would you mind telling me exactly what you changed?

benneti commented 2 years ago

in partner_settings I needed to add

 80: {
            # meinBuchhändler
            'client_id'        : 'meinebuchhandlung0501html5readerV0001',
            'scope'            : 'e-publishing',
            'signup_url'       : '',
            'profile_url'      : '',
            'token_url'        : 'https://lore.shop-asp.de/oauth/token',
            # 'login_form_url'   : '',
            'x_buchde.skin_id' : '17',
            'x_buchde.mandant_id' :'2',
            'x_web_aspde.skinId' : 'web_aspde_de',
            'auth_url'         : 'https://lore.shop-asp.de/oauth/authorize',
            'login_url'        : '',
            'login_form'       : {
                'username' : 'j_username',
                'password' : 'j_password',
                'extra'    : {
                    'login' : ''
                    }
             },
            'login_cookie'     : '',
            'logout_url'       : '',
            'reader_url'       : 'https://webreader.mytolino.com/library/index.html#/mybooks/titles',
            'register_url'     : 'https://bosh.pageplace.de/bosh/rest/v2/registerhw',
            'devices_url'      : 'https://bosh.pageplace.de/bosh/rest/handshake/devices/list',
            'unregister_url'   : 'https://bosh.pageplace.de/bosh/rest/handshake/devices/delete',
            'upload_url'       : 'https://bosh.pageplace.de/bosh/rest/upload',
            'meta_url'         : 'https://bosh.pageplace.de/bosh/rest/meta',
            'cover_url'        : 'https://bosh.pageplace.de/bosh/rest/cover',
            'sync_data_url'    : 'https://bosh.pageplace.de/bosh/rest/sync-data?paths=publications,audiobooks',
            'delete_url'       : 'https://bosh.pageplace.de/bosh/rest/deletecontent',
            'inventory_url'    : 'https://bosh.pageplace.de/bosh/rest/inventory/delta',
            'downloadinfo_url' : 'https://bosh.pageplace.de/bosh/rest//cloud/downloadinfo/{}/{}/type/external-download'
            },

mind that some urls are missing but this should be the minimum to get it working with the workaround.

benneti commented 2 years ago

Also I got around the cloudfare stuff by using from cloudscraper import CloudScraper and in init self.session = CloudScraper(browser={'browser': 'firefox', 'platform': 'linux', 'mobile': False }) but login still did not work

darkphoenix commented 2 years ago

Right, I have those additions due to my attempts at getting meineBuchhandlung to work properly, but they won't actually work for logging in - meineBuchhandlung uses some more complicated stuff in the actual login flow. When using a device token none of the login specific URLs are actually used, it only uses the later pageplace URLs, which are of course identical between all partners, but when you set it to 80 it expects that to exist.

The login for Thalia could work using Cloudscraper, but it certainly won't work for Hugendubel or meineBuchhandlung, due to their more complex flows.

darkphoenix commented 2 years ago

So, I've been digging into this again because I needed to use Thalia - and it seems their expiry logic is different. Libri tokens are long-lived, Thalia's are only good 3600 seconds. Therefore I included some extra logic to use the refresh token for Thalia instead - when the partner is set to anything that isn't 80, the password is interpreted as a refresh token instead (as can be retrieved from the request to thalia.de/.../token), which should last a lot longer.

benneti commented 2 years ago

cool and thanks for the update, I might try again in this case!

Gomez commented 2 years ago

Thanks @darkphoenix

I tried switching to the refresh token but does not work for me. Here is a traceback:

Traceback (most recent call last): File "/jail/scripts/tolino-calibre-sync/tolinocloud.py", line 386, in login j = r.json() File "/usr/lib/python3/dist-packages/requests/models.py", line 897, in json return complexjson.loads(self.text, **kwargs) File "/usr/lib/python3.7/json/__init__.py", line 348, in loads return _default_decoder.decode(s) File "/usr/lib/python3.7/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib/python3.7/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I use thalia.de.

darkphoenix commented 2 years ago

This looks like Thalia is not returning a valid JSON at all - which is... interesting, I usually got a JSON formatted error message. Would you mind running it with --debug? That should print out the full HTTP response you actually get.

darkphoenix commented 2 years ago

Also @benneti, it appears even with a refresh token Thalia has relatively short lived sessions. I should keep a list of this... Libri access tokens are good for a long while, Thalia's are very short and their refresh tokens die, too (and they don't give you a new one, I've actually attempted to store the refresh token returned by /token with no success), Weltbild has access tokens good for half a day or so and refresh tokens good for a while - I've been testing one for a few days and it hasn't expired yet, will update when it does. This is all in the OAuth setup of the individual providers, so the life varies quite a bit. I also wonder if I could get a better token by using a client ID associated with an actual reader device or app, not the web reader, but I'm not entirely sure how I would even go about doing that.

darkphoenix commented 2 years ago

So as a minor update, the Weltbild token is still running with no change 3 months later, so I'd say it's a decent option.