diff --git a/src/js/Content/Features/Community/FriendsAndGroups/FGroupsManageButton.js b/src/js/Content/Features/Community/FriendsAndGroups/FGroupsManageButton.js index d4e65006b..c260844d7 100644 --- a/src/js/Content/Features/Community/FriendsAndGroups/FGroupsManageButton.js +++ b/src/js/Content/Features/Community/FriendsAndGroups/FGroupsManageButton.js @@ -137,6 +137,6 @@ export default class FGroupsManageButton extends CallbackFeature { "steamids[]": id }; - return RequestData.post(this._endpoint, data, {}, true); + return RequestData.post(this._endpoint, data); } } diff --git a/src/js/Content/Features/Community/Inventory/FQuickSellOptions.js b/src/js/Content/Features/Community/Inventory/FQuickSellOptions.js index 9a95a9aa2..e4d89b583 100644 --- a/src/js/Content/Features/Community/Inventory/FQuickSellOptions.js +++ b/src/js/Content/Features/Community/Inventory/FQuickSellOptions.js @@ -116,7 +116,7 @@ export default class FQuickSellOptions extends CallbackFeature { "price": sellPrice }; - const result = await RequestData.post("https://steamcommunity.com/market/sellitem/", data, {}, true).catch(err => err); + const result = await RequestData.post("https://steamcommunity.com/market/sellitem/", data).catch(err => err); if (!result?.success) { loadingEl.textContent = result?.message ?? Localization.str.error; diff --git a/src/js/Content/Features/Community/Workshop.js b/src/js/Content/Features/Community/Workshop.js index f3a911b6f..e15e2e75a 100644 --- a/src/js/Content/Features/Community/Workshop.js +++ b/src/js/Content/Features/Community/Workshop.js @@ -8,7 +8,7 @@ export default class Workshop { const data = {"sessionid": User.sessionId, appid, id}; - const res = await RequestData.post(`https://steamcommunity.com/sharedfiles/${_method}`, data, {}, true); + const res = await RequestData.post(`https://steamcommunity.com/sharedfiles/${_method}`, data); if (method === "subscribe") { // https://github.com/SteamDatabase/SteamTracking/blob/3ab40a4604426852de8a51c50d963978e9660de4/steamcommunity.com/public/javascript/sharedfiles_functions_logged_in.js#L533 diff --git a/src/js/Content/Features/Store/Common/AddToCart.js b/src/js/Content/Features/Store/Common/AddToCart.js index 4b67bdb43..afb31a4ff 100644 --- a/src/js/Content/Features/Store/Common/AddToCart.js +++ b/src/js/Content/Features/Store/Common/AddToCart.js @@ -30,12 +30,16 @@ export class AddToCart { // Use the form's `action` here because free promotions are submitted to a different endpoint const endpoint = formEl.getAttribute("action"); - const body = new FormData(formEl); + + if (endpoint.includes("freelicense/")) { + this._addFreePromotion(endpoint, formEl, onWishlist, addToCartEl); + return; + } let response; try { - response = await RequestData.post(endpoint, body, {}, "none"); + response = await RequestData.post(endpoint, new FormData(formEl), {}, false); } catch (err) { // Likely network error; response.ok doesn't mean the item was added successfully Page.runInPageContext((errTitle, errDesc, errStr) => { @@ -78,4 +82,49 @@ export class AddToCart { window.location.reload(); } } + + // See https://github.com/SteamDatabase/SteamTracking/blob/14f2138651e27bae760d067c490948c1197e5e61/store.steampowered.com/public/javascript/main.js#L1419 + static async _addFreePromotion(endpoint, formEl, onWishlist, addToCartEl) { + + const _endpoint = endpoint.endsWith("/") ? endpoint : `${endpoint}/`; + const body = new FormData(formEl); + const id = body.get("subid") || body.get("bundleid"); + + // Yield back to Steam if required fields are missing + if (!id || !body.has("sessionid")) { + formEl.submit(); + } + + const data = { + "ajax": true, + "sessionid": body.get("sessionid") + }; + + const response = await RequestData.post(`${_endpoint}${id}`, data).catch(err => console.error(err)); + + // This endpoint returns an empty array on success + if (!Array.isArray(response)) { + Page.runInPageContext((errTitle, errDesc, errStr) => { + window.SteamFacade.showAlertDialog(errTitle, errStr ? `${errDesc}

${errStr}` : errDesc); + }, + [ + Localization.str.error, + Localization.str.addtocart_dialog.error_desc_freepromo, + response ? `Error code: ${response.purchaseresultdetail}` : undefined + ]); + + return; + } + + if (onWishlist) { + addToCartEl.setAttribute("href", "https://store.steampowered.com/account/licenses/"); + addToCartEl.querySelector("span").textContent = Localization.str.in_account; + + Page.runInPageContext(() => { + window.SteamFacade.dynamicStoreInvalidateCache(); + }); + } else { + window.location.reload(); + } + } } diff --git a/src/js/Content/Features/Store/RegisterKey/FMultiProductKeys.js b/src/js/Content/Features/Store/RegisterKey/FMultiProductKeys.js index a241767ef..1867ad212 100644 --- a/src/js/Content/Features/Store/RegisterKey/FMultiProductKeys.js +++ b/src/js/Content/Features/Store/RegisterKey/FMultiProductKeys.js @@ -90,18 +90,17 @@ export default class FMultiProductKeys extends Feature { "product_key": currentKey }; - const request = RequestData.post("https://store.steampowered.com/account/ajaxregisterkey", data).then(response => { - const _data = JSON.parse(response); + const request = RequestData.post("https://store.steampowered.com/account/ajaxregisterkey", data).then(result => { const attempted = currentKey; let message = Localization.str.register.default; - if (_data.success === 1) { + if (result.success === 1) { document.querySelector(`#attempt_${attempted}_icon img`).setAttribute("src", ExtensionResources.getURL("img/sr/okay.png")); - if (_data.purchase_receipt_info.line_items.length > 0) { - document.querySelector(`#attempt_${attempted}_result`).textContent = Localization.str.register.success.replace("__gamename__", _data.purchase_receipt_info.line_items[0].line_item_description); + if (result.purchase_receipt_info.line_items.length > 0) { + document.querySelector(`#attempt_${attempted}_result`).textContent = Localization.str.register.success.replace("__gamename__", result.purchase_receipt_info.line_items[0].line_item_description); document.querySelector(`#attempt_${attempted}_result`).style.display = "block"; } } else { - switch (_data.purchase_result_details) { + switch (result.purchase_result_details) { case 9: message = Localization.str.register.owned; break; case 13: message = Localization.str.register.notavail; break; case 14: message = Localization.str.register.invalid; break; diff --git a/src/js/Content/Modules/RequestData.js b/src/js/Content/Modules/RequestData.js index f31864c9b..703af1056 100644 --- a/src/js/Content/Modules/RequestData.js +++ b/src/js/Content/Modules/RequestData.js @@ -30,27 +30,22 @@ class RequestData { ProgressBar.finishRequest(); - return responseType === "none" ? response : response[responseType](); + return await response[responseType](); } - static post(url, data, settings = {}, returnJSON = false) { + static async post(url, data, settings = {}, returnJSON = true) { const _settings = { - ...settings, "method": "POST", - "body": new URLSearchParams(data) + "body": new URLSearchParams(data), + "credentials": "include", + "headers": {"origin": window.location.origin}, + "referrer": window.location.origin + window.location.pathname, + ...settings }; - let _responseType; - if (typeof returnJSON === "string") { - _responseType = returnJSON; - } else if (returnJSON) { - _responseType = "json"; - } else { - _responseType = "text"; - } - - return RequestData.getHttp(url, _settings, _responseType); + const response = await RequestData._fetchFn(url, _settings); + return returnJSON ? await response.json() : response; } static getJson(url, settings) { diff --git a/src/localization/en.json b/src/localization/en.json index 7d62c0952..711925ae2 100644 --- a/src/localization/en.json +++ b/src/localization/en.json @@ -2,6 +2,7 @@ "delete_comment_prompt": "Are you sure you want to delete this comment?", "addtocart_dialog": { "error_desc": "An error occurred while adding your item to Cart.", + "error_desc_freepromo": "An error occurred while adding this item to your account.", "title": "Added to Shopping Cart", "desc": "The item was added to your Shopping Cart.", "checkout": "No, checkout", @@ -35,6 +36,7 @@ }, "cart": "Cart", "in_cart": "In Cart", + "in_account": "In Account", "steamid_of_user": "__user__'s SteamID", "copied": "Copied to your clipboard!", "view_steamid": "View SteamID",