From 2c5e33acf60a3e662f96b67f63c3e2de785f4152 Mon Sep 17 00:00:00 2001 From: ashap5 <73000735+ashap5@users.noreply.github.com> Date: Sun, 1 Oct 2023 02:54:44 +0200 Subject: [PATCH 1/5] add jsotpmin js --- jsOTP.min.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 jsOTP.min.js diff --git a/jsOTP.min.js b/jsOTP.min.js new file mode 100644 index 0000000..4296241 --- /dev/null +++ b/jsOTP.min.js @@ -0,0 +1,7 @@ +/* + * File combining + * (1) sha.js by Brian Turek 2008-2013 under BSD license + * (2) and a modified js OTP implementation found on JSFiddle +*/ + +(function(){var r,e;e=class{constructor(r=30,e=6){if(this.expiry=r,this.length=e,this.length>8||this.length<6)throw"Error: invalid code length"}dec2hex(r){return(r<15.5?"0":"")+Math.round(r).toString(16)}hex2dec(r){return parseInt(r,16)}base32tohex(r){var e,n,t,o,h;for("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",e="",t="",o=0;o=r.length&&(r=Array(e+1-r.length).join(n)+r),r}getOtp(r,e=(new Date).getTime()){var n,t,o,h,i,w,d;if(o=this.base32tohex(r),n=Math.round(e/1e3),d=this.leftpad(this.dec2hex(Math.floor(n/this.expiry)),16,"0"),(w=new jsSHA("SHA-1","HEX")).setHMACKey(o,"HEX"),w.update(d),"KEY MUST BE IN BYTE INCREMENTS"===(t=w.getHMAC("HEX")))throw"Error: hex key must be in byte increments";return h=this.hex2dec(t.substring(t.length-1)),i=(i=(this.hex2dec(t.substr(2*h,8))&this.hex2dec("7fffffff"))+"").length>this.length?i.substr(i.length-this.length,this.length):this.leftpad(i,this.length,"0")}},r=class{constructor(r=6){if(this.length=r,this.length>8||this.length<6)throw"Error: invalid code length"}uintToString(r){var e;return e=String.fromCharCode.apply(null,r),decodeURIComponent(escape(e))}getOtp(r,e){var n,t,o,h,i;return(h=new jsSHA("SHA-1","TEXT")).setHMACKey(r,"TEXT"),h.update(this.uintToString(new Uint8Array(this.intToBytes(e)))),n=h.getHMAC("HEX"),i=(127&(t=this.hexToBytes(n))[o=15&t[19]])<<24|(255&t[o+1])<<16|(255&t[o+2])<<8|255&t[o+3],(i+="").substr(i.length-this.length,this.length)}intToBytes(r){var e,n;for(e=[],n=7;n>=0;)e[n]=255&r,r>>=8,--n;return e}hexToBytes(r){var e,n,t;for(n=[],t=0,e=r.length;t>>3,0!=u%2)throw new Error("String of HEX type must be in byte increments");for(o=0;o>>1)+d)>>>2;t.length<=i;)t.push(0);t[i]|=h<<8*(3-w%4)}return{value:t,binLen:4*u+n}}function t(r,e,n){var t,o,h,i,w,d=[];for(d=e||[0],h=(n=n||0)>>>3,o=0;o>>2,d.length<=i&&d.push(0),d[i]|=t<<8*(3-w%4);return{value:d,binLen:8*r.length+n}}function o(r,e,n){var t,o,h,i,w,d,u,a,l=[],s=0;if(l=e||[0],d=(n=n||0)>>>3,-1===r.search(/^[a-zA-Z0-9=+\/]+$/))throw new Error("Invalid character in base-64 string");if(w=r.indexOf("="),r=r.replace(/\=/g,""),-1!==w&&w { + MakeNewAccount().then( + (r) => { + console.log(r) + } + ) + }); + + // Function to update the websites list when the profile is changed function updateWebsitesList() { const selectedProfile = profileDropdown.value; @@ -307,6 +274,7 @@ // Add elements to the profile menu profileMenu.appendChild(profileDropdown); + profileMenu.appendChild(MakeNewAccountButton) profileMenu.appendChild(websitesList); profileMenu.appendChild(startButton); profileMenu.appendChild(closeButton); @@ -321,6 +289,11 @@ // Function to get the profile name from the URL function getProfileName(token) { return JSON.parse(decodeURIComponent(atob(token.split('.')[0]))).CODE + } + async function MakeNewAccount() + { + + } // Show/hide the profile menu when clicking the activate button @@ -340,4 +313,5 @@ document.addEventListener('DOMContentLoaded', () => { createActivateButton(); }); + })(); From 2ed69f0c87fc54e4a5d8d2d6c791cfe33a6bf1f1 Mon Sep 17 00:00:00 2001 From: ashap5 Date: Sun, 1 Oct 2023 20:49:32 +0200 Subject: [PATCH 3/5] Changes by matus --- index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 75b9a20..e7db2d1 100644 --- a/index.js +++ b/index.js @@ -112,13 +112,16 @@ // Create the activate button and profile menu function createActivateButton() { + const MenuDivUpperButtons = document.createElement('div'); + MenuDivUpperButtons.style.display = 'flex'; const activateButton = document.createElement('button'); activateButton.textContent = 'Auto-Trial'; activateButton.style.position = 'fixed'; activateButton.style.top = '10px'; activateButton.style.left = '10px'; activateButton.style.zIndex = '9999'; - document.body.appendChild(activateButton); + document.body.appendChild(MenuDivUpperButtons); + MenuDivUpperButtons.append(activateButton); // Example profiles (you can add more profiles or customize the websites for each profile) const defaultProfiles = { From a28b3a7e1b43874d9aeb7f3fc76180b927aa2973 Mon Sep 17 00:00:00 2001 From: ashap5 Date: Sun, 1 Oct 2023 22:56:10 +0200 Subject: [PATCH 4/5] fast commit --- GetCaptchaTesting.js | 25 +++ index.js | 164 ++++++++++++++- page.html | 463 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 645 insertions(+), 7 deletions(-) create mode 100644 GetCaptchaTesting.js create mode 100644 page.html diff --git a/GetCaptchaTesting.js b/GetCaptchaTesting.js new file mode 100644 index 0000000..6dd237f --- /dev/null +++ b/GetCaptchaTesting.js @@ -0,0 +1,25 @@ +async function GetCaptha() +{ + const GetCapthaPage = await fetch("https://www.digitalcombatsimulator.com/en/auth/?register=yes", { + method: "GET", + headers: { + "Content-Type": "text/html", + } + }); + + let capthawithsid = (await GetCapthaPage.text()).match(/\?captcha_sid=\w+/); + + + let captchaid = capthawithsid[0].replace("?captcha_sid=", ""); + + const CaptchaImageLink = "https://www.digitalcombatsimulator.com/bitrix/tools/captcha.php?captcha_sid=" + captchaid; + + return {captchaid : captchaid, CaptchaImageLink : CaptchaImageLink}; + +} +GetCaptha().then( + (r) => { + console.log(r.captchaid); + console.log(r.CaptchaImageLink); + } +) \ No newline at end of file diff --git a/index.js b/index.js index e7db2d1..7ce4b49 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,6 @@ // @match https://www.digitalcombatsimulator.com/* // @grant none // @run-at document-start -// @require /home/pasha/WebstormProjects/DcsTrialActivator/index.js // ==/UserScript== (function() { 'use strict'; @@ -194,11 +193,12 @@ MakeNewAccountButton.style.marginTop = '5px'; MakeNewAccountButton.addEventListener('click', () => { - MakeNewAccount().then( - (r) => { - console.log(r) - } - ) + // MakeNewAccount().then( + // (r) => { + // console.log(r) + // } + // ) + CreateLoginPasswordWindow() }); @@ -293,10 +293,160 @@ function getProfileName(token) { return JSON.parse(decodeURIComponent(atob(token.split('.')[0]))).CODE } - async function MakeNewAccount() + async function MakeNewAccount(username, password) { + const waitFor = delay => new Promise(resolve => setTimeout(resolve, delay)); + let {mailadress, token} = await GetEmailAdress(); + while (await CheckEmailCount() < 1) { + console.log("Waiting for email"); + await waitFor(3000); + } + console.log("Email received"); + ConfirmAccount().then(r => { + console.log("result" + r); + + //in gui this shows succes + }); + async function GetEmailAdress() { + const GetAvailableDomains = await fetch("https://api.mail.tm/domains", { + method: "GET", + headers: {"Content-Type": "application/json"}, + }); + + let mailadress = Math.random().toString(36).substring(7); + let domain = (await GetAvailableDomains.json())['hydra:member'][0]?.domain; + + if (!domain) { + console.log("No domains available"); + alert("no Domains available (tempmail api error)") + } + + const CreateAccount = await fetch("https://api.mail.tm/accounts", { + method: "POST", + body: JSON.stringify({ + "address": mailadress + "@" + domain, + "password": "test", + }), + headers: {"Content-Type": "application/json"}, + }); + console.log(await CreateAccount.json()); + + const GetToken = await fetch("https://api.mail.tm/token", { + method: "POST", + body: JSON.stringify({ + "address": mailadress + "@" + domain, + "password": "test", + }), + headers: {"Content-Type": "application/json"}, + }); + + + let token = (await GetToken.json())['token']; + return {mailadress : mailadress + "@" + domain, token : token}; + } + + async function CreateAccount() + { + const url = 'https://www.digitalcombatsimulator.com/en/auth/?register=yes'; + + const headers = { + 'Host': 'www.digitalcombatsimulator.com', + 'Cookie': '_gcl_au=1.1.908428613.1696105221; _gid=GA1.2.1802591656.1696105222; _ym_uid=1696105222389662133; _ym_d=1696105222; BX_USER_ID=616410b48b17033705d714859d247b5d; _ga_0PEB8NMGB5=GS1.1.1696113494.2.0.1696113494.60.0.0; _ga=GA1.2.28649852.1696105222; PHPSESSID=1GlSSfAvafvQC7YQJWD3NJnimPLtHrIA; BITRIX_CONVERSION_CONTEXT_s1=%7B%22ID%22%3A3%2C%22EXPIRE%22%3A1696204740%2C%22UNIQUE%22%3A%5B%22conversion_visit_day%22%5D%7D', + 'Content-Length': '318', + 'Cache-Control': 'max-age=0', + 'Sec-Ch-Ua': '"Chromium";v="117", "Not;A=Brand";v="8"', + 'Sec-Ch-Ua-Mobile': '?0', + 'Sec-Ch-Ua-Platform': '"Linux"', + 'Upgrade-Insecure-Requests': '1', + 'Origin': 'https://www.digitalcombatsimulator.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', + 'Sec-Fetch-Site': 'same-origin', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-User': '?1', + 'Sec-Fetch-Dest': 'document', + 'Referer': 'https://www.digitalcombatsimulator.com/en/auth/?register=yes', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US,en;q=0.9', + }; + + const formData = new FormData(); + formData.append('AUTH_FORM', 'Y'); + formData.append('TYPE', 'REGISTRATION'); + formData.append('USER_NAME', 'mike'); + formData.append('USER_LAST_NAME', 'morin'); + formData.append('USER_EMAIL', mailadress); + formData.append('USER_LOGIN', username); + formData.append('USER_PASSWORD', password); + formData.append('USER_CONFIRM_PASSWORD', password); + formData.append('captcha_sid', '070c616980cb7c7c92060bc3342907a0'); // todo get the captcha and show it to the user + formData.append('captcha_word', 'BCK5T'); + formData.append('UF_SUBSCRIBE_NEWSLETTER', '0'); + formData.append('send_account_info', ''); + + const response = await fetch(url, { + method: 'POST', + headers, + body: formData + }); + + console.log('Response:', response); + } + async function CheckEmailCount() + { + const GetEmails = await fetch("https://api.mail.tm/messages", { + method: "GET", + headers: { + "Content-Type": "application/json", + "Authorization" : 'Bearer ' + token, + }, + }); + let emailjson = await GetEmails.json(); + // null check because api sometimes returns null instead of json // todo look into why + if (emailjson === null) { + return "0"; + } + return emailjson['hydra:totalItems']; + } + + async function ConfirmAccount() // todo try to get the message id without this additonial request + { + const GetEmails = await fetch("https://api.mail.tm/messages", { + method: "GET", + headers: { + "Content-Type": "application/json", + "Authorization" : 'Bearer ' + token, + }, + }); + let messageid = (await GetEmails.json())['hydra:member'][0]['id']; + console.log(messageid); + const GetEmail = await fetch("https://api.mail.tm/messages/" + messageid, { + method: "GET", + headers: { + "Content-Type": "application/json", + "Authorization" : 'Bearer ' + token, + }, + }); + let json = await GetEmail.json(); + + const linkMatch = json.text.match(/(https:\/\/www.digitalcombatsimulator.com\/en\/auth\/\?confirm_registration=yes&confirm_user_id=\d+&confirm_code=\w+)/); + + if (linkMatch) { + const url = linkMatch[1]; + console.log("Extracted URL:", url); + const ConfirmAccount = await fetch(url, { + method: "GET", + }); + return (await ConfirmAccount.text()).includes("User registration has been confirmed successfully"); + + } else { + console.log("No link found in the text."); + } + + } } // Show/hide the profile menu when clicking the activate button diff --git a/page.html b/page.html new file mode 100644 index 0000000..70f16dc --- /dev/null +++ b/page.html @@ -0,0 +1,463 @@ + + + + Register + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+

Register

+
+
If your e-mail address is registered in Hotmail/Outlook (@hotmail, @msn, @live, @outlook), you must add our digitalcombatsimulator.com domain to the Safe Senders and Domains List so that the email from this site is never treated as junk.
To do this in Hotmail/Outlook open Options -> Mail -> Junk email -> Safe senders and add domain digitalcombatsimulator.com.
+
+ + + +
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
Attention! A registration confirmation request will be sent to the specified e-mail address.
+
+
+ + +
+
+
+
+
+ + +
+
+
+
The password must contain at least 8 characters, contain Latin uppercase letters (A-Z), contain Latin lowercase letters (a-z), contain digits (0-9).
+
+
+
+ + +
+
+
+
+
+ + CAPTCHA

+
+ +
+
+
+ + +
+
+
+ +
+
+
+ +
+
+
+
+
+ FOLLOW US + +
+
+
+
+ + + + + + + + + +
+
+ + + +
+ + +
+
+ + From 31b3c9cf8356f395b18f613c9477fa0bbbce6cd5 Mon Sep 17 00:00:00 2001 From: ashap5 Date: Sun, 1 Oct 2023 22:56:19 +0200 Subject: [PATCH 5/5] Changes by matus --- index.js | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 7ce4b49..b82af9a 100644 --- a/index.js +++ b/index.js @@ -113,13 +113,15 @@ function createActivateButton() { const MenuDivUpperButtons = document.createElement('div'); MenuDivUpperButtons.style.display = 'flex'; + MenuDivUpperButtons.style.width = '100%'; + MenuDivUpperButtons.style.justifyContent = 'space-between'; // todo should work, but doesn't. const activateButton = document.createElement('button'); activateButton.textContent = 'Auto-Trial'; activateButton.style.position = 'fixed'; activateButton.style.top = '10px'; activateButton.style.left = '10px'; activateButton.style.zIndex = '9999'; - document.body.appendChild(MenuDivUpperButtons); + document.body.appendChild(MenuDivUpperButtons); // myslim ze spravnejsie by bolo append na profileMenu ale nefunguje, mozno fix ale netreba MenuDivUpperButtons.append(activateButton); // Example profiles (you can add more profiles or customize the websites for each profile) @@ -163,6 +165,7 @@ // Function to create the profile menu function createProfileMenu() { profileMenu = document.createElement('div'); + profileMenu.id = 'profileMenu'; profileMenu.style.position = 'fixed'; profileMenu.style.color = 'green' profileMenu.style.top = '50px'; @@ -201,7 +204,32 @@ CreateLoginPasswordWindow() }); - + function CreateLoginPasswordWindow() { + // todo make it work by "unhiding" the window instead of creating it because this way you can just spam the button and break it + // have a login username and login passowrd field in it, centered in the entire page + const LoginPasswordContainerDiv = document.createElement('div'); + document.body.appendChild(LoginPasswordContainerDiv); + LoginPasswordContainerDiv.style.display = 'flex'; + LoginPasswordContainerDiv.style.justifySelf = 'center'; + LoginPasswordContainerDiv.style.width = '20%'; + LoginPasswordContainerDiv.style.height = '20%'; + LoginPasswordContainerDiv.style.zIndex = '10'; + LoginPasswordContainerDiv.style.backgroundColor = 'blue'; + LoginPasswordContainerDiv.id = 'LoginContainer'; + const LoginInput = document.createElement('input'); + LoginInput.type = 'text'; + LoginPasswordContainerDiv.append(LoginInput); + const PasswordInput = document.createElement('input'); + PasswordInput.type = 'password'; + LoginPasswordContainerDiv.append(PasswordInput); + const captchaImg = document.createElement('img'); + captchaImg.id = 'captcha-img'; + captchaImg.style.width = '180px'; + captchaImg.style.height = '40px'; + captchaImg.alt = 'CAPTCHA'; + captchaImg.src = 'SEM SRC CAPTCHA IMG'; //SEM SRC CAPTCHA IMG, nejak asi cez variable ale to ja neviem + LoginPasswordContainerDiv.append(captchaImg); + } // Function to update the websites list when the profile is changed function updateWebsitesList() { const selectedProfile = profileDropdown.value;