From 374892d0f950665c373926ea4facf7cf795a0ef4 Mon Sep 17 00:00:00 2001
From: candela97 <54083835+candela97@users.noreply.github.com>
Date: Sun, 10 Sep 2023 04:04:04 +0800
Subject: [PATCH] Improve no-redirect handling for free promotions
---
.../FriendsAndGroups/FGroupsManageButton.js | 2 +-
.../Community/Inventory/FQuickSellOptions.js | 2 +-
src/js/Content/Features/Community/Workshop.js | 2 +-
.../Features/Store/Common/AddToCart.js | 53 ++++++++++++++++++-
.../Store/RegisterKey/FMultiProductKeys.js | 11 ++--
src/js/Content/Modules/RequestData.js | 23 ++++----
src/localization/en.json | 2 +
7 files changed, 70 insertions(+), 25 deletions(-)
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",