├── LICENSE.md
├── README.md
├── images
├── ico128.png
├── ico16.png
├── ico32.png
├── ico48.png
└── ico64.png
├── manifest.json
├── options.html
├── options.js
├── right-click-steam-activator.js
└── right_click_steam_activator_browser_extension_icon.png
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Roman Davydov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #  Right-click Steam Activator
2 |
3 | 
4 | 
5 | 
6 | 
7 | 
8 |
9 | Browser extension that allows to select/mark a Steam key and quickly activate it through the right-click context menu.
10 |
11 |
12 |
13 | You need to be logged in to the Steam store!
14 |
15 | ## Super powered key detection
16 | New super powered engine that can detect a Steam key in the selected line even if it has junk data before and after the key!
17 |
18 | ## How to Use
19 | 1. Select a Steam key on the web page as a text
20 | 2. Right-click and select 'Activate: XXX'
21 |
22 | ## Options
23 | Extension has an options page where you can set your own `sessionid` and `steamLoginSecure` values. Warning! This will change your cookies in the browser!
24 | It is useful when you want to quickly transfer your Steam account between browsers without the annoying login procedure.
25 |
26 | ## How to Install
27 | https://addons.mozilla.org/en-US/firefox/addon/right-click-steam-activator/
28 |
29 | OR
30 | 1. Clone this repo
31 | 2. Go to chrome extensions `chrome://extensions`
32 | 3. Enable developer mode
33 | 4. Click on load unpacked extension and select this cloned repo
34 |
--------------------------------------------------------------------------------
/images/ico128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdavydov/right-click-steam-activator/7cd2dee5928b44ae61c0396e3ec595b4b60f8060/images/ico128.png
--------------------------------------------------------------------------------
/images/ico16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdavydov/right-click-steam-activator/7cd2dee5928b44ae61c0396e3ec595b4b60f8060/images/ico16.png
--------------------------------------------------------------------------------
/images/ico32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdavydov/right-click-steam-activator/7cd2dee5928b44ae61c0396e3ec595b4b60f8060/images/ico32.png
--------------------------------------------------------------------------------
/images/ico48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdavydov/right-click-steam-activator/7cd2dee5928b44ae61c0396e3ec595b4b60f8060/images/ico48.png
--------------------------------------------------------------------------------
/images/ico64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdavydov/right-click-steam-activator/7cd2dee5928b44ae61c0396e3ec595b4b60f8060/images/ico64.png
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 2,
3 | "name": "Right-click Steam Activator",
4 | "description": "Use the right-click menu to activate selected Steam key",
5 | "version": "2.2",
6 | "permissions": [
7 | "contextMenus",
8 | "cookies",
9 | "https://store.steampowered.com/",
10 | "storage",
11 | "notifications"
12 | ],
13 | "background": {
14 | "scripts": [
15 | "right-click-steam-activator.js"
16 | ]
17 | },
18 | "minimum_chrome_version": "88",
19 | "icons": {
20 | "16": "images/ico16.png",
21 | "32": "images/ico32.png",
22 | "48": "images/ico48.png",
23 | "64": "images/ico64.png",
24 | "128": "images/ico128.png"
25 | },
26 | "options_ui": {
27 | "page": "options.html"
28 | },
29 | "action": {
30 | "default_icon": "images/ico32.png"
31 | },
32 | "host_permissions": [
33 | "http://*/",
34 | "https://*/"
35 | ]
36 | }
--------------------------------------------------------------------------------
/options.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Steam Key Activator Options
7 |
86 |
87 |
88 |
89 | Options
90 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/options.js:
--------------------------------------------------------------------------------
1 | const optionsForm = document.getElementById('options-form');
2 | const sessionidInput = document.getElementById('sessionid-input');
3 | const steamLoginSecureInput = document.getElementById('steamLoginSecure-input');
4 | const infoBox = document.getElementById('info-box');
5 |
6 | optionsForm.addEventListener('submit', (event) => {
7 | event.preventDefault();
8 |
9 | const sessionid = sessionidInput.value;
10 | const steamLoginSecure = steamLoginSecureInput.value;
11 |
12 | if (sessionid && steamLoginSecure) {
13 | chrome.storage.sync.set({ sessionid, steamLoginSecure }, () => {
14 | if (sessionid) {
15 | chrome.cookies.set({
16 | url: "https://store.steampowered.com/",
17 | name: "sessionid",
18 | value: sessionid,
19 | secure: true,
20 | httpOnly: true
21 | }, () => {
22 | console.log("sessionid cookie value is set");
23 | });
24 | }
25 |
26 | if (steamLoginSecure) {
27 | chrome.cookies.set({
28 | url: "https://store.steampowered.com/",
29 | name: "steamLoginSecure",
30 | value: steamLoginSecure,
31 | secure: true,
32 | httpOnly: true
33 | }, () => {
34 | console.log("steamLoginSecure cookie value is set");
35 | });
36 | }
37 |
38 | // Update existing info box
39 | infoBox.classList.remove('error');
40 | infoBox.classList.add('success');
41 | infoBox.textContent = 'Cookie values are set for the extension and for the Steam store.';
42 | });
43 | } else {
44 | chrome.storage.sync.set({ sessionid: "", steamLoginSecure: "" }, () => {
45 | sessionidInput.value = '';
46 | steamLoginSecureInput.value = '';
47 | // Update existing info box
48 | infoBox.classList.remove('success');
49 | infoBox.classList.add('error');
50 | infoBox.textContent = 'Cookie values are cleared for the extension. We\'ll get them from the Steam store.';
51 | });
52 | }
53 | });
54 |
55 | chrome.storage.sync.get(['sessionid', 'steamLoginSecure'], ({ sessionid, steamLoginSecure }) => {
56 | sessionidInput.value = sessionid || '';
57 | steamLoginSecureInput.value = steamLoginSecure || '';
58 | });
59 |
--------------------------------------------------------------------------------
/right-click-steam-activator.js:
--------------------------------------------------------------------------------
1 | function notify(message) {
2 | console.log("Notifying user: ", message);
3 | chrome.notifications.create({
4 | "type": "basic",
5 | "iconUrl": "images/ico128.png",
6 | // "iconUrl": browser.extension.getURL("images/ico128.png"),
7 | "title": "Right-click Steam Activator",
8 | "message": message
9 | });
10 | }
11 |
12 | function activatekey(info) {
13 | // const _re = new RegExp('^[0-9A-Z]{4,7}-[0-9A-Z]{4,7}-[0-9A-Z]{4,7}(?:(?:-[0-9A-Z]{4,7})?(?:-[0-9A-Z]{4,7}))?$', 'i');
14 |
15 | // /^[a-zA-Z0-9]{4,6}\-[a-zA-Z0-9]{4,6}\-[a-zA-Z0-9]{4,6}$/.test(key)
16 |
17 | // Declare a regular expression that matches a string of 4-5 alphanumeric characters,
18 | // followed by a hyphen and another string of 4-5 alphanumeric characters, repeated
19 | // 2-4 times. This pattern is case-insensitive.
20 | const regex = /[0-9A-Z]{4,5}(?:-[0-9A-Z]{4,5}){2,4}/i;
21 | // Trim leading and trailing whitespace from the selected text and attempt to
22 | // match it against the regular expression.
23 | // ?. is an optional chaining operator to safely access the first element of the resulting array.
24 | // If there is no match, it will return undefined instead of throwing an error.
25 | const _key = info.selectionText.trim().match(regex)?.[0];
26 |
27 | if (_key) {
28 | console.log("Activating Steam key: ", _key);
29 |
30 | // Retrieve sessionid from storage or default to empty string using promises
31 | const sessionidPromise = new Promise((resolve, reject) => {
32 | chrome.storage.sync.get({ sessionid: "" }, function ({ sessionid }) {
33 | if (sessionid) {
34 | console.log("Using user-supplied sessionid cookie:", sessionid);
35 | resolve(sessionid);
36 | } else {
37 | console.log("User-supplied sessionid cookie was not found in the storage. Getting it from the Steam store.");
38 | // Retrieve sessionid cookie from https://store.steampowered.com/
39 | chrome.cookies.get(
40 | { url: "https://store.steampowered.com/", name: "sessionid" },
41 | function (cookie) {
42 | if (cookie) {
43 | const sessionid = cookie.value;
44 | console.log("Retrieved sessionid cookie from https://store.steampowered.com/:", sessionid);
45 | resolve(sessionid);
46 | } else {
47 | const error = new Error("sessionid cookie was not found!");
48 | notify(error);
49 | reject(error);
50 | }
51 | }
52 | );
53 | }
54 | });
55 | });
56 |
57 | // Use the sessionid value after it has been retrieved from storage or cookies
58 | sessionidPromise.then((sessionid) => {
59 | // Create form data
60 | const formData = new FormData();
61 | formData.append('product_key', _key);
62 | formData.append('sessionid', sessionid);
63 |
64 | // Send POST request to activate key
65 | fetch('https://store.steampowered.com/account/ajaxregisterkey/', {
66 | method: 'POST',
67 | credentials: 'include',
68 | body: formData
69 | })
70 | .then(response => response.json())
71 | .catch(error => {
72 | notify("Failed to parse response as JSON. Most likely you are not logged in to the Steam store.");
73 | console.error("Failed to parse response as JSON: " + error);
74 | throw error;
75 | })
76 | .then(data => {
77 | switch (data.success) {
78 | case 1:
79 | notify("Activated: " + data?.purchase_receipt_info?.line_items[0]?.line_item_description);
80 | return;
81 | case 21:
82 | notify("ERROR! Not a valid sessionid: " + sessionid);
83 | return;
84 | case 2:
85 | console.log("'success' is 2. Key is not activated.")
86 | break;
87 | default:
88 | notify("success: " + data?.success);
89 | break;
90 | }
91 |
92 | // const resultDetail = data.purchase_receipt_info.result_detail;
93 |
94 | switch (data?.purchase_result_details) {
95 | case 53:
96 | notify("Temporary ban from Steam. It should vanish in 45-60 minutes.");
97 | return;
98 | case 9:
99 | notify("Already own: " + data?.purchase_receipt_info?.line_items[0]?.line_item_description);
100 | return;
101 | case 14:
102 | notify("Invalid key: " + _key);
103 | return;
104 | case 15:
105 | notify("Somebody already activated this code for: " + data?.purchase_receipt_info?.line_items[0]?.line_item_description);
106 | return;
107 | case 13:
108 | notify("Regional restrictions: " + data?.purchase_receipt_info?.line_items[0]?.line_item_description);
109 | return;
110 | case 24:
111 | notify("Missing base game: " + data?.purchase_receipt_info?.line_items[0]?.line_item_description);
112 | return;
113 | case 36:
114 | notify("Need a PS3?"); // ?
115 | return;
116 | case 50:
117 | notify("This is the recharge code!"); // ?
118 | return;
119 | default:
120 | notify("purchase_result_details: " + data?.purchase_result_details);
121 | break;
122 | }
123 | })
124 | .catch(error => {
125 | // if (!data) return;
126 | console.error("Failed to parse data from response's JSON: " + error);
127 | throw error;
128 | });
129 | });
130 | } else {
131 | notify("Not a valid Steam key.");
132 | }
133 | }
134 |
135 | chrome.contextMenus.removeAll(function () {
136 | chrome.contextMenus.create({
137 | id: "ActSteamKey",
138 | title: "Activate: %s",
139 | contexts: ["selection"]
140 | });
141 | });
142 |
143 | chrome.contextMenus.onClicked.addListener(function (info) {
144 | if (info.menuItemId == "ActSteamKey") {
145 | activatekey(info);
146 | }
147 | });
148 |
149 | /* const steamKeyRedeemResponses = {
150 | 0: 'NoDetail',
151 | 1: 'AVSFailure',
152 | 2: 'InsufficientFunds',
153 | 3: 'ContactSupport',
154 | 4: 'Timeout',
155 | 5: 'InvalidPackage',
156 | 6: 'InvalidPaymentMethod',
157 | 7: 'InvalidData',
158 | 8: 'OthersInProgress',
159 | 9: 'AlreadyPurchased',
160 | 10: 'WrongPrice',
161 | 11: 'FraudCheckFailed',
162 | 12: 'CancelledByUser',
163 | 13: 'RestrictedCountry',
164 | 14: 'BadActivationCode',
165 | 15: 'DuplicateActivationCode',
166 | 16: 'UseOtherPaymentMethod',
167 | 17: 'UseOtherFunctionSource',
168 | 18: 'InvalidShippingAddress',
169 | 19: 'RegionNotSupported',
170 | 20: 'AcctIsBlocked',
171 | 21: 'AcctNotVerified',
172 | 22: 'InvalidAccount',
173 | 23: 'StoreBillingCountryMismatch',
174 | 24: 'DoesNotOwnRequiredApp',
175 | 25: 'CanceledByNewTransaction',
176 | 26: 'ForceCanceledPending',
177 | 27: 'FailCurrencyTransProvider',
178 | 28: 'FailedCyberCafe',
179 | 29: 'NeedsPreApproval',
180 | 30: 'PreApprovalDenied',
181 | 31: 'WalletCurrencyMismatch',
182 | 32: 'EmailNotValidated',
183 | 33: 'ExpiredCard',
184 | 34: 'TransactionExpired',
185 | 35: 'WouldExceedMaxWallet',
186 | 36: 'MustLoginPS3AppForPurchase',
187 | 37: 'CannotShipToPOBox',
188 | 38: 'InsufficientInventory',
189 | 39: 'CannotGiftShippedGoods',
190 | 40: 'CannotShipInternationally',
191 | 41: 'BillingAgreementCancelled',
192 | 42: 'InvalidCoupon',
193 | 43: 'ExpiredCoupon',
194 | 44: 'AccountLocked',
195 | 45: 'OtherAbortableInProgress',
196 | 46: 'ExceededSteamLimit',
197 | 47: 'OverlappingPackagesInCart',
198 | 48: 'NoWallet',
199 | 49: 'NoCachedPaymentMethod',
200 | 50: 'CannotRedeemCodeFromClient',
201 | 51: 'PurchaseAmountNoSupportedByProvider',
202 | 52: 'OverlappingPackagesInPendingTransaction',
203 | 53: 'RateLimited',
204 | 54: 'OwnsExcludedApp',
205 | 55: 'CreditCardBinMismatchesType',
206 | 56: 'CartValueTooHigh',
207 | 57: 'BillingAgreementAlreadyExists',
208 | 58: 'POSACodeNotActivated',
209 | 59: 'CannotShipToCountry',
210 | 60: 'HungTransactionCancelled',
211 | 61: 'PaypalInternalError',
212 | 62: 'UnknownGlobalCollectError',
213 | 63: 'InvalidTaxAddress',
214 | 64: 'PhysicalProductLimitExceeded',
215 | 65: 'PurchaseCannotBeReplayed',
216 | 66: 'DelayedCompletion',
217 | 67: 'BundleTypeCannotBeGifted',
218 | }; */
--------------------------------------------------------------------------------
/right_click_steam_activator_browser_extension_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdavydov/right-click-steam-activator/7cd2dee5928b44ae61c0396e3ec595b4b60f8060/right_click_steam_activator_browser_extension_icon.png
--------------------------------------------------------------------------------