[
  {
    "path": ".dockerignore",
    "content": ".git\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.{yml,coffee,js,json}]\nindent_size = 2\n\n[Makefile]\nindent_style = tab\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "\"use strict\";\n\nmodule.exports = {\n  env: {\n    es6: true,\n    node: true\n  },\n  extends: [\"eslint:recommended\"],\n  plugins: [\"import\"],\n  rules: {\n    curly: [\"error\", \"multi\", \"consistent\"],\n    \"import/no-extraneous-dependencies\": [\n      \"error\",\n      { devDependencies: [\"tests*/**\", \"scripts/**\"] }\n    ],\n    \"no-console\": \"off\",\n    \"no-else-return\": \"error\",\n    \"no-inner-declarations\": \"error\",\n    \"no-unneeded-ternary\": \"error\",\n    \"no-useless-return\": \"error\",\n    \"no-var\": \"error\",\n    \"no-trailing-spaces\": \"error\",\n    \"prefer-arrow-callback\": \"error\",\n    \"prefer-const\": \"error\",\n    \"react/no-deprecated\": \"off\",\n    semi: [\"error\", \"never\"],\n    strict: \"error\",\n    eqeqeq: 2,\n    \"symbol-description\": \"error\",\n    \"nonblock-statement-body-position\": [\"error\", \"beside\"],\n    yoda: [\"error\", \"never\", { exceptRange: true }]\n  },\n  parserOptions: {\n  }\n};\n"
  },
  {
    "path": ".gitignore",
    "content": "database.json\nnode_modules\ndb.json\ntelebot.json\n*.bak\nconfig/\n"
  },
  {
    "path": ".mailmap",
    "content": "frk <hazefrk+dev@gmail.com>  frk <frk@haze-productions.com>\nfrk <hazefrk+dev@gmail.com>  frk1 <frk@haze-productions.com>\nfrk <hazefrk+dev@gmail.com>  frk1 <frk1@users.noreply.github.com>\n"
  },
  {
    "path": ".yarnclean",
    "content": "# test directories\n__tests__\ntest\ntests\npowered-test\n\n# asset directories\ndocs\ndoc\nwebsite\nimages\nassets\n\n# examples\nexample\nexamples\n\n# code coverage directories\ncoverage\n.nyc_output\n\n# build scripts\nMakefile\nGulpfile.js\nGruntfile.js\n\n# configs\nappveyor.yml\ncircle.yml\ncodeship-services.yml\ncodeship-steps.yml\nwercker.yml\n.tern-project\n.gitattributes\n.editorconfig\n.*ignore\n.eslintrc\n.jshintrc\n.flowconfig\n.documentup.json\n.yarn-metadata.json\n.travis.yml\n\n# misc\n*.md\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "\n4.1.2 / 2017-11-14\n==================\n\n  * 🚑 Fix steam accounts not restarting\n  * 🎨 app.js: prefer ternary operator\n  * 📝 readme: install production dependencies only\n  * ✏️ changelog: fix typo\n  * ✨ Add pretty script to format using prettier\n\n4.1.1 / 2017-11-12\n==================\n\n  * 🚀 Remove dependency on babel\n  * 🔧 Update .editorconfig\n\n4.1.0 / 2017-11-12\n==================\n\n  * 📝 Update Readme\n  * 🐛 Fix crash if database.json was not created already\n  * 🔨 Cleanup after conversion\n  * ✨ Add husky git-commit hooks\n  * 🐋 Update Dockerfile\n  * 🔥 Remove coffeelint.json\n  * 🔧 Add devDependencies\n  * 🐋 Update Dockerfile\n  * 🚀 Migrate from coffeescript to ES2016+ javascript!\n  * 📝 readme: add snyk.io vulnerabilities badge\n\n4.0.1 / 2017-11-08\n==================\n\n  * 📝 Add changelog\n  * 🔨 Use manageDB.read() where possible\n\n4.0.0 / 2017-11-08\n==================\n\n  * 🔧 Update .mailmap\n  * 👥 Add .mailmap\n  * 🔨 Move database migration code to own file\n  * 💥 Move config files to config folder\n  * 🔨 If there are no games do not login\n  * ✨ Add .yarnclean file\n  * 🐋 Add docker-compose.yml\n  * 🔥 Remove package-lock.json\n  * ✨ Integrate telegram bot into app.coffee\n  * 🐋 Use docker multistage feature\n  * 🐋 Add .dockerignore\n\n3.0.2 / 2017-11-07\n==================\n\n  * 🔨 Move database read/write logic to own file\n  * 🔥 Remove unused dependency\n  * 🚚 Fix telebot.gif path\n\n3.0.1 / 2017-11-06\n==================\n\n  * 🐛 Add missing require in user.coffee\n  * 🐋 Add Dockerfile\n  * 🚀 Modernize code\n  * ✨ Add .editorconfig\n  * 🔧 Update coffeelint.json\n\n3.0.0 / 2017-11-05\n==================\n\n  * 🚀 Modernize code\n  * ✨ Add .editorconfig\n  * 🔧 Update coffeelint.json\n  * Merge pull request #4 from M0V3/patch-1\n  * Fixed directory name in how to\n\n2.3.1 / 2016-08-09\n==================\n\n  * Fix telegraf-flow incompatibility\n\n2.3.0 / 2016-08-09\n==================\n\n  * Add telegram bot\n  * Minor code cleanup\n  * Update dependencies\n\n2.2.2 / 2016-08-06\n==================\n\n  * Generate 2fa code using callback\n\n2.2.1 / 2016-08-05\n==================\n\n  * Fix readLineSync error\n\n2.2.0 / 2016-07-31\n==================\n\n  * Use inquirer to select games\n  * Wait 1.5s for the sentry to be confirmed\n\n2.1.1 / 2016-07-30\n==================\n\n  * Always convert gameid to integer\n  * Reformat timeout error message\n  * Remove dead code\n  * Add missing_fat_arrows to coffeelint\n\n2.1.0 / 2016-07-22\n==================\n\n  * Make use of Promises\n  * Update steam-user to 3.11.0\n  * Prefer SteamTotp callback version\n  * Allow retry if 2FA failed\n  * Do not try to log off if steamguard failed earlier\n  * Optimize behaviour if steam guard is invalid\n  * Add support for 'npm start'\n  * Minor code reorganisations\n\n2.0.4 / 2016-07-16\n==================\n\n  * Remove debug code\n  * Simplify boost.coffee using lodash\n\n2.0.3 / 2016-07-16\n==================\n\n  * Cleanup boost.coffee\n  * Optimize indentation\n  * Remove superfluous 'loggedOn' event listeners\n  * When logging off set games played to none\n\n2.0.2 / 2016-07-15\n==================\n\n  * Bump steam-user version\n  * Fix various bugs\n  * Timestamp will now display 24h time\n\n2.0.1 / 2016-07-12\n==================\n\n  * Improve 'reliable connection' situation\n  * Change timestamp format\n\n2.0.0 / 2016-07-08\n==================\n\n  * Add minimal node version\n  * Improve handling of common errors\n  * Add coffeelint.json\n  * Add license (MIT)\n  * Add converter.coffee for old db.json style\n  * Do not prompt for steamguard code in boost.coffee\n  * Save sentry files automatically\n  * Initial commit\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM mhart/alpine-node:9\nWORKDIR /app\nCOPY . /app\nRUN yarn install --production && yarn cache clean\n\nFROM mhart/alpine-node:base-9\nWORKDIR /app\nCOPY --from=0 /app .\nCOPY . .\nCMD [ \"node\", \"/app/lib/app.js\" ]\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016-2017 frk <hazefrk+dev@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![GitHub package version](https://img.shields.io/github/package-json/v/frk1/steamhourboostv2.svg)](https://github.com/frk1/steamhourboostv2/tree/master)\n[![Known Vulnerabilities](https://snyk.io/test/github/frk1/steamhourboostv2/badge.svg)](https://snyk.io/test/github/frk1/steamhourboostv2)\n[![Docker Automated build](https://img.shields.io/docker/automated/frk1/steamhourboostv2.svg)](https://hub.docker.com/r/frk1/steamhourboostv2/)\n[![Docker Build Status](https://img.shields.io/docker/build/frk1/steamhourboostv2.svg)](https://hub.docker.com/r/frk1/steamhourboostv2/)\n[![GitHub stars](https://img.shields.io/github/stars/frk1/steamhourboostv2.svg?style=social&label=Stars)](https://github.com/frk1/steamhourboostv2)\n[![GitHub forks](https://img.shields.io/github/forks/frk1/steamhourboostv2.svg?style=social&label=Fork)](https://github.com/frk1/steamhourboostv2)\n\n## steamhourboost v2\n\nA new version of an application for boosting the hours of Steam games. The new version supports two-factor authentication using a shared secret key.\n\nNew users can be added to the `config/database.json`. Just run `npm run user` and follow the instructions.\n\nBy default the application will boost CS 1.6 and CS:GO. The boosted game can be changed by editing the `config/database.json`.\n\n### Installation\nInstall a (version `>= 8.9.0`) `node` and `pm2`. Clone the steamhourboostv2 repository and install dependencies:\n\n```bash\napt-get update -yq                                                    && \\\napt-get install -yq git make curl                                     && \\\ncurl -L https://git.io/n-install | N_PREFIX=~/.n bash -s -- -y latest && \\\nsource /root/.bashrc                                                  && \\\nnpm install -g pm2 yarn                                               && \\\ncd ~                                                                  && \\\ngit clone https://github.com/frk1/steamhourboostv2.git                && \\\ncd steamhourboostv2                                                   && \\\nyarn install --production                                             && \\\nclear                                                                 && \\\necho \"Done. Run 'npm run user' to add users!\"\n```\n\n### Usage\n\nAccounts can be added with `npm run user`. Start the script using `pm2`:\n\n```bash\n# Start boosting and telegram bot\nnpm run pm2\n\n# Alternate command\npm2 start lib/app.js\n```\n\nTo start the application **without** pm2:\n\n```bash\n# Start boosting and telegram bot.\nnpm run app\n\n# Alternate command\nnode lib/app.js\n```\n\n### The database.json format\n\nThe configuration files are saved in the `config` subfolder.\nIf files need to be edited, remember to also edit the files **inside the config folder**!\n\nsteamhourboost will automatically convert the old database and move it if necessary.\n\nA backup of the old database will be created as `database.json.bak`.\n\n### Restarting the application\n\nJust do the following:\n\n```bash\npm2 restart all\n```\n\nIf multiple processes are running, the ID of the process to be restarted must be specified.  The ID can be found using:\n\n```bash\npm2 ls\n```\n\n### Docker\n\n[Steamhourboost](https://hub.docker.com/r/frk1/steamhourboostv2/) can be used Docker. Copy the `docker-compose.yml` and run it.\nThe `develop` branch is selected by default. To change branches, edit the compose file to target the `latest` tag.\n\nThe images are based on [mhart/alpine-node](https://github.com/mhart/alpine-node) and are as minimal as possible.\n\n## Telegram Bot\n\nAn optional telegram bot is included to generate 2FA tokens using telegram.\n\nTo use the Telegram Bot, [acquire a bot token from *@BotFather*](https://core.telegram.org/bots#6-botfather).\n\nThe first execution of steamhourboost will create an empty `config/telebot.json`. Set the bot token and restart the application.\n\nTo find out the id, write anything to the bot.\n\nSet the id as `admin_id` in the `config/telebot.json` and restart the application.\n\nThat's it! The bot is now waiting for requests. Ask him about tokens! Just enter the username (or something close similar) and it will generate the key:\n\n![telebot](https://raw.githubusercontent.com/frk1/steamhourboostv2/master/docs/telebot.gif)\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3'\nservices:\n  hourboost:\n    image: frk1/steamhourboostv2:develop\n    restart: always\n    volumes:\n      - \"./config:/app/config\"\n"
  },
  {
    "path": "lib/app.js",
    "content": "\"use strict\"\n\nconst _ = require(\"lodash\")\nconst R = require(\"ramda\")\nconst Promise = require(\"bluebird\")\n\nconst SteamAccount = require(\"./steamaccount\")\nconst migrate = require(\"./migrate\")\nconst manageDB = require(\"./database\")\n\nmigrate()\nconst database = manageDB.read()\n\nconst telebot = require(\"./telebot\")\ntelebot()\n\nif (database.length === 0) {\n  console.error(\n    \"[!] No accounts have been added! Please run 'npm run user' to add accounts!\"\n  )\n  process.exit(0)\n}\n\nconst pad = 24 + _.maxBy(R.pluck(\"name\", database), \"length\").length\nconst accounts = database\n  .map(({ name, password, sentry, secret, games = [] }) => {\n    return games.length > 0\n      ? new SteamAccount(name, password, sentry, secret, games, pad)\n      : null\n  })\n  .filter(val => val !== null)\n\nconst restartBoost = () => {\n  console.log(\"[=] Restart boosting\")\n  return Promise.map(accounts, _.method(\"restartGames\"))\n    .delay(1800000)\n    .finally(restartBoost)\n}\n\nconsole.log(\"[=] Start boosting\")\nPromise.map(accounts, _.method(\"boost\"))\n  .delay(1800000)\n  .then(restartBoost)\n"
  },
  {
    "path": "lib/database.js",
    "content": "\"use strict\"\n\nconst fs = require(\"fs-extra\")\nconst approot = require(\"app-root-path\")\n\nconst write = (obj, path = \"config/database.json\") =>\n  fs.writeJsonSync(approot.resolve(path), obj, { spaces: 2, EOL: \"\\n\" })\n\nconst read = (path = \"config/database.json\") =>\n  fs.readJsonSync(approot.resolve(path))\n\nmodule.exports = { read, write }\n"
  },
  {
    "path": "lib/migrate.js",
    "content": "\"use strict\"\n\nconst _ = require(\"lodash\")\nconst fs = require(\"fs-extra\")\nconst approot = require(\"app-root-path\")\nconst manageDB = require(\"./database\")\n\nconst moveFileToConfigFolder = filename => {\n  const path = approot.resolve(filename)\n  const pathDest = approot.resolve(`config/${filename}`)\n  if (fs.pathExistsSync(path)) {\n    fs.moveSync(path, pathDest, { overwrite: true })\n    return console.log(`[+] Moved '${filename}' to config folder!`)\n  }\n}\n\nconst convertOldDatabaseFormat = () => {\n  const path = approot.resolve(\"config/database.json\")\n  if (!fs.pathExistsSync(path)) return manageDB.write([])\n\n  let database = manageDB.read()\n  if (!_.isPlainObject(database)) return\n\n  manageDB.write(database, \"config/database.json.bak\")\n  database = _.map(database, (data, name) => {\n    data.name = name\n    return data\n  })\n  manageDB.write(database)\n  return console.log(\n    \"[+] Converted database to new format! The old one has been backuped as database.json.bak\"\n  )\n}\n\nmodule.exports = () => {\n  [\"database.json\", \"telebot.json\"].forEach(moveFileToConfigFolder)\n  return convertOldDatabaseFormat()\n}\n"
  },
  {
    "path": "lib/steamaccount.js",
    "content": "\"use strict\"\n\nconst _ = require(\"lodash\")\nconst SteamUser = require(\"steam-user\")\nconst SteamTotp = require(\"steam-totp\")\nconst Promise = require(\"bluebird\")\nconst moment = require(\"moment\")\nconst EventEmitter = require(\"events\")\n\nmodule.exports = class SteamAccount extends EventEmitter {\n  constructor(name, password, sentry, secret, games, indent = 0) {\n    super()\n    this.name = name\n    this.password = password\n    this.sentry = sentry\n    this.secret = secret\n    this.games = games\n    this.indent = indent\n    const options = {\n      promptSteamGuardCode: false,\n      dataDirectory: null\n    }\n    this.client = new SteamUser(null, options)\n    if (this.sentry) this.client.setSentry(Buffer.from(this.sentry, \"base64\"))\n\n    this.client.on(\"error\", err => this.emit(\"clientError\", err))\n    this.client.on(\"steamGuard\", () => this.emit(\"clientSteamGuard\"))\n    this.client.once(\"steamGuard\", () => (this.steamGuardRequested = true))\n  }\n\n  logheader() {\n    return _.padEnd(\n      `[${moment().format(\"YYYY-MM-DD HH:mm:ss\")} - ${this.name}]`,\n      this.indent\n    )\n  }\n\n  error(err) {\n    return this.emit(\"customError\", err)\n  }\n\n  login() {\n    if (this.client.client.loggedOn) return Promise.resolve()\n    if (this.steamGuardRequested && !this.secret) return Promise.reject(\"Steam guard requested!\")\n\n    return new Promise((resolve, reject) => {\n      this.once(\"clientError\", reject)\n      this.once(\"clientSteamGuard\", () => reject(\"Steam guard requested!\"))\n      this.client.once(\"loggedOn\", resolve)\n      if (this.secret) return SteamTotp.getAuthCode(this.secret, (err, code) => {\n          return this.client.logOn({\n            accountName: this.name,\n            password: this.password,\n            twoFactorCode: code\n          })\n        })\n\n      return this.client.logOn({\n        accountName: this.name,\n        password: this.password\n      })\n    })\n      .timeout(10000)\n      .catch(Promise.TimeoutError, () => Promise.reject(\"Timed out at login\"))\n      .finally(() => {\n        this.removeAllListeners(\"clientError\")\n        this.removeAllListeners(\"clientSteamGuard\")\n        return this.client.removeAllListeners(\"loggedOn\")\n      })\n  }\n\n  logoff() {\n    if (!this.client.client.loggedOn) return\n    this.client.gamesPlayed([])\n    return this.client.logOff()\n  }\n\n  boost() {\n    return this.login()\n      .then(() => {\n        this.client.setPersona(SteamUser.EPersonaState.Offline)\n        this.client.gamesPlayed(this.games !== null ? this.games : [10, 730])\n        return console.log(`${this.logheader()} Starting to boost games!`)\n      })\n      .catch(err => console.error(`${this.logheader()} ${err}`))\n  }\n\n  restartGames() {\n    this.client.gamesPlayed([])\n    return Promise.delay(5000).then(() => this.boost())\n  }\n}\n"
  },
  {
    "path": "lib/telebot.js",
    "content": "\"use strict\"\n\nconst R = require(\"ramda\")\nconst Fuse = require(\"fuse.js\")\nconst Promise = require(\"bluebird\")\nconst moment = require(\"moment\")\nconst Telegraf = require(\"telegraf\")\n\nconst manageDB = require(\"./database\")\nconst database = manageDB.read()\n\nconst totp = Promise.promisify(require(\"steam-totp\").getAuthCode)\nlet token, admin_id\n\ntry {\n  ({ token, admin_id } = manageDB.read(\"config/telebot.json\"))\n} catch (e) {\n  token = \"\"\n  admin_id = 0\n  manageDB.write({ token, admin_id }, \"config/telebot.json\")\n}\n\nconst validate_admin = (ctx, next) => {\n  if (ctx.from.id === admin_id) return next()\n\n  console.error(`[#] [${moment().format()}] ${ctx.from.id} tried to request!`)\n  return ctx.replyWithMarkdown(`\\\nYou *do not* have the permission to use this bot!\n\nYour telegram id is: \\`${ctx.from.id}\\`\\\n`)\n}\n\nconst bot = new Telegraf(token)\nbot.use(validate_admin)\nbot.command(\"cancel\", ctx => ctx.scene.leave())\n\nconst fuzzy = (query = \"\") => {\n  if (database.length === 0) return []\n  if (query.length === 0) return R.pluck(\"name\", database)\n\n  const fuse = new Fuse(database, {\n    id: \"name\",\n    keys: [\"name\"],\n    shouldSort: true,\n    threshold: 0.4,\n    location: 0,\n    distance: 100,\n    maxPatternLength: 32,\n    minMatchCharLength: 0\n  })\n  return fuse.search(query)\n}\n\nbot.command(\"list\", ctx => {\n  const query = ctx.message.text.length < 6 ? \"\" : ctx.message.text.substr(6)\n  let fmt = \"The following accounts are available:\\n\"\n  fuzzy(query).map(a => (fmt += `\\`- ${a}\\`\\n`))\n  return ctx.replyWithMarkdown(fmt)\n})\n\nbot.hears(/(.*)/, ctx => {\n  const [name] = Array.from(fuzzy(ctx.message.text))\n  if (name) {\n    const acc = R.find(R.propEq(\"name\", name), database)\n    return totp(acc.secret)\n      .then(code =>\n        ctx.replyWithMarkdown(`\\\nSelected account *${acc.name}*.\n\n2FA-Code: \\`${code}\\`\\\n`)\n      )\n      .catch(err =>\n        ctx.replyWithMarkdown(`\\\nSelected account *${acc.name}*.\n\nError: \\`${err}\\`\\\n`)\n      )\n  }\n  return ctx.replyWithMarkdown(`\\\nCould not find a matching account!\n\nTry */list* to get a list of available accounts!\\\n`)\n})\n\nmodule.exports = () => {\n  if (token === \"\") return console.log(\n      \"[!] If you want to use the telegram bot please set a valid token in telebot.json!\"\n    )\n\n  console.log(\"[=] Start Telegram bot\")\n  return bot.startPolling()\n}\n"
  },
  {
    "path": "lib/user.js",
    "content": "\"use strict\"\n\nconst R = require(\"ramda\")\nconst SteamUser = require(\"steam-user\")\nconst SteamTotp = require(\"steam-totp\")\nconst inquirer = require(\"inquirer\")\n\nconst migrate = require(\"./migrate\")\nconst manageDB = require(\"./database\")\n\nmigrate()\nconst database = manageDB.read()\n\nconst promptGames = {\n  type: \"checkbox\",\n  name: \"games\",\n  message: \"Select the games to boost:\",\n  choices: [\n    { value: 10, name: \"CS 1.6\", checked: true },\n    { value: 730, name: \"CS:GO\", checked: true },\n    { value: 570, name: \"DOTA2\" }\n  ]\n}\n\ninquirer\n  .prompt([\n    { name: \"username\", message: \"Username:\" },\n    { name: \"password\", message: \"Password:\", type: \"password\" }\n  ])\n  .then(({ username, password }) => {\n    let index = R.findIndex(R.propEq(\"name\", username), database)\n    if (index === -1) {\n      database.push({\n        name: username,\n        password\n      })\n      index = R.findIndex(R.propEq(\"name\", username), database)\n    }\n\n    const client = new SteamUser()\n    client.setOption(\"promptSteamGuardCode\", false)\n    client.setOption(\"dataDirectory\", null)\n    client.logOn({\n      accountName: username,\n      password\n    })\n\n    client.on(\"steamGuard\", (domain, callback) => {\n      if (domain) return inquirer\n          .prompt([{ name: \"code\", message: `Steam guard code (${domain}):` }])\n          .then(({ code }) => callback(code))\n\n      return inquirer\n        .prompt([\n          {\n            name: \"secret\",\n            message: \"Two-factor shared secret:\",\n            type: \"password\"\n          }\n        ])\n        .then(({ secret }) =>\n          SteamTotp.generateAuthCode(secret, (err, code) => {\n            database[index].secret = secret\n            return callback(code)\n          })\n        )\n    })\n\n    client.on(\"sentry\", sentry => {\n      database[index].sentry = sentry.toString(\"base64\")\n      return manageDB.write(database)\n    })\n\n    client.on(\"loggedOn\", () => {\n      database[index].password = password\n      return inquirer.prompt(promptGames).then(({ games }) => {\n        database[index].games = games\n        manageDB.write(database)\n        return process.exit(0)\n      })\n    })\n\n    return client.on(\"error\", err => {\n      console.log(`Error: ${err}`)\n      return process.exit(1)\n    })\n  })\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"steamhourboostv2\",\n  \"version\": \"4.1.3\",\n  \"description\": \"Steam hour boost with two factor support\",\n  \"main\": \"lib/app.js\",\n  \"scripts\": {\n    \"app\": \"node lib/app.js\",\n    \"boost\": \"node lib/app.js\",\n    \"user\": \"node lib/user.js\",\n    \"pm2\": \"pm2 start lib/app.js\",\n    \"pretty\": \"prettier-eslint lib/*.js --write\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/frk1/steamhourboostv2.git\"\n  },\n  \"keywords\": [\n    \"steam\",\n    \"boost\",\n    \"csgo\"\n  ],\n  \"author\": \"frk <hazefrk+dev@gmail.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/frk1/steamhourboostv2/issues\"\n  },\n  \"homepage\": \"https://github.com/frk1/steamhourboostv2#readme\",\n  \"dependencies\": {\n    \"app-root-path\": \"^2.0.1\",\n    \"bluebird\": \"^3.5.1\",\n    \"fs-extra\": \"^5.0.0\",\n    \"fuse.js\": \"^3.2.0\",\n    \"inquirer\": \"^5.2.0\",\n    \"lodash\": \"^4.17.10\",\n    \"moment\": \"^2.22.1\",\n    \"ramda\": \"^0.25.0\",\n    \"steam-totp\": \"^2.1.0\",\n    \"steam-user\": \"^3.27.1\",\n    \"telegraf\": \"^3.15.3\"\n  },\n  \"engines\": {\n    \"node\": \">=8.9.0\"\n  },\n  \"devDependencies\": {\n    \"eslint\": \"^4.11.0\",\n    \"eslint-config-recommended\": \"^2.0.0\",\n    \"eslint-plugin-import\": \"^2.8.0\",\n    \"eslint-plugin-node\": \"^6.0.1\",\n    \"prettier\": \"^1.8.2\",\n    \"prettier-eslint-cli\": \"^4.4.0\"\n  }\n}\n"
  }
]