From 326191482864182a3f24db30aa7a6d9ae85a1057 Mon Sep 17 00:00:00 2001 From: Amin Mahmoudi Date: Thu, 9 Feb 2023 14:11:39 +0330 Subject: [PATCH] Rewrite and Work with the last version of twitch and solve kasada (x-kpsdk-cd, x-kpsdk-ct ) https://github.com/masterking32/twitch-account-creator/issues/21 https://github.com/masterking32/twitch-account-creator/issues/24 --- README.MD | 21 +- config.js | 8 +- follow.js | 185 ------------- main.js | 664 ++++++++++++++++++++++++++++------------------ package-lock.json | 210 +++++++++------ package.json | 19 +- proxy.txt | 3 +- trash-mail.js | 7 - unfollow.js | 151 ----------- useragents.txt | 4 + utils.js | 100 ++++++- 11 files changed, 665 insertions(+), 707 deletions(-) delete mode 100644 follow.js delete mode 100644 unfollow.js create mode 100644 useragents.txt diff --git a/README.MD b/README.MD index 1f9fa02..161cda0 100644 --- a/README.MD +++ b/README.MD @@ -1,15 +1,12 @@ [![GitHub stars](https://img.shields.io/github/stars/masterking32/twitch-account-creator.svg)](https://github.com/masterking32/twitch-account-creator/stargazers) [![GitHub issues](https://img.shields.io/github/issues/masterking32/twitch-account-creator.svg)](https://github.com/masterking32/twitch-account-creator/issues) -[![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine/) # A NodeJS Bot to create Twitch accounts. -# ❌❌❌ This repo is deprecated for now. ❌❌❌ +# TESTED AND WORKS (0/FEB/2023) ✔️ This project will create new accounts and verify the accounts using the email address. ✔️ -✔️ Twitch follow bot added. (08/21/2022) ✔️ - *❌ Do not abuse this project, this project is made for testing only, and you cannot use it according to Twitch rules. ❌* **⭐ If you liked the project, feel free to give it a shining star. ⭐** @@ -25,11 +22,9 @@ ✅ Get an API key from: -**🟢 [2Captcha to resolve Twitch FunCaptcha](https://2captcha.com?from=8210547)**. (Required Balance/Recommended) - -**🔴 OR 🔴** +**🟢 [1) Create an account on this website, Add some funds, and then add `Pay-Per-Usage solving API Key` to your config file.](https://dashboard.capsolver.com/passport/register?inviteCode=Lpullbhszlum)** (Required Balance) -**🟢 [Anti-Captcha to resolve Twitch FunCaptcha](http://getcaptchasolution.com/svlzmusv0h)**. (Required Balance) +**🟢 [2) Create an account and buy some `http` proxies and put proxies in `proxy.txt` file.](https://www.webshare.io/?referral_code=2ghmowzxmc26)** (Required Balance) ## 💻 Installation @@ -37,18 +32,12 @@ - Clone the repo and do `npm install` ### 🟣 Account creator: -- Put your `Anti-Captcha` **or** `2Captcha` API key in `config.js` +- Put your `YOUR Solver API KEY` API key in `config.js` +- Put your `Proxies` API key in `config.js` - Run the project (`node main.js`). -### 🟣 Follow Bot: - -- Run the Account creator. -- Run the `node follow.js`. - ## 🔧 Optional -You can use a proxy list to bypass limits. - You can get a free or paid proxy list from [this website](https://www.webshare.io/?referral_code=2ghmowzxmc26). Put your proxies in the proxy.txt file. diff --git a/config.js b/config.js index d6a1299..b1fe465 100644 --- a/config.js +++ b/config.js @@ -1,10 +1,8 @@ var config = {}; -// Get API Key from Anti-Captcha or 2Captcha -config.API_KEY_2CAPTCHA = 'YOUR 2captcha.com API KEY'; // RECOMMENDED / BETTER SOLVING -config.API_KEY_AntiCaptcha = 'YOUR anti-captcha.com API KEY'; +// config.CapSolverKey = 'YOUR CapSolver API KEY'; // READ README file in github! +config.CapSolverKey = 'YOUR CapSolver API KEY'; config.RandomUsername = false; // If you want to make new accounts with random usernames, change this to true. -config.UseProxy = false; // If you have proxy list, you can use it. (Put your proxy list in the proxies.txt file) - +config.proxyType = 'http'; module.exports = config; \ No newline at end of file diff --git a/follow.js b/follow.js deleted file mode 100644 index 15ae81d..0000000 --- a/follow.js +++ /dev/null @@ -1,185 +0,0 @@ -const fs = require('fs'); -const axios = require('axios'); -const readline = require("readline"); -var config = require('./config'); -const randomUseragent = require('random-useragent'); - -const outFilePathTokens = './results/tokens.txt'; - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}); - - -let tokens = fs.readFileSync(outFilePathTokens).toString().replace(/\r/g, '').split("\n"); - -if(tokens.length == 0) -{ - console.log("No tokens found! Please run the token generator first! (main.js)"); - process.exit(); -} - -let proxies = []; - -if(config.UseProxy == true) -{ - proxies = fs.readFileSync('proxy.txt').toString().replace(/\r/g, '').split("\n"); -} - -function getProxy() -{ - if(config.UseProxy == false || proxies.length == 0) - { - return {}; - } - - let proxy = proxies[Math.floor(Math.random() * proxies.length)]; - let proxy_arry = proxy.split(':'); - if(proxy_arry.length == 2) - { - return { - proxy: { - host: proxy_arry[0], - port: proxy_arry[1] - } - }; - } else if(proxy_arry.length == 4) { - return { - proxy: { - host: proxy_arry[0], - port: proxy_arry[1], - auth: { - username: proxy_arry[2], - password: proxy_arry[3] - } - } - }; - } else { - console.log("Proxy is not valid!"); - return {}; - } -} - -async function StartRequest(uname) { - try{ - await FollowAccount(uname); - } catch(e) { - console.log(e); - } -} - -const GetUserID = async (uname) => { - json = {"operationName": "ChannelShell", - "variables": { - "login": uname - }, - "extensions": { - "persistedQuery": { - "version": 1, - "sha256Hash": "580ab410bcd0c1ad194224957ae2241e5d252b2c5173d8e0cce9d32d5bb14efe" - } - } - } - - headers = { - headers : {'Client-ID': 'kimne78kx3ncx6brgo4mv6wki5h1ko'} - } - - response = await axios.post('https://gql.twitch.tv/gql', json, headers); - if(response.data.data.userOrError != undefined && response.data.data.userOrError.id != undefined) - { - return response.data.data.userOrError.id; - } else { - return false; - } -} -const integrityToken = async (accessToken, userAgent, DeviceID, options) => { - options.headers = { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Accept-Language": "en-US", - 'Client-Id': 'kimne78kx3ncx6brgo4mv6wki5h1ko', - Connection: "keep-alive", - "Content-Type": "text/plain; charset=UTF-8", - "Device-ID": DeviceID, - Origin: "https://www.twitch.tv", - Referer: "https://www.twitch.tv/", - Authorization: "OAuth " + accessToken, - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-site", - "Sec-GPC": "1", - "User-Agent": userAgent, - }; - - return await axios.post('https://gql.twitch.tv/integrity', {}, options); -}; - -const FollowChannel = async (channel_ID, accessToken) => { - console.log("Follow sent ..."); - let options = getProxy(); - const userAgent = randomUseragent.getRandom(); - const DeviceID = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - let integrity_resp = await integrityToken(accessToken, userAgent, DeviceID, options); - if(integrity_resp.data != null && integrity_resp.data.token != null) { - const integrity = integrity_resp.data.token; - let proxy = options; - await sendGQLRequest(proxy, accessToken, integrity, userAgent, DeviceID, `[{"operationName":"FollowButton_FollowUser","variables":{"input":{"disableNotifications":false,"targetID":"${channel_ID}"}},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"800e7346bdf7e5278a3c1d3f21b2b56e2639928f86815677a7126b093b2fdd08"}}}]`); - } -} - -const sendGQLRequest = async (current_porxy, accessToken, integrity, userAgent, DeviceID, query) => { - let options = current_porxy; - options.headers = { - 'Client-Integrity': integrity, - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Accept-Language": "en-US", - 'Client-Id': 'kimne78kx3ncx6brgo4mv6wki5h1ko', - Connection: "keep-alive", - "Content-Type": "text/plain; charset=UTF-8", - "Device-ID": DeviceID, - Origin: "https://www.twitch.tv", - Referer: "https://www.twitch.tv/", - Authorization: "OAuth " + accessToken, - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-site", - "Sec-GPC": "1", - "User-Agent": userAgent, - }; - - return await axios.post('https://gql.twitch.tv/gql', query, options); -}; - -const FollowAccount = async (uname) => { - userID = await GetUserID(uname); - if(userID == false) - { - console.log("Username not valid."); - GettingUsername(); - return false; - } - - for (const token of tokens) { - if(tokens == undefined ||tokens == null || tokens == "") - { - GettingUsername(); - return false; - } - - await FollowChannel(userID, token); - } - - console.log("All following done!"); - GettingUsername(); -} - -const GettingUsername = async () => { - rl.question("Username?\n", function(uname) { - StartRequest(uname); - }); -}; - -GettingUsername(); \ No newline at end of file diff --git a/main.js b/main.js index b110c86..6a9d22a 100644 --- a/main.js +++ b/main.js @@ -1,227 +1,418 @@ const fs = require('fs'); -const axios = require('axios'); -const {generateRandomCredentials, generateUsername} = require('./utils'); +const axios = require('axios-https-proxy-fix'); +const {generateRandomRegisterData, generateUsername, getUserAgent, getProxy, MakeRandomID, TwitchClinetID} = require('./utils'); const {getEmail, waitFirstMail} = require('./trash-mail'); -const randomUseragent = require('random-useragent'); -const readline = require("readline"); -const ac = require("@antiadmin/anticaptchaofficial"); var config = require('./config'); - -const CLIENT_ID = 'kimne78kx3ncx6brgo4mv6wki5h1ko'; -const funcaptchaSignupPublicKey = 'E5554D43-23CC-1982-971D-6A2262A2CA24'; -const outFilePathAll = './results/results.txt'; -const outFilePathUsers = './results/users.txt'; -const outFilePathPass = './results/pass.txt'; -const outFilePathTokens = './results/tokens.txt'; +const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); -if(config.API_KEY_AntiCaptcha != 'YOUR anti-captcha.com API KEY' && config.API_KEY_AntiCaptcha != '') { - ac.setAPIKey(config.API_KEY_AntiCaptcha); - ac.settings.funcaptchaApiJSSubdomain = 'twitch-api.arkoselabs.com'; - ac.setSoftId(1034); -} +const outFilePathAll = './results/results.txt'; +const outFilePathUsers = './results/users.txt'; +const outFilePathPass = './results/pass.txt'; +const outFilePathTokens = './results/tokens.txt'; -let proxies = []; let currennt_porxy = {}; +let current_useragent = ''; +let KasdaResponse = {}; -if(config.UseProxy == true) -{ - proxies = fs.readFileSync('proxy.txt').toString().replace(/\r/g, '').split("\n"); -} - -function getProxy() -{ - if(config.UseProxy == false || proxies.length == 0) - { - return {}; - } +const KasdaResolver = async () => { + try { - let proxy = proxies[Math.floor(Math.random() * proxies.length)]; - let proxy_arry = proxy.split(':'); - if(proxy_arry.length == 2) - { - return { - proxy: { - host: proxy_arry[0], - port: proxy_arry[1] - } - }; - } else if(proxy_arry.length == 4) { - return { - proxy: { - host: proxy_arry[0], - port: proxy_arry[1], - auth: { - username: proxy_arry[2], - password: proxy_arry[3] - } + let response = await axios.post('https://api.capsolver.com/kasada/invoke', { + "clientKey": config.CapSolverKey, + "appId": 'B278567A-C94E-457E-B419-F1D6A5D1AA6D', + "task": { + "type": "AntiKasadaTask", + "pageURL": "https://gql.twitch.tv/", //Required + "proxy": currennt_porxy.proxy.href, //Required + "cd": true, //Optional + "onlyCD": false, //Optional + "userAgent": current_useragent //Optional } - }; - } else { - console.log("Proxy is not valid!"); - return {}; + }, {headers: { 'content-type': 'text/json' }}); + if(response.data.success) + { + current_useragent = response.data.solution['user-agent']; + KasdaResponse = {}; + KasdaResponse.original = response.data.solution; + KasdaResponse.useragent = response.data.solution['user-agent']; + KasdaResponse.kpsdkcd = response.data.solution['x-kpsdk-cd']; + KasdaResponse.kpsdkct = response.data.solution['x-kpsdk-ct']; + } + return KasdaResponse; + } catch (e) { + // console.log(e); } -} + return false; +}; -const API_2Captcha_Validate = async (requestID) => { - await new Promise(r => setTimeout(r, 2000)); - let URL = "http://2captcha.com/res.php?key=" + config.API_KEY_2CAPTCHA + "&action=get&id=" + requestID + "&json=1"; - response = await axios.get(URL); - if(response.data.status == 0) - { - if(response.data.request == 'ERROR_CAPTCHA_UNSOLVABLE') +const integrityGetToken = async (kpsdkcd, kpsdkct, cookies) => { + try { + let response = await axios.post('https://passport.twitch.tv/integrity', {}, { + proxy: currennt_porxy.proxy, + headers: { + 'User-Agent': current_useragent, + 'Accept': '*/*', + 'Accept-Language': 'en-US,en;q=0.5', + 'Accept-Encoding': 'gzip, deflate, br', + 'Referer': 'https://www.twitch.tv/', + 'x-kpsdk-ct': kpsdkct, + 'x-kpsdk-cd': kpsdkcd, + 'Origin': 'https://www.twitch.tv', + 'DNT': 1, + 'Connection': 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site', + 'Content-Length': 0, + } + }); + if(response.data.token) { - console.log('ERROR_CAPTCHA_UNSOLVABLE'); - return false; + response.headers['set-cookie'].forEach(element => { + let p1 = element.split(';')[0]; + let p2 = p1.split('='); + cookies[p2[0]] = p2[1]; + }); + + let result = []; + result['token'] = response.data.token; + result['cookies'] = cookies; + return result; } - return await API_2Captcha_Validate(requestID); - } else { - // console.log(response.data); - return response.data.request; + } catch (e) { + console.log(e); } + + return false; }; -const API_2Captcha_Request = async () => { - let URL = "http://2captcha.com/in.php?key=" + config.API_KEY_2CAPTCHA + "&method=funcaptcha&publickey=" + funcaptchaSignupPublicKey + "&surl=https://twitch-api.arkoselabs.com&pageurl=https://www.twitch.tv/signup&soft_id=3432&json=1"; - response = await axios.get(URL); - try{ - if(response.data.status == 1) { - console.log("Request sent to the 2captcha wait a bit, Request ID: " + response.data.request); - console.log("Wating to reslove ... (15 - 300 sec)"); - let validate_resp = await API_2Captcha_Validate(response.data.request); - if (validate_resp == false) { - console.log("Starting new funcaptcha."); - return await API_2Captcha_Request(); - } - return validate_resp; - } else { - console.log("Something is wrong with 2Captcha, Check your 2Captcha API Key."); - return await API_2Captcha_Request(); +const RegisterFinal = async (cookies, PostParams) => { + try { + + let options = currennt_porxy; + let cookies_string = ''; + for (var key in cookies) { + cookies_string = cookies_string + key + "=" + cookies[key] + "; "; } + + options.headers = { + 'User-Agent': current_useragent, + 'Accept': '*/*', + 'Accept-Language': 'en-US,en;q=0.5', + 'Accept-Encoding': 'gzip, deflate, br', + 'Referer': 'https://www.twitch.tv/', + 'Content-Type': 'text/plain;charset=UTF-8', + 'Origin': 'https://www.twitch.tv', + 'DNT': 1, + 'Connection': 'keep-alive', + 'Cookie': cookies_string, + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site' + }; + + let response = await axios.post('https://passport.twitch.tv/protected_register', PostParams, options); + + return response.data; } catch (e) { - console.log("Something is wrong with 2Captcha, Check your 2Captcha API Key!" + e); - return await API_2Captcha_Request(); + return e.response.data; } -} +}; + +const GetTwitchCookies = async () => { + try { + let options = currennt_porxy; + // delete currennt_porxy.proxy.href; + options.headers = { + 'User-Agent': current_useragent, + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', + 'Accept-Language': 'en-US,en;q=0.5', + 'Accept-Encoding': 'gzip, deflate, br', + 'DNT': 1, + 'Connection': 'keep-alive', + 'Upgrade-Insecure-Requests': 1, + 'Sec-Fetch-Dest': 'document', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-Site': 'none', + 'Sec-Fetch-User': '?1', + }; + let response = await axios.get('https://twitch.tv', options); -// function replaceAll(str, find, replace) { -// return str.replace(new RegExp(find, 'g'), replace); -// } - -const solveArkoseCaptcha = async () => { - let captcha = null; - ac.solveFunCaptchaProxyless('https://www.twitch.tv/signup', funcaptchaSignupPublicKey) - .then(token => { - // console.log('response: '+token); - // token = replaceAll(token, 'funcaptcha.com', 'client-api.arkoselabs.com'); - // token = replaceAll(token, 'funcaptcha.com', 'twitch-api.arkoselabs.com'); - // token = token.replace('|pk=','|lang=en|pk='); - // token = replaceAll(token, 'ap-southeast-1', 'eu-west-1'); - captcha = token; - }) - .catch(error => {console.log('test received error '+error); captcha = false;}); - - while(captcha == null) { - await new Promise(r => setTimeout(r, 100)); + let cookies = []; + response.headers['set-cookie'].forEach(element => { + let p1 = element.split(';')[0]; + let p2 = p1.split('='); + cookies[p2[0]] = p2[1]; + }); + return cookies; + } catch (e) { + console.log(e); } - return captcha; + return false; }; -const generatePayload = async ({username, password, birthday}, email, captchaToken) => { - return { - username, - password, - email, - birthday, - include_verification_code: true, - client_id: CLIENT_ID, - arkose: {token: captchaToken}, - }; +const verifyEmail = async (ClientID, XDeviceId, ClientVersion, ClientSessionId, accessToken, ClientIntegrity, code, userId, email) => { + let query = `[{"operationName":"ValidateVerificationCode","variables":{"input":{"code":"${code}","key":"${userId}","address":"${email}"}},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"05eba55c37ee4eff4dae260850dd6703d99cfde8b8ec99bc97a67e584ae9ec31"}}}]`; + try { + + let options = currennt_porxy; + + options.headers = { + 'User-Agent': current_useragent, + Accept: 'application/json', + 'Accept-Language': 'en-US', + 'Accept-Encoding': 'identity', + Referer: 'https://www.twitch.tv/', + 'Client-Id': ClientID, + 'X-Device-Id': XDeviceId, + 'Client-Version': ClientVersion, + 'Client-Session': ClientSessionId, + Authorization: "OAuth " + accessToken, + 'Client-Integrity': ClientIntegrity, + 'Content-Type': 'text/plain;charset=UTF-8', + Origin: 'https://www.twitch.tv', + DNT: 1, + Connection: 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site' + }; + + let response = await axios.post('https://gql.twitch.tv/gql#origin=twilight', query, options); + return response.data; + } catch (e) { + console.log(e); + return {}; + } }; -const registerAccount = async payload => { +const FollowGames = async (ClientID, XDeviceId, ClientVersion, ClientSessionId, accessToken, ClientIntegrity) => { + let query = `[{"operationName":"OnboardingFollowGame","variables":{"id":"509658"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"4cbe32f65d5272a46515f0eb05b257d99d03fef995a526cde1c88ff72337e94f"}}},{"operationName":"OnboardingFollowGame","variables":{"id":"21779"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"4cbe32f65d5272a46515f0eb05b257d99d03fef995a526cde1c88ff72337e94f"}}},{"operationName":"OnboardingFollowGame","variables":{"id":"27471"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"4cbe32f65d5272a46515f0eb05b257d99d03fef995a526cde1c88ff72337e94f"}}},{"operationName":"OnboardingFollowGame","variables":{"id":"516575"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"4cbe32f65d5272a46515f0eb05b257d99d03fef995a526cde1c88ff72337e94f"}}},{"operationName":"OnboardingFollowUser","variables":{"id":"814157119"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"539461eda09076f0493d22d92f9684be6d0a7d5a7d450a76d3a4a3bac173fec7"}}},{"operationName":"OnboardingFollowUser","variables":{"id":"31545223"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"539461eda09076f0493d22d92f9684be6d0a7d5a7d450a76d3a4a3bac173fec7"}}}]`; try { - // console.log(payload); - currennt_porxy = getProxy(); - const response = await axios.post('https://passport.twitch.tv/register', payload, currennt_porxy); - const headers = response.headers; - let output = {}; - output.userid = response.data.userID; - output.access_token = response.data.access_token; - return output; + + let options = currennt_porxy; + + options.headers = { + 'User-Agent': current_useragent, + Accept: 'application/json', + 'Accept-Language': 'en-US', + 'Accept-Encoding': 'identity', + Referer: 'https://www.twitch.tv/', + 'Client-Id': ClientID, + 'X-Device-Id': XDeviceId, + 'Client-Version': ClientVersion, + 'Client-Session': ClientSessionId, + Authorization: "OAuth " + accessToken, + 'Client-Integrity': ClientIntegrity, + 'Content-Type': 'text/plain;charset=UTF-8', + Origin: 'https://www.twitch.tv', + DNT: 1, + Connection: 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site' + }; + + let response = await axios.post('https://gql.twitch.tv/gql#origin=twilight', query, options); + return response.data; } catch (e) { - console.log(e.response.data.error); - if(e.response.data.error == 'Please complete the CAPTCHA correctly.') { - return 'captcha'; + console.log(e); + return {}; + } +}; + +const PublicIntegrityGetToken = async (TwitchClinetID, XDeviceId, ClientRequestId, ClientSessionId, ClientVersion, kpsdkct, kpsdkcd, accesstoken) => { + try { + + let options = currennt_porxy; + options.headers = { + 'User-Agent': current_useragent, + Accept: 'application/json', + 'Accept-Language': 'en-US', + 'Accept-Encoding': 'identity', + Authorization: "OAuth " + accesstoken, + 'Referer': 'https://www.twitch.tv/', + 'Client-Id': TwitchClinetID, + 'X-Device-Id': XDeviceId, + 'Client-Request-Id': ClientRequestId, + 'Client-Session-Id': ClientSessionId, + 'Client-Version': ClientVersion, + 'x-kpsdk-ct': kpsdkct, + 'x-kpsdk-cd': kpsdkcd, + 'Origin': 'https://www.twitch.tv', + 'DNT': 1, + 'Connection': 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site', + 'Content-Length': 0, + }; + + let response = await axios.post('https://gql.twitch.tv/integrity', {}, options); + if(response.data.token) { + cookies = ''; + response.headers['set-cookie'].forEach(element => { + let p1 = element.split(';')[0]; + cookies = cookies + p1 + '; '; + }); + + let result = []; + result['token'] = response.data.token; + result['cookies'] = cookies; + return result; } + } catch (e) { + console.log(e); + } + + return false; +}; +const IntegrityOption = async () => { + try { + + let options = currennt_porxy; + options.headers = { + 'User-Agent': current_useragent, + 'Accept': '*/*', + 'Accept-Language': 'en-US,en;q=0.5', + 'Accept-Encoding': 'gzip, deflate, br', + 'Access-Control-Request-Method': 'POST', + 'Access-Control-Request-Headers': 'x-kpsdk-cd,x-kpsdk-ct', + 'Referer': 'https://www.twitch.tv/', + 'Origin': 'https://www.twitch.tv', + 'DNT': 1, + 'Connection': 'keep-alive', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site' + }; + + await axios.options('https://passport.twitch.tv/integrity', options); + return true; + } catch (e) { return false; } }; -async function CaptchaAndRegister(credentials, email, userAgent) { - console.log('Solving captcha'); - let captchaToken = ''; - if(config.API_KEY_2CAPTCHA != 'YOUR 2captcha.com API KEY' && config.API_KEY_2CAPTCHA != '') { - console.log("Using 2Captcha."); - captchaToken = await API_2Captcha_Request(); - } else if(config.API_KEY_AntiCaptcha != 'YOUR anti-captcha.com API KEY' && config.API_KEY_AntiCaptcha != '') { - console.log('Using anti-captcha.com'); - captchaToken = await solveArkoseCaptcha(); - } else { - console.log("Please set your anti-captcha.com API KEY or 2Captcha API KEY."); - return false; +async function StartCreate(uname) { + currennt_porxy = getProxy(config.proxyType); + current_useragent = getUserAgent(); + const email = await getEmail(uname); + let register_post_data = generateRandomRegisterData(uname, email); + console.log('\x1b[32m--------------------------------------\x1b[37m'); + console.log('\x1b[32m------------ Account Info ------------\x1b[37m'); + console.log('\x1b[32m--------------------------------------\x1b[37m'); + console.log("\x1b[32mUsername: " + register_post_data.username + "\x1b[37m"); + console.log("\x1b[32mPassword: " + register_post_data.password + "\x1b[37m"); + console.log("\x1b[32memail: " + email); + console.log("\x1b[32mBirthday: " + register_post_data.birthday.year + "/" + register_post_data.birthday.month + "/" + register_post_data.birthday.day) + "\x1b[37m"; + console.log('\x1b[33m--------------------------------------\x1b[37m'); + console.log('\x1b[33m------- Start creating account -------\x1b[37m'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + console.log('\x1b[37m 1) Getting Twitch cookies!'); + let cookies = await GetTwitchCookies(); + if(cookies === false) { + console.log('\x1b[37m Unable to get twitch cookies!'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + return; + } + console.log('\x1b[37m 2) Getting Kasada code ...'); + let kasada = await KasdaResolver(); + if(kasada == false) + { + console.log('\x1b[37m Unable to solve Kasada!'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + return; + } + console.log('\x1b[37m 3) Getting local integrity token ...'); + await IntegrityOption(); + let integrityData = await integrityGetToken(KasdaResponse.kpsdkcd, KasdaResponse.kpsdkct, cookies); + if(integrityData['token'] == false) + { + console.log('\x1b[37m Unable to get register token!'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + return; + } + + console.log('\x1b[37m 4) Creating account ...'); + register_post_data.integrity_token = integrityData['token']; + let protected_register = await RegisterFinal(integrityData['cookies'], register_post_data); + if("error" in protected_register) + { + console.log('\x1b[31m ' + protected_register.error); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + return; } - console.log('Generating payload'); - const payload = await generatePayload(credentials, email, captchaToken); - console.log('Captcha found, registering account ...'); - const registerData = await registerAccount(payload); - if(registerData === 'captcha') + if(!("access_token" in protected_register && "userID" in protected_register)){ + + console.log('\x1b[31m Something is wrong!!!'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + } + + let userID = protected_register.userID; + let access_token = protected_register.access_token; + console.log("\x1b[32mAccount Created!\x1b[37m"); + console.log('\x1b[32mUserID: ' + userID + ' AccessToken: ' + access_token + "\x1b[37m"); + + console.log('\x1b[37m 5) Waiting for verification email ...'); + const verifyCode = await waitFirstMail(register_post_data.username); + console.log('Verify Code:' + verifyCode); + + console.log('\x1b[37m 6) Getting Kasada code ...'); + let kasada2 = await KasdaResolver(); + if(kasada2 == false) { - console.log("Try resolve captcha again"); - return await CaptchaAndRegister(credentials, email, userAgent) + console.log('\x1b[37m Unable to solve Kasada!'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + return; } - return registerData; -} -async function StartCreate(uname) { - const credentials = generateRandomCredentials(uname); - const userAgent = randomUseragent.getRandom(); - const DeviceID = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - console.log("Username: " + credentials.username + " Password:" + credentials.password + " BDay: " + credentials.birthday.year + "/" + + credentials.birthday.month + "/"+ credentials.birthday.day); - console.log('Getting email'); - const email = await getEmail(credentials.username); - const registerData = await CaptchaAndRegister(credentials, email, userAgent); - if(registerData == false) + let ClientID = TwitchClinetID; + let ClientSessionId = MakeRandomID(16).toLowerCase(); + let XDeviceId = cookies['unique_id']; + let ClientVersion = '3040e141-5964-4d72-b67d-e73c1cf355b5'; + let ClientRequestID = MakeRandomID(32); + + console.log('\x1b[37m 7) Getting public integrity token ...'); + let PublicInter = await PublicIntegrityGetToken(ClientID, XDeviceId, ClientRequestID, ClientSessionId, ClientVersion, KasdaResponse.kpsdkct, KasdaResponse.kpsdkcd, access_token) + + console.log('\x1b[37m 8) Try to verify the account ...'); + let verifyEmailResponse = await verifyEmail(ClientID, XDeviceId, ClientVersion, ClientSessionId, access_token, PublicInter['token'], verifyCode, userID, email) + + console.log('\x1b[33m--------------------------------------\x1b[37m'); + if(verifyEmailResponse[0].data.validateVerificationCode.request.status == 'VERIFIED') { - return false; + await saveResult(register_post_data.username, register_post_data.password, register_post_data.email, userID, access_token); + console.log("\x1b[32mAccount verified and saved!\x1b[37m"); } + console.log('\x1b[33m--------------------------------------\x1b[37m'); + console.log('\x1b[33m 9) Following Games...'); + ClientRequestID = MakeRandomID(32); - const userId = registerData.userid; - const accessToken = registerData.access_token; - console.log('Getting integrity token'); - const integrity_resp = await integrityToken(accessToken, userAgent, DeviceID); - if(integrity_resp.data != null && integrity_resp.data.token != null) + console.log('\x1b[37m 9.1) Getting Kasada code ...'); + let kasada3 = await KasdaResolver(); + if(kasada3 == false) { - const integrity = integrity_resp.data.token; - console.log('Wait verification mail'); - const verifyCode = await waitFirstMail(credentials.username); - console.log('Verify email, Verify Code:' + verifyCode); - await verifyEmail(accessToken, userId, email, verifyCode, integrity, userAgent, DeviceID); - console.log('Follow Games ...'); - await followChannel(accessToken, integrity, userAgent, DeviceID); - console.log('Done'); - await saveResult(credentials.username, credentials.password, email, userId, accessToken); - } else { - console.log("Error to getting integrity (Account created but the account is not verified)"); + console.log('\x1b[37m Unable to solve Kasada!'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + return; } + + console.log('\x1b[37m 9.2) Getting public integrity token ...'); + let PublicInter2 = await PublicIntegrityGetToken(ClientID, XDeviceId, ClientRequestID, ClientSessionId, ClientVersion, KasdaResponse.kpsdkct, KasdaResponse.kpsdkcd, access_token); + await FollowGames(ClientID, XDeviceId, ClientVersion, ClientSessionId, access_token, PublicInter2['token']); + console.log('\x1b[33m--------------------------------------\x1b[37m'); + console.log('\x1b[33m Account is ready!\x1b[37m'); + console.log('\x1b[33m--------------------------------------\x1b[37m'); } async function CreateNewAccount(uname) @@ -233,16 +424,55 @@ async function CreateNewAccount(uname) GettingUsername = async () => { if(config.RandomUsername == true) { let uname = generateUsername(); - console.log('Username: ' + uname); + console.log('Random username: ' + uname); await CreateNewAccount(uname); } else { - rl.question("Username?\n", function(uname) { + rl.question("Please choose a username:\n", function(uname) { CreateNewAccount(uname) }); } }; -GettingUsername(); +StartProgram = async () => { + console.log('\x1b[31m---------------------------------------\x1b[37m'); + console.log('\x1b[31m---------------------------------------\x1b[37m'); + console.log('\x1b[31m---------------------------------------\x1b[37m'); + console.log('\x1b[31m| MasterkinG32 Twitch Account Creator |\x1b[37m'); + console.log('\x1b[31m---------------------------------------\x1b[37m'); + console.log('\x1b[31m---------------------------------------\x1b[37m'); + console.log('\x1b[31m---------------------------------------\x1b[37m'); + if(config.CapSolverKey == 'YOUR CapSolver API KEY') { + console.log('\x1b[35mYour captcha solver API token (READ DOCUMENT TO KNOW HOW TO GET IT):\x1b[37m'); + it = rl[Symbol.asyncIterator](); + let cpsl = await it.next(); + config.CapSolverKey = cpsl.value; + } + + console.log('\x1b[35mCreate accounts with random Username[y/yes]:\x1b[37m'); + it = rl[Symbol.asyncIterator](); + let rdu = await it.next(); + let rdus = rdu.value; + if(rdus.toLowerCase() == 'y' || rdus.toLowerCase() == 'yes') + { + config.RandomUsername = true; + } else { + config.RandomUsername = false; + } + + console.log('\x1b[35mProxy type in proxy.txt [http/https/socks5/socks5]:\x1b[37m'); + it = rl[Symbol.asyncIterator](); + let proxy_type = await it.next(); + let proxy_typev = proxy_type.value; + if(proxy_typev.toLowerCase() == 'http' || proxy_typev.toLowerCase() == 'https' || proxy_typev.toLowerCase() == 'socks' || proxy_typev.toLowerCase() == 'socks5') + { + config.proxyType = proxy_typev.toLowerCase(); + } + + console.log('\x1b[33m---------------------------------------\x1b[37m'); + GettingUsername(); +} + +StartProgram(); async function saveResult(username, password, email, userid, token) { if (!fs.existsSync(outFilePathAll)) @@ -281,82 +511,4 @@ async function saveResult(username, password, email, userid, token) { if (err) throw err; console.log("Data Saved."); }); -}; - -module.exports.validateAuthToken = async authToken => { - const {status} = await axios.get('https://id.twitch.tv/oauth2/validate', { - headers: { - Authorization: `OAuth ${authToken}`, - }, - validateStatus: status => status === 401, - }); - return status === 401; -}; - -const followChannel = async (accessToken, integrity, userAgent, DeviceID) => { - await sendGQLRequest(accessToken, integrity, userAgent, DeviceID, `[{"data":{"followGame":{"game":{"id":"509658","__typename":"Game"},"__typename":"FollowGamePayload"}},"extensions":{"durationMilliseconds":37,"operationName":"OnboardingFollowGame","requestID":"01GDA7VVY8GF8FXTH06P5113MY"}}]`); - await sendGQLRequest(accessToken, integrity, userAgent, DeviceID, `[{"operationName":"FollowButton_FollowUser","variables":{"input":{"disableNotifications":false,"targetID":"814157119"}},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"800e7346bdf7e5278a3c1d3f21b2b56e2639928f86815677a7126b093b2fdd08"}}}]`); -} - -const verifyEmail = async (accessToken, userId, email, code, integrity, userAgent, DeviceID) => { - const response = await sendGQLRequest(accessToken, integrity, userAgent, DeviceID, `[{"operationName":"ValidateVerificationCode","variables":{"input":{"code":"${code}","key":"${userId}","address":"${email}"}},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"05eba55c37ee4eff4dae260850dd6703d99cfde8b8ec99bc97a67e584ae9ec31"}}}]`); - const response_data = response.data; - - if(response_data[0].data.validateVerificationCode !== undefined) { - const validateVerificationCode = response_data[0].data.validateVerificationCode; - if (validateVerificationCode.request.status == 'VERIFIED') { - console.log("Account verified"); - } else { - console.log("Account not verified"); - } - } -}; - -const integrityToken = async (accessToken, userAgent, DeviceID) => { - let options = currennt_porxy; - options.headers = { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Accept-Language": "en-US", - 'Client-Id': CLIENT_ID, - Connection: "keep-alive", - "Content-Type": "text/plain; charset=UTF-8", - "Device-ID": DeviceID, - Origin: "https://www.twitch.tv", - Referer: "https://www.twitch.tv/", - Authorization: "OAuth " + accessToken, - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-site", - "Sec-GPC": "1", - "User-Agent": userAgent, - }; - - return await axios.post('https://gql.twitch.tv/integrity', {}, options); -}; - -const sendGQLRequest = async (accessToken, integrity, userAgent, DeviceID, query) => { - let options = currennt_porxy; - options.headers = { - 'Client-Id': CLIENT_ID, - 'Authorization': `OAuth ${accessToken}`, - 'Client-Integrity': integrity, - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Accept-Language": "en-US", - 'Client-Id': CLIENT_ID, - Connection: "keep-alive", - "Content-Type": "text/plain; charset=UTF-8", - "Device-ID": DeviceID, - Origin: "https://www.twitch.tv", - Referer: "https://www.twitch.tv/", - Authorization: "OAuth " + accessToken, - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-site", - "Sec-GPC": "1", - "User-Agent": userAgent, - }; - - return await axios.post('https://gql.twitch.tv/gql', query, options); -}; +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 11f7ab3..62c8c8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,31 +5,14 @@ "packages": { "": { "dependencies": { - "@antiadmin/anticaptchaofficial": "^1.0.24", "axios": "^0.27.2", + "axios-https-proxy-fix": "^0.17.1", "fs": "^0.0.1-security", "generate-password": "^1.7.0", - "random-useragent": "^0.5.0", "readline": "^1.3.0", "username-generator": "^1.1.0" } }, - "node_modules/@antiadmin/anticaptchaofficial": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/@antiadmin/anticaptchaofficial/-/anticaptchaofficial-1.0.24.tgz", - "integrity": "sha512-omDpPvyNGjxV0EBVSQ1tT/gIu/JxChFGtjc+SmliicJddcWPg79Wt45AtfnC1k5EAONIBlU18HW1cQb3f5o95A==", - "dependencies": { - "axios": "^0.21.1" - } - }, - "node_modules/@antiadmin/anticaptchaofficial/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -44,6 +27,47 @@ "form-data": "^4.0.0" } }, + "node_modules/axios-https-proxy-fix": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/axios-https-proxy-fix/-/axios-https-proxy-fix-0.17.1.tgz", + "integrity": "sha512-ZsIVzZEndyNHQXMphMeyZi6AmwfxhyHqZIXmqpfA/Lea7P3DoPCzwnCVgvIVTJVlSONkIaGIunOO8oVI5d35UA==", + "dependencies": { + "follow-redirects": "^1.2.5", + "https-proxy-agent": "^2.1.1", + "is-buffer": "^1.1.5" + } + }, + "node_modules/axios-https-proxy-fix/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/axios-https-proxy-fix/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/axios-https-proxy-fix/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -63,10 +87,23 @@ "node": ">=0.4.0" } }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", @@ -105,10 +142,10 @@ "resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.0.tgz", "integrity": "sha512-WPCtlfy0jexf7W5IbwxGUgpIDvsZIohbI2DAq2Q6TSlKKis+G4GT9sxvPxrZUGL8kP6WUXMWNqYnxY6DDKAdFA==" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "node_modules/mime-db": { "version": "1.52.0", @@ -129,24 +166,10 @@ "node": ">= 0.6" } }, - "node_modules/random-seed": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/random-seed/-/random-seed-0.3.0.tgz", - "integrity": "sha512-y13xtn3kcTlLub3HKWXxJNeC2qK4mB59evwZ5EkeRlolx+Bp2ztF7LbcZmyCnOqlHQrLnfuNbi1sVmm9lPDlDA==", - "dependencies": { - "json-stringify-safe": "^5.0.1" - }, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/random-useragent": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/random-useragent/-/random-useragent-0.5.0.tgz", - "integrity": "sha512-FUMkqVdZeoSff5tErNL3FFGYXElDWZ1bEuedhm5u9MdCFwANriJWbHvDRYrLTOzp/fBsBGu5J1cWtDgifa97aQ==", - "dependencies": { - "random-seed": "^0.3.0" - } + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/readline": { "version": "1.3.0", @@ -160,24 +183,6 @@ } }, "dependencies": { - "@antiadmin/anticaptchaofficial": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/@antiadmin/anticaptchaofficial/-/anticaptchaofficial-1.0.24.tgz", - "integrity": "sha512-omDpPvyNGjxV0EBVSQ1tT/gIu/JxChFGtjc+SmliicJddcWPg79Wt45AtfnC1k5EAONIBlU18HW1cQb3f5o95A==", - "requires": { - "axios": "^0.21.1" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -192,6 +197,43 @@ "form-data": "^4.0.0" } }, + "axios-https-proxy-fix": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/axios-https-proxy-fix/-/axios-https-proxy-fix-0.17.1.tgz", + "integrity": "sha512-ZsIVzZEndyNHQXMphMeyZi6AmwfxhyHqZIXmqpfA/Lea7P3DoPCzwnCVgvIVTJVlSONkIaGIunOO8oVI5d35UA==", + "requires": { + "follow-redirects": "^1.2.5", + "https-proxy-agent": "^2.1.1", + "is-buffer": "^1.1.5" + }, + "dependencies": { + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + } + } + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -205,10 +247,23 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "requires": { + "es6-promise": "^4.0.3" + } + }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "form-data": { "version": "4.0.0", @@ -230,10 +285,10 @@ "resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.0.tgz", "integrity": "sha512-WPCtlfy0jexf7W5IbwxGUgpIDvsZIohbI2DAq2Q6TSlKKis+G4GT9sxvPxrZUGL8kP6WUXMWNqYnxY6DDKAdFA==" }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "mime-db": { "version": "1.52.0", @@ -248,21 +303,10 @@ "mime-db": "1.52.0" } }, - "random-seed": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/random-seed/-/random-seed-0.3.0.tgz", - "integrity": "sha512-y13xtn3kcTlLub3HKWXxJNeC2qK4mB59evwZ5EkeRlolx+Bp2ztF7LbcZmyCnOqlHQrLnfuNbi1sVmm9lPDlDA==", - "requires": { - "json-stringify-safe": "^5.0.1" - } - }, - "random-useragent": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/random-useragent/-/random-useragent-0.5.0.tgz", - "integrity": "sha512-FUMkqVdZeoSff5tErNL3FFGYXElDWZ1bEuedhm5u9MdCFwANriJWbHvDRYrLTOzp/fBsBGu5J1cWtDgifa97aQ==", - "requires": { - "random-seed": "^0.3.0" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "readline": { "version": "1.3.0", diff --git a/package.json b/package.json index c07ff31..90df723 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,25 @@ { + "name" : "twitch-account-creator", + "version" : "1.0", + "description" : "Twitch Account Creator", + "main" : "main.js", + "author" : "MasterkinG32", + "pkg" : { + "scripts" : [ + "./config.js", + "./trash-mail.js", + "./utils.js" + ], + "assets" : [ + "./node_modules/*" + ] + }, + "license" : "ISC", "dependencies": { - "@antiadmin/anticaptchaofficial": "^1.0.24", "axios": "^0.27.2", + "axios-https-proxy-fix": "^0.17.1", "fs": "^0.0.1-security", "generate-password": "^1.7.0", - "random-useragent": "^0.5.0", "readline": "^1.3.0", "username-generator": "^1.1.0" } diff --git a/proxy.txt b/proxy.txt index f7de1d8..a0be416 100644 --- a/proxy.txt +++ b/proxy.txt @@ -1 +1,2 @@ -YOUR PROXIES \ No newline at end of file +IP:PORT:USER:PASS +Read document. \ No newline at end of file diff --git a/trash-mail.js b/trash-mail.js index 09a871a..f6aa687 100644 --- a/trash-mail.js +++ b/trash-mail.js @@ -12,13 +12,6 @@ module.exports.getAllMails = async username => { return response.data; }; -module.exports.getMailHTMLContent = async (login, mailId) => { - const {body} = await axios.get('https://tm.in-ulm.de/mail.php', { - params: {search: login, nr: mailId}, - }); - return body; -}; - module.exports.waitFirstMail = name => { return new Promise(async resolve => { const check = async () => { diff --git a/unfollow.js b/unfollow.js deleted file mode 100644 index 2f47902..0000000 --- a/unfollow.js +++ /dev/null @@ -1,151 +0,0 @@ -const fs = require('fs'); -const axios = require('axios'); -const readline = require("readline"); -var config = require('./config'); - -const outFilePathTokens = './results/tokens.txt'; - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}); - - -let tokens = fs.readFileSync(outFilePathTokens).toString().replace(/\r/g, '').split("\n"); - -if(tokens.length == 0) -{ - console.log("No tokens found! Please run the token generator first! (main.js)"); - process.exit(); -} - -let proxies = []; - -if(config.UseProxy == true) -{ - proxies = fs.readFileSync('proxy.txt').toString().replace(/\r/g, '').split("\n"); -} - -function getProxy() -{ - if(config.UseProxy == false || proxies.length == 0) - { - return {}; - } - - let proxy = proxies[Math.floor(Math.random() * proxies.length)]; - let proxy_arry = proxy.split(':'); - if(proxy_arry.length == 2) - { - return { - proxy: { - host: proxy_arry[0], - port: proxy_arry[1] - } - }; - } else if(proxy_arry.length == 4) { - return { - proxy: { - host: proxy_arry[0], - port: proxy_arry[1], - auth: { - username: proxy_arry[2], - password: proxy_arry[3] - } - } - }; - } else { - console.log("Proxy is not valid!"); - return {}; - } -} - -async function StartRequest(uname) { - try{ - await FollowAccount(uname); - } catch(e) { - console.log(e); - } -} - -const GetUserID = async (uname) => { - json = {"operationName": "ChannelShell", - "variables": { - "login": uname - }, - "extensions": { - "persistedQuery": { - "version": 1, - "sha256Hash": "580ab410bcd0c1ad194224957ae2241e5d252b2c5173d8e0cce9d32d5bb14efe" - } - } - } - - headers = { - headers : {'Client-ID': 'kimne78kx3ncx6brgo4mv6wki5h1ko'} - } - - response = await axios.post('https://gql.twitch.tv/gql', json, headers); - if(response.data.data.userOrError != undefined && response.data.data.userOrError.id != undefined) - { - return response.data.data.userOrError.id; - } else { - return false; - } -} - -const FollowChannel = async (channel_ID, token) => { - let options = getProxy(); - options.headers = { - 'Accept': '*/*', - 'Accept-Language': 'en-GB', - 'Authorization': 'OAuth ' + token, - 'Client-Id': 'kimne78kx3ncx6brgo4mv6wki5h1ko', - 'Connection': 'keep-alive', - 'Content-Type': 'text/plain;charset=UTF-8', - 'Origin': 'https://www.twitch.tv', - 'Referer': 'https://www.twitch.tv/', - 'Sec-Fetch-Dest': 'empty', - 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Site': 'same-site', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', - 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - }; - data = '{ "operationName": "FollowButton_UnfollowUser", "variables": { "input": { "targetID": "793701515" } }, "extensions": { "persistedQuery": { "version": 1, "sha256Hash": "f7dae976ebf41c755ae2d758546bfd176b4eeb856656098bb40e0a672ca0d880" } } }' - response = await axios.post('https://gql.twitch.tv/gql', data, options); - console.log(response) - console.log('_________________') -} - -const FollowAccount = async (uname) => { - userID = await GetUserID(uname); - if(userID == false) - { - console.log("Username not valid."); - GettingUsername(); - return false; - } - - for (const token of tokens) { - if(tokens == undefined ||tokens == null || tokens == "") - { - GettingUsername(); - return false; - } - - await FollowChannel(userID, token); - } - - console.log("Unfollowing done!"); - GettingUsername(); -} - -const GettingUsername = async () => { - rl.question("Username?\n", function(uname) { - StartRequest(uname); - }); -}; - -GettingUsername(); \ No newline at end of file diff --git a/useragents.txt b/useragents.txt new file mode 100644 index 0000000..0132b87 --- /dev/null +++ b/useragents.txt @@ -0,0 +1,4 @@ +Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0 +Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; x64; rv:109.0) Gecko/20100101 Firefox/109.0 +Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 +Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 \ No newline at end of file diff --git a/utils.js b/utils.js index f2fafe7..b2ef88a 100644 --- a/utils.js +++ b/utils.js @@ -1,3 +1,4 @@ +const fs = require('fs'); const UsernameGenerator = require('username-generator'); const PasswordGenerator = require('generate-password'); function randomIntFromInterval(min, max) { @@ -13,9 +14,106 @@ module.exports.generateBirthday = () => ({ year: randomIntFromInterval(1960, 1999), }); -module.exports.generateRandomCredentials = (uname) => ({ +const TwitchClinetID = "kimne78kx3ncx6brgo4mv6wki5h1ko"; +module.exports.TwitchClinetID = TwitchClinetID; +module.exports.generateRandomRegisterData = (uname, mail) => ({ username: uname, password: this.generatePassword(), birthday: this.generateBirthday(), + email: mail, + client_id: TwitchClinetID, + integrity_token: null }); + +let useragents = fs.readFileSync('useragents.txt').toString().replace(/\r/g, '').split("\n"); +let proxies = fs.readFileSync('proxy.txt').toString().replace(/\r/g, '').split("\n"); + +module.exports.MakeRandomID = (length) => { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + const charactersLength = characters.length; + let counter = 0; + while (counter < length) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + counter += 1; + } + return result; +} + +module.exports.getProxy = (ptype) => { + if(proxies.length == 0) + { + return {}; + } + + let proxy = proxies[Math.floor(Math.random() * proxies.length)]; + let proxy_arry = proxy.split(':'); + if(proxy_arry.length == 2) + { + return { + timeout: null, + maxFreeSockets: 1, + maxSockets: 1, + maxTotalSockets: Infinity, + sockets: {}, + freeSockets: {}, + requests: {}, + options: {}, + secureProxy: false, + proxy: { + protocol: ptype + ':', + slashes: true, + auth: null, + host: proxy_arry[0], + port: proxy_arry[1], + hostname: proxy_arry[0], + hash: null, + search: null, + query: null, + href: ptype + '://' + proxy_arry[0] + ':' + proxy_arry[1] + } + }; + } else if(proxy_arry.length == 4) { + return { + timeout: null, + maxFreeSockets: 1, + maxSockets: 1, + maxTotalSockets: Infinity, + sockets: {}, + freeSockets: {}, + requests: {}, + options: {}, + secureProxy: false, + proxy: { + protocol: ptype + ':', + slashes: true, + auth: { + username: proxy_arry[2], + password: proxy_arry[3] + }, + host: proxy_arry[0], + port: proxy_arry[1], + hostname: proxy_arry[0], + hash: null, + search: null, + query: null, + href: ptype + '://' + proxy_arry[2] + ':' + proxy_arry[3] + '@' + proxy_arry[0] + ':' + proxy_arry[1] + } + }; + } else { + console.log("Proxy is not valid!"); + return {}; + } +}; + +module.exports.getUserAgent = () => { + if(useragents.length == 0) + { + return {}; + } + + let useragent = useragents[Math.floor(Math.random() * useragents.length)]; + return useragent; +}; + module.exports.convertCookieForRequestHeader = cookies => cookies.map(cookies => cookies.split(';')[0]).join(';');