diff --git a/index.js b/index.js index c387a6c..602455c 100644 --- a/index.js +++ b/index.js @@ -28,27 +28,33 @@ var useAutoCatcha = configFile.useAutoCatcha; var captchaApiKey = configFile.captchaApiKey; // End Config File Imports -if(useAutoCatcha) - showWindow = false; +if (useAutoCatcha) + showWindow = false; // argv parse var argv = require('minimist')(process.argv.slice(2)); -if (argv['h']) { - console.log("usage: index.js [-h] [-u USERNAME] [-s START] [-e END]"); - console.log(""); - console.log("An automation script based on Nightmare.js."); - console.log("Can create any number of Nintendo Pokémon Trainer Club accounts,"); - console.log("with a single e-mail address."); - console.log(""); - console.log("optional arguments:"); - console.log(" -u The usernane used."); - console.log(" -s Starting number."); - console.log(" -e Ending number."); - process.exit(); +if (argv['h']) { + console.log("usage: index.js [-h] [-u USERNAME] [-s START] [-e END]"); + console.log(""); + console.log("An automation script based on Nightmare.js."); + console.log("Can create any number of Nintendo Pokémon Trainer Club accounts,"); + console.log("with a single e-mail address."); + console.log(""); + console.log("optional arguments:"); + console.log(" -u The usernane used."); + console.log(" -s Starting number."); + console.log(" -e Ending number."); + process.exit(); +} +if (argv['u']) { + username = argv['a']; +} +if (argv['s']) { + start = argv['s']; +} +if (argv['e']) { + end = argv['e']; } -if (argv['u']) { username=argv['a']; } -if (argv['s']) { start=argv['s']; } -if (argv['e']) { end=argv['e']; } var outputFile = "PogoPlayer/accounts.csv"; // File which will contain the generated "username password" combinations. var outputFormat = "ptc,%NICK%,%PASS%,%LAT%,%LON%,%UN%\r\n"; // Format used to save the account data in outputFile. Supports %NICK%, %PASS%. @@ -57,6 +63,7 @@ var screenshotFolder = "output/screenshots/"; // App data var url_ptc = "https://club.pokemon.com/us/pokemon-trainer-club/sign-up/"; var useragent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"; +var symbols = ["#", "?", "!", "@", "$", "%", "^", "&", ">", "<", "+", "`", "*", "(", ")", "-", "[", "]"]; var nightmare_opts = { show: showWindow, waitTimeout: 10000, @@ -80,9 +87,8 @@ if ((email_user + '+' + username + end + '@' + email_domain).length > 75) { process.exit(); } -if (!useRandomPassword && password.length > 15) { - console.log("Error: length of password can't be longer than 15 characters."); - console.log("Please use a shorter password."); +if (!useRandomPassword && (password.length > 15 || !containsSymbol(password) || !containsUppercase(password))) { + console.log("Error: length of password can't be longer than 15 characters, requires a symbol and uppercase characters."); process.exit(); } @@ -94,49 +100,76 @@ createAccount(start); // Helpers +function containsUppercase(txt) { + return txt.toLowerCase() !== txt; +} + +function containsSymbol(txt) { + return symbols.some(function(s) { return txt.indexOf(s) > -1; }); +} + function handleError(err) { - if(debug) { + if (debug) { console.log("[DEBUG] Error:" + JSON.stringify(err)); } - + return err; } -function randomPassword() { - return Math.random().toString(36).substr(2, 8); +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; } -function prepareNightmare(nightmare) { - nightmare.useragent(useragent); +function getRandomNumbers(length) { + return Math.random().toString().substr(2, length); +} + +function getRandomSymbols(length) { + var str = ""; + + for (let i = 0; i < length; i++) { + str += symbols[getRandomInt(0, symbols.length - 1)]; + } + + return str; } function randomPassword() { - return Math.random().toString(36).substr(2, 8); + return Math.random().toString(36).substr(2, 8) + getRandomNumbers(3) + getRandomSymbols(3); +} + +function prepareNightmare(nightmare) { + nightmare.useragent(useragent); } // Pages function createAccount(ctr) { console.log("Creating account " + ctr + " of " + end); - + // Launch instance handleFirstPage(ctr); } // First page function handleFirstPage(ctr) { - if(debug) { + if (debug) { console.log("[DEBUG] Handle first page #" + ctr); } - + nightmare.goto(url_ptc) .evaluate(evaluateDobPage) - .then(function(validated) { - if(!validated) { + .then(function(validated) { + if (!validated) { // Missing form data, loop over itself console.log("[" + ctr + "] Servers are acting up... Trying again."); - return function() { nightmare.wait(500).refresh().wait(); handleFirstPage(ctr); }; + return function() { + nightmare.wait(500).refresh().wait(); + handleFirstPage(ctr); + }; } else { - return function() { fillFirstPage(ctr); }; + return function() { + fillFirstPage(ctr); + }; } }) .then(function(next) { @@ -152,21 +185,23 @@ function handleFirstPage(ctr) { } function fillFirstPage(ctr) { - if(debug) { + if (debug) { console.log("[DEBUG] Fill first page #" + ctr); } - + nightmare.evaluate(function(data) { - var dob = new Date((new Date()).getTime() - (Math.random() * (new Date()).getTime()) - 18*365*24*60*60*1000 ); - document.getElementById("id_dob").value = dob.getFullYear() + "-" + (dob.getMonth()+1) + "-" + dob.getDate(); + var dob = new Date((new Date()).getTime() - (Math.random() * (new Date()).getTime()) - 18 * 365 * 24 * 60 * 60 * 1000); + document.getElementById("id_dob").value = dob.getFullYear() + "-" + (dob.getMonth() + 1) + "-" + dob.getDate(); var els = document.getElementsByName("country"); - for(var i = 0; i < els.length; i++) { + for (var i = 0; i < els.length; i++) { els[i].value = data.country; } - + return document.getElementById("id_dob").value; - }, { country: country }) + }, { + country: country + }) .click("form[name='verify-age'] [type=submit]") .wait("#id_username") .then(function() { @@ -182,18 +217,23 @@ function fillFirstPage(ctr) { // Signup page function handleSignupPage(ctr) { - if(debug) { + if (debug) { console.log("[DEBUG] Handle second page #" + ctr); } - + nightmare.evaluate(evaluateSignupPage) .then(function(validated) { - if(!validated) { + if (!validated) { // Missing form data, loop over itself console.log("[" + ctr + "] Servers are acting up... Trying again."); - return function() { nightmare.wait(500).refresh().wait(); handleFirstPage(ctr); }; + return function() { + nightmare.wait(500).refresh().wait(); + handleFirstPage(ctr); + }; } else { - return function() { fillSignupPage(ctr); }; + return function() { + fillSignupPage(ctr); + }; } }).then(function(next) { // Handle next step: either a loop to first page in case of error, or form fill on success @@ -208,157 +248,162 @@ function handleSignupPage(ctr) { } function fillSignupPage(ctr) { - if(debug) { + if (debug) { console.log("[DEBUG] Fill signup page #" + ctr); } - + var _pass = password; var _nick = username + ctr; - - if(useRandomPassword) { + + if (useRandomPassword) { _pass = randomPassword(); } - + // Use nicknames list, or (username + number) combo? - if(useNicknamesFile) { + if (useNicknamesFile) { // Make sure we have a nickname left - if(nicknames.length < 1) { + if (nicknames.length < 1) { throw Error("We're out of nicknames to use!"); } - + // Get the first nickname off the list & use it _nick = nicknames.shift(); } - + // Fill it all in - if(useAutoCatcha) - { - nightmare.evaluate(function(data) { - document.getElementById("id_password").value = data.pass; - document.getElementById("id_confirm_password").value = data.pass; - document.getElementById("id_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; - document.getElementById("id_confirm_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; - document.getElementById("id_screen_name").value = data.nick; - document.getElementById("id_username").value = data.nick; - window.scrollTo(0,document.body.scrollHeight); - }, { "pass": _pass, "nick": _nick, "email_user": email_user, "email_domain": email_domain }) - .check("#id_terms"); - - - nightmare.evaluate(function(){ - return document.getElementsByClassName("g-recaptcha")[0].getAttribute('data-sitekey'); - }).then(function(result) - { - console.log("Start recaptcha solving"); - request('http://2captcha.com/in.php?key=' + captchaApiKey + '&method=userrecaptcha&googlekey=' + result + '&pageurl=club.pokemon.com', function (error, response, body) - { - var checkCaptcha = function() - { - request('http://2captcha.com/res.php?key=' + captchaApiKey + '&action=get&id=' + body.substring(3), function (error, response, body) - { - if(body.substring(0, 2) == "OK") - { - var captchaValidation = body.substring(3); - nightmare.evaluate(function(data) { - document.getElementById("g-recaptcha-response").value = data.captchaValidation; - }, { captchaValidation: captchaValidation }) - .click('.button-green[value=" Continue"]') - .then(function() - { - nightmare.wait(function() { - return (document.getElementById("signup-signin") !== null || document.getElementById("btn-reset") !== null || document.body.textContent.indexOf("That username already exists") > -1); - }) - .evaluate(function() { - return (document.body.textContent.indexOf("Hello! Thank you for creating an account!") > -1); - }) - .then(function(success) { - if(success) { - // Log it in the file of used nicknames - var content = outputFormat.replace('%NICK%', _nick).replace('%PASS%', _pass).replace('%LAT%', lat).replace('%LON%', lon).replace('%UN%', _nick); - fs.appendFile(outputFile, content, function(err) { - // - }); - } - - if((success && screenshotResult) || screenshotFail) { - // Screenshot - nightmare.screenshot(screenshotFolder + _nick + ".png"); - } - - // Next one, or stop - if(ctr < end) { - return function() { createAccount(ctr + 1); }; - } else { - return nightmare.end(); - } - }).then(function(next) { - return next(); - }).catch(handleError) - .then(function(err) { - if (typeof err !== "undefined") { - return handleSignupPage(ctr); - } - }); - }); - } - else - { - // Not ready yet... - setTimeout(checkCaptcha, 2000); - } - }); - }; - setTimeout(checkCaptcha, 2000); - }); - }); - } - else - { - nightmare.evaluate(function(data) { - document.getElementById("id_password").value = data.pass; - document.getElementById("id_confirm_password").value = data.pass; - document.getElementById("id_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; - document.getElementById("id_confirm_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; - document.getElementById("id_screen_name").value = data.nick; - document.getElementById("id_username").value = data.nick; - window.scrollTo(0,document.body.scrollHeight); - }, { "pass": _pass, "nick": _nick, "email_user": email_user, "email_domain": email_domain }) - .check("#id_terms") - .wait(function() { - return (document.getElementById("signup-signin") !== null || document.getElementById("btn-reset") !== null || document.body.textContent.indexOf("That username already exists") > -1); - }) - .evaluate(function() { - return (document.body.textContent.indexOf("Hello! Thank you for creating an account!") > -1); - }) - .then(function(success) { - if(success) { - // Log it in the file of used nicknames - var content = outputFormat.replace('%NICK%', _nick).replace('%PASS%', _pass).replace('%LAT%', lat).replace('%LON%', lon).replace('%UN%', _nick); - fs.appendFile(outputFile, content, function(err) { - // - }); - } - - if((success && screenshotResult) || screenshotFail) { - // Screenshot - nightmare.screenshot(screenshotFolder + _nick + ".png"); - } - - // Next one, or stop - if(ctr < end) { - return function() { createAccount(ctr + 1); }; - } else { - return nightmare.end(); - } - }).then(function(next) { - return next(); - }).catch(handleError) - .then(function(err) { - if (typeof err !== "undefined") { - return handleSignupPage(ctr); - } - }); - } + if (useAutoCatcha) { + nightmare.evaluate(function(data) { + document.getElementById("id_password").value = data.pass; + document.getElementById("id_confirm_password").value = data.pass; + document.getElementById("id_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; + document.getElementById("id_confirm_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; + document.getElementById("id_screen_name").value = data.nick; + document.getElementById("id_username").value = data.nick; + window.scrollTo(0, document.body.scrollHeight); + }, { + "pass": _pass, + "nick": _nick, + "email_user": email_user, + "email_domain": email_domain + }) + .check("#id_terms"); + + + nightmare.evaluate(function() { + return document.getElementsByClassName("g-recaptcha")[0].getAttribute('data-sitekey'); + }).then(function(result) { + console.log("Start recaptcha solving"); + request('http://2captcha.com/in.php?key=' + captchaApiKey + '&method=userrecaptcha&googlekey=' + result + '&pageurl=club.pokemon.com', function(error, response, body) { + var checkCaptcha = function() { + request('http://2captcha.com/res.php?key=' + captchaApiKey + '&action=get&id=' + body.substring(3), function(error, response, body) { + if (body.substring(0, 2) == "OK") { + var captchaValidation = body.substring(3); + nightmare.evaluate(function(data) { + document.getElementById("g-recaptcha-response").value = data.captchaValidation; + }, { + captchaValidation: captchaValidation + }) + .click('.button-green[value=" Continue"]') + .then(function() { + nightmare.wait(function() { + return (document.getElementById("signup-signin") !== null || document.getElementById("btn-reset") !== null || document.body.textContent.indexOf("That username already exists") > -1); + }) + .evaluate(function() { + return (document.body.textContent.indexOf("Hello! Thank you for creating an account!") > -1); + }) + .then(function(success) { + if (success) { + // Log it in the file of used nicknames + var content = outputFormat.replace('%NICK%', _nick).replace('%PASS%', _pass).replace('%LAT%', lat).replace('%LON%', lon).replace('%UN%', _nick); + fs.appendFile(outputFile, content, function(err) { + // + }); + } + + if ((success && screenshotResult) || screenshotFail) { + // Screenshot + nightmare.screenshot(screenshotFolder + _nick + ".png"); + } + + // Next one, or stop + if (ctr < end) { + return function() { + createAccount(ctr + 1); + }; + } else { + return nightmare.end(); + } + }).then(function(next) { + return next(); + }).catch(handleError) + .then(function(err) { + if (typeof err !== "undefined") { + return handleSignupPage(ctr); + } + }); + }); + } else { + // Not ready yet... + setTimeout(checkCaptcha, 2000); + } + }); + }; + setTimeout(checkCaptcha, 2000); + }); + }); + } else { + nightmare.evaluate(function(data) { + document.getElementById("id_password").value = data.pass; + document.getElementById("id_confirm_password").value = data.pass; + document.getElementById("id_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; + document.getElementById("id_confirm_email").value = data.email_user === "" ? data.nick + "@" + data.email_domain : data.email_user + "+" + data.nick + "@" + data.email_domain; + document.getElementById("id_screen_name").value = data.nick; + document.getElementById("id_username").value = data.nick; + window.scrollTo(0, document.body.scrollHeight); + }, { + "pass": _pass, + "nick": _nick, + "email_user": email_user, + "email_domain": email_domain + }) + .check("#id_terms") + .wait(function() { + return (document.getElementById("signup-signin") !== null || document.getElementById("btn-reset") !== null || document.body.textContent.indexOf("That username already exists") > -1); + }) + .evaluate(function() { + return (document.body.textContent.indexOf("Hello! Thank you for creating an account!") > -1); + }) + .then(function(success) { + if (success) { + // Log it in the file of used nicknames + var content = outputFormat.replace('%NICK%', _nick).replace('%PASS%', _pass).replace('%LAT%', lat).replace('%LON%', lon).replace('%UN%', _nick); + fs.appendFile(outputFile, content, function(err) { + // + }); + } + + if ((success && screenshotResult) || screenshotFail) { + // Screenshot + nightmare.screenshot(screenshotFolder + _nick + ".png"); + } + + // Next one, or stop + if (ctr < end) { + return function() { + createAccount(ctr + 1); + }; + } else { + return nightmare.end(); + } + }).then(function(next) { + return next(); + }).catch(handleError) + .then(function(err) { + if (typeof err !== "undefined") { + return handleSignupPage(ctr); + } + }); + } } // Evaluations