-
-
Save ReedGraf/e2cda3d4bcca35a155805f9aab2c97df to your computer and use it in GitHub Desktop.
| // ==UserScript== | |
| // @name qobuz auth token login | |
| // @namespace io.github.uhwot.qbztoken | |
| // @match https://play.qobuz.com/* | |
| // @grant none | |
| // @version 1.1 | |
| // @author Updated by Reed Graf | |
| // @description allows logging in via auth tokens on qobuz | |
| // @homepageURL https://gist.github.com/ReedGraf/e2cda3d4bcca35a155805f9aab2c97df | |
| // @downloadURL https://gist.github.com/ReedGraf/e2cda3d4bcca35a155805f9aab2c97df/raw/qbztoken.user.js | |
| // @icon https://play.qobuz.com/resources/favicon/favicon-96x96.png | |
| // @run-at document-start | |
| // ==/UserScript== | |
| /* | |
| ORIGINAL BY UH WOT - https://gist.github.com/uhwot/8250904f3e4bfbad684c5ec26943e082 | |
| UPDATED BY REED GRAF | |
| */ | |
| function waitForElm(selector) { | |
| return new Promise(resolve => { | |
| if (document.querySelector(selector)) { | |
| return resolve(document.querySelector(selector)); | |
| } | |
| const observer = new MutationObserver(mutations => { | |
| if (document.querySelector(selector)) { | |
| resolve(document.querySelector(selector)); | |
| observer.disconnect(); | |
| } | |
| }); | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| }); | |
| } | |
| function ass() { | |
| // Create Input Field | |
| if (window.location.pathname === "/login") { | |
| waitForElm("div.LoginPage__content").then((_) => { | |
| const element = document.querySelector("div.LoginPage__content") | |
| // Create Container | |
| const div = document.createElement("div") | |
| div.setAttribute("style", "width: 100%") | |
| // Create Labels and Inputs | |
| const p = document.createElement("p") | |
| p.innerText = "ID:" | |
| p.setAttribute("style", "color: #FFFFFF") | |
| const input = document.createElement("input") | |
| input.setAttribute("class", "SearchBar__input") | |
| input.setAttribute("type", "password") | |
| input.setAttribute("style", "padding: 0px 10px 0px 10px; width: 100%; height: 50px") | |
| const p2 = document.createElement("p") | |
| p2.innerText = "Token:" | |
| p2.setAttribute("style", "color: #FFFFFF") | |
| const input2 = document.createElement("input") | |
| input2.setAttribute("class", "SearchBar__input") | |
| input2.setAttribute("type", "password") | |
| input2.setAttribute("style", "padding: 0px 10px 0px 10px; width: 100%; height: 50px") | |
| // Listen for Enter Key | |
| div.addEventListener("keypress", function(event) { | |
| if (event.key === "Enter") { | |
| if (input.value !== "" && input2.value !== "") { | |
| event.preventDefault() | |
| localStorage.setItem("app_id", input.value) | |
| localStorage.setItem("token", input2.value) | |
| window.location = "https://play.qobuz.com/featured?code_autorisation=!token!" | |
| } else { | |
| const errorbox = document.createElement("div") | |
| errorbox.innerHTML = '<span style="color: red;">Error! Try Again.</span>' | |
| div.appendChild(errorbox) | |
| } | |
| } | |
| }) | |
| // Append all new elements | |
| div.appendChild(p) | |
| div.appendChild(input) | |
| div.appendChild(p2) | |
| div.appendChild(input2) | |
| element.appendChild(div) | |
| }) | |
| } | |
| } | |
| // Local Storage Magic | |
| const token = localStorage.getItem("token") | |
| const app_id = localStorage.getItem("app_id") | |
| if (window.location == "https://play.qobuz.com/featured?code_autorisation=!token!" && token !== null) { | |
| localStorage.removeItem("token") | |
| localStorage.removeItem("app_id") | |
| window.fetch = (function (fetch) { | |
| return async function (url, init) { | |
| if (url.startsWith("https://www.qobuz.com/api.json/0.2/oauth/callback?code=")) { | |
| window.fetch = fetch | |
| return new Response(JSON.stringify({ | |
| token: token, | |
| user_id: app_id | |
| })) | |
| } | |
| return await fetch(url, init) | |
| } | |
| })(window.fetch); | |
| } | |
| window.addEventListener('load', function() { | |
| ass() | |
| const replaceState = window.history.replaceState | |
| Object.defineProperty(window.history, 'replaceState', { | |
| get(_) {return function() { | |
| replaceState.apply(window.history, arguments) | |
| ass() | |
| }}, | |
| set(_) {}, | |
| }); | |
| const pushState = window.history.pushState | |
| Object.defineProperty(window.history, 'pushState', { | |
| get(_) {return function() { | |
| pushState.apply(window.history, arguments) | |
| ass() | |
| }}, | |
| set(_) {}, | |
| }); | |
| }, false) |
Damn, finally someone is working on this <3 Thanks
I've realized that the script still works perfectly fine with only a token. You don't even need a USER_ID for it to work. So, I'm not sure why or how to integrate app_id and app_secret since it still works assuming you have a valid token from an account. I extracted a token from my account and it works flawlessly. I should note that I can't find any reference to an app_secret or app_id in the network activity or local storage from Firefox's dev tools. I might be missing something so let me know if I have.
Also, fyi, check Firehawk's telegram if you still want to use an account with a token instead of the new stuff...
Quick Update: I was able to find references to app_secret and app_id in the main Javascript file Qobuz uses called bundle.js. I'll keep you updated...
unfortunately, it doesn't work anymore :)
Can it be fixed?
@Spicytin @CrossyAtom46 Gotcha, later today I'll look into it. I suspect that the info given, (
app_idand theapp_secret) is different from what I used which was labeled in the browser's local storage astokenanduser_id. Thanks for the feedback! :)