|
45 | 45 | ) |
46 | 46 | from urllib.parse import parse_qs, urlencode, urlsplit |
47 | 47 |
|
| 48 | +import pyaes |
48 | 49 | import requests |
49 | 50 | from requests.exceptions import HTTPError |
50 | 51 |
|
@@ -111,7 +112,6 @@ class Config: |
111 | 112 | api_v1_location: str = "https://api.tidal.com/v1/" |
112 | 113 | api_v2_location: str = "https://api.tidal.com/v2/" |
113 | 114 | openapi_v2_location: str = "https://openapi.tidal.com/v2/" |
114 | | - api_token: str |
115 | 115 | client_id: str |
116 | 116 | client_secret: str |
117 | 117 | image_url: str = "https://resources.tidal.com/images/%s/%ix%i.jpg" |
@@ -151,65 +151,25 @@ def __init__( |
151 | 151 | else: |
152 | 152 | self.item_limit = item_limit |
153 | 153 |
|
154 | | - self.api_token = eval("\x67\x6c\x6f\x62\x61\x6c\x73".encode("437"))()[ |
155 | | - "\x5f\x5f\x6e\x61\x6d\x65\x5f\x5f".encode( |
156 | | - "".join(map(chr, [105, 105, 99, 115, 97][::-1])) |
157 | | - ).decode("".join(map(chr, [117, 116, 70, 95, 56]))) |
158 | | - ] |
159 | | - self.api_token += "." + eval( |
160 | | - "\x74\x79\x70\x65\x28\x73\x65\x6c\x66\x29\x2e\x5f\x5f\x6e\x61\x6d\x65\x5f\x5f".encode( |
161 | | - "".join(map(chr, [105, 105, 99, 115, 97][::-1])) |
162 | | - ).decode( |
163 | | - "".join(map(chr, [117, 116, 70, 95, 56])) |
| 154 | + # OAuth Client Authorization |
| 155 | + self.client_id = base64.b64decode( |
| 156 | + base64.b64decode(b"V214bmVWTnVhR3RpVnpVdw==") |
| 157 | + + base64.b64decode(b"VjJ4a1RFMUhiRFJXUVQwOQ==") |
| 158 | + ).decode("utf-8") |
| 159 | + self.client_secret = base64.b64decode( |
| 160 | + base64.b64decode( |
| 161 | + b"VFZVMWRVOVZSbTFTUlVaeFpVaEtibE5yV2t0WmEzUlBWakI0YkZGWQ==" |
164 | 162 | ) |
165 | | - ) |
166 | | - token = self.api_token |
167 | | - token = token[:8] + token[16:] |
168 | | - self.api_token = list( |
169 | | - (base64.b64decode("d3RjaThkamFfbHlhQnBKaWQuMkMwb3puT2ZtaXhnMA==").decode()) |
170 | | - ) |
171 | | - tok = "".join(([chr(ord(x) - 2) for x in token[-6:]])) |
172 | | - token2 = token |
173 | | - token = token[:9] |
174 | | - token += tok |
175 | | - tok2 = "".join(([chr(ord(x) - 2) for x in token[:-7]])) |
176 | | - token = token[8:] |
177 | | - token = tok2 + token |
178 | | - self.api_token = list( |
179 | | - (base64.b64decode("enJVZzRiWF9IalZfVm5rZ2MuMkF0bURsUGRvZzRldA==").decode()) |
180 | | - ) |
181 | | - for word in token: |
182 | | - self.api_token.remove(word) |
183 | | - self.api_token = "".join(self.api_token) |
184 | | - string = "" |
185 | | - save = False |
186 | | - if not isinstance(token2, str): |
187 | | - save = True |
188 | | - string = "".encode("ISO-8859-1") |
189 | | - token2 = token2.encode("ISO-8859-1") |
190 | | - tok = string.join(([chr(ord(x) + 24) for x in token2[:-7]])) |
191 | | - token2 = token2[8:] |
192 | | - token2 = tok + token2 |
193 | | - tok2 = string.join(([chr(ord(x) + 23) for x in token2[-6:]])) |
194 | | - token2 = token2[:9] |
195 | | - token2 += tok2 |
196 | | - self.client_id = list( |
197 | | - ( |
198 | | - base64.b64decode( |
199 | | - "VoxKgUt8aHlEhEZ5cYhKgVAucVp2hnOFUH1WgE5+QlY2" |
200 | | - "dWtYVEptd2x2YnR0UDd3bE1scmM3MnNlND0=" |
201 | | - ).decode("ISO-8859-1") |
| 163 | + + base64.b64decode( |
| 164 | + b"YkV4U01WcElZbFZzVDJSV2FGRlZSWGhKVm14b1FtUnVhRUphZWpBOQ==" |
202 | 165 | ) |
203 | | - ) |
204 | | - if save: |
205 | | - token2.decode("ISO-8859-1").encode("utf-16") |
206 | | - self.client_id = [x.encode("ISO-8859-1") for x in self.client_id] |
207 | | - for word in token2: |
208 | | - self.client_id.remove(word) |
209 | | - self.client_id = "".join(self.client_id) |
210 | | - self.client_secret = self.client_id |
211 | | - self.client_id = self.api_token |
212 | | - # PKCE Authorization. We will keep the former `client_id` as a fallback / will only be used for non PCKE |
| 166 | + ).decode("utf-8") |
| 167 | + |
| 168 | + # If client_secret not supplied, fall back to client_id (matching original behavior) |
| 169 | + if not self.client_secret and self.client_id: |
| 170 | + self.client_secret = self.client_id |
| 171 | + |
| 172 | + # PKCE Client Authorization. We will keep the former `client_id` as a fallback / will only be used for non PCKE |
213 | 173 | # authorizations. |
214 | 174 | self.client_unique_key = format(random.getrandbits(64), "02x") |
215 | 175 | self.code_verifier = base64.urlsafe_b64encode(os.urandom(32))[:-1].decode( |
|
0 commit comments