From 3f6c823599853d6ee8488977113a8de3ae39bffc Mon Sep 17 00:00:00 2001 From: ririxi Date: Thu, 19 Dec 2024 18:10:51 +0100 Subject: [PATCH] feat: add ability to change cors proxy server --- CustomApps/lyrics-plus/Settings.js | 29 +++++++++++++++++++++++++++++ jsHelper/spicetifyWrapper.js | 16 ++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CustomApps/lyrics-plus/Settings.js b/CustomApps/lyrics-plus/Settings.js index 4d4df0d18c..80109ec889 100644 --- a/CustomApps/lyrics-plus/Settings.js +++ b/CustomApps/lyrics-plus/Settings.js @@ -452,6 +452,22 @@ const ServiceList = ({ itemsList, onListChange = () => {}, onToggle = () => {}, }); }; +const corsProxyTemplate = () => { + const [proxyValue, setProxyValue] = react.useState(localStorage.getItem("spicetify:corsProxyTemplate") || "https://cors-proxy.spicetify.app/{url}"); + + return react.createElement("input", { + placeholder: "CORS Proxy Template", + value: proxyValue, + onChange: (event) => { + const value = event.target.value; + setProxyValue(value); + + if (value === "" || !value) return localStorage.removeItem("spicetify:corsProxyTemplate"); + localStorage.setItem("spicetify:corsProxyTemplate", value); + }, + }); +}; + const OptionList = ({ type, items, onChange }) => { const [itemList, setItemList] = useState(items); const [, forceUpdate] = useState(); @@ -646,6 +662,19 @@ function openConfig() { CONFIG.providers[name].token = value; localStorage.setItem(`${APP_NAME}:provider:${name}:token`, value); }, + }), + react.createElement("h2", null, "CORS Proxy Template"), + react.createElement("span", { + dangerouslySetInnerHTML: { + __html: + "Use this to bypass CORS restrictions. Replace the URL with your cors proxy server of your choice. {url} will be replaced with the request URL.", + }, + }), + react.createElement(corsProxyTemplate), + react.createElement("span", { + dangerouslySetInnerHTML: { + __html: "Spotify will reload its webview after applying. Leave empty to restore default: https://cors-proxy.spicetify.app/{url}", + }, }) ); diff --git a/jsHelper/spicetifyWrapper.js b/jsHelper/spicetifyWrapper.js index 386e64ddd2..ee39422aac 100644 --- a/jsHelper/spicetifyWrapper.js +++ b/jsHelper/spicetifyWrapper.js @@ -352,7 +352,6 @@ window.Spicetify = { const _cosmos = Spicetify.Player.origin?._cosmos ?? Spicetify.Platform?.Registry.resolve(Symbol.for("Cosmos")); - const corsProxyURL = "https://cors-proxy.spicetify.app"; const allowedMethodsMap = { get: "get", post: "post", @@ -374,6 +373,7 @@ window.Spicetify = { return async function (url, body) { const urlObj = new URL(url); + const corsProxyURLTemplate = window.localStorage.getItem("spicetify:corsProxyTemplate") ?? "https://cors-proxy.spicetify.app/{url}"; const isWebAPI = urlObj.hostname === "api.spotify.com"; const isSpClientAPI = urlObj.hostname.includes("spotify.com") && urlObj.hostname.includes("spclient"); const isInternalURL = internalEndpoints.has(urlObj.protocol); @@ -396,10 +396,18 @@ window.Spicetify = { if (body) { if (method === "get") { const params = new URLSearchParams(body); - finalURL += `?${params.toString()}`; + const useSeparator = shouldUseCORSProxy && new URL(finalURL).search.startsWith("?"); + finalURL += `${useSeparator ? "&" : "?"}${params.toString()}`; } else options.body = !Array.isArray(body) && typeof body === "object" ? JSON.stringify(body) : body; } - if (shouldUseCORSProxy) finalURL = `${corsProxyURL}/${finalURL}`; + if (shouldUseCORSProxy) { + finalURL = corsProxyURLTemplate.replace(/{url}/, finalURL); + try { + new URL(finalURL); + } catch { + console.error("[spicetifyWrapper] Invalid CORS Proxy URL template"); + } + } const Authorization = `Bearer ${Spicetify.Platform.AuthorizationAPI.getState().token.accessToken}`; let injectedHeaders = {}; @@ -459,7 +467,7 @@ window.Spicetify = { () => { webpackDidCallback = true; }, - 6 + 12 ); let chunks = Object.entries(require.m);