diff --git a/.prettierignore b/.prettierignore index 0e796c3..e130c68 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,4 @@ node_modules dist -build \ No newline at end of file +build +/CHANGELOG.md \ No newline at end of file diff --git a/README.md b/README.md index 71147c5..850829d 100644 --- a/README.md +++ b/README.md @@ -31,41 +31,42 @@ ## 📖 About -This project is an open source initiative to host multiple steam bot accounts to trade inventory -items, automatically calculating the prices and items in each exchange sent and responding to them -at the same time, like some Trading Card Exchange bots, but with any item. We still have a lot to -improve, and that is what i'll do in the next days, Feel free to send a PR or open a new issue. +This project is an open source initiative to host multiple steam bot accounts to trade +inventory items, automatically calculating the prices and items in each exchange sent and +responding to them at the same time, like some Trading Card Exchange bots, but with any +item. We still have a lot to improve, and that is what i'll do in the next days, Feel free +to send a PR or open a new issue. ## 📁 Downloading -> _The main branch is used for development, to download the code, prefer to download a specific -> tag._ +> _The main branch is used for development, to download the code, prefer to download a +> specific tag._ Open this repository -releases tab -and download the latest source code **.zip** file. +releases +tab and download the latest source code **.zip** file. ## ⚙️ Configuration -A `config.json` file already existed in previous versions, however, now everything is officially -configured by our panel. To access it, start the application correctly and go to localhost at the -specified port. +A `config.json` file already existed in previous versions, however, now everything is +officially configured by our panel. To access it, start the application correctly and go +to localhost at the specified port. #### 🔐 SDA, Shared Secret and Identity Secret -To register a steam account with **steam-trader**, you need to know the `Shared Secret` and -`Identity Secret` of your account. These two secrets are responsible for the automatic generation of -the steam guard mobile code and auto reconnection. +To register a steam account with **steam-trader**, you need to know the `Shared Secret` +and `Identity Secret` of your account. These two secrets are responsible for the automatic +generation of the steam guard mobile code and auto reconnection. To get them easily, you will need to enable -SDA on the -account and after that, you will find it +SDA +on the account and after that, you will find it here. ## 🏃 Executing -You can host it docker on any hosting service that supports containerized applications or use docker -locally, simply by typing: +You can host it docker on any hosting service that supports containerized applications or +use docker locally, simply by typing: > _For any help with docker, here are the > docs._ @@ -78,10 +79,12 @@ $ docker-compose up $ docker-compose up -d ``` -If you have no access or knowledge to use Docker, you can run it having **Node.JS** installed. As we -have a `package.json` in our root containing some scripts, all you need to do is follow these steps. +If you have no access or knowledge to use Docker, you can run it having **Node.JS** +installed. As we have a `package.json` in our root containing some scripts, all you need +to do is follow these steps. -> _Always prefer to use Docker, as this application was built based on it and is totally faster._ +> _Always prefer to use Docker, as this application was built based on it and is totally +> faster._ ```sh # Install yarn and concurrently to run the next scripts. @@ -94,15 +97,15 @@ $ npm run build $ npm run start ``` -After building and installing it for the first time, you are ready to go and you can start it every -time only running the last command. +After building and installing it for the first time, you are ready to go and you can start +it every time only running the last command. ### Security -We assume that all connections are secure and trustworthy, so we don't require any passwords. If -you're hosting it on third-party services like AWS or Azure, make sure you only allow its IP address -to connect to the web interface and server. You can also use a proxy between authenticated -connections to prevent unauthorized requests. +We assume that all connections are secure and trustworthy, so we don't require any +passwords. If you're hosting it on third-party services like AWS or Azure, make sure you +only allow its IP address to connect to the web interface and server. You can also use a +proxy between authenticated connections to prevent unauthorized requests. ## 📃 License @@ -111,5 +114,6 @@ Licensed under the **GNU General Public License v3.0**. See ## 📧 Contact -See my contact information on my GitHub -Profile Page or open a new issue. +See my contact information on my +GitHub Profile Page or +open a new issue. diff --git a/SECURITY.md b/SECURITY.md index 4c62cb3..3e797b5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -14,4 +14,5 @@ ## Reporting a Vulnerability -**DO NOT CREATE AN ISSUE** to report a security problem. Instead, please send an email to arthurfiorette@gmail.com +**DO NOT CREATE AN ISSUE** to report a security problem. Instead, please send an email to +arthurfiorette@gmail.com diff --git a/app/src/accounts/account.ts b/app/src/accounts/account.ts index ba715dc..60ee024 100644 --- a/app/src/accounts/account.ts +++ b/app/src/accounts/account.ts @@ -27,9 +27,13 @@ export default class Account { this.client.on('webSession', (_sessionId: number, cookies: string[]) => this.onWebSession(cookies) ); - this.client.on('wallet', (_hasWallet: boolean, currency: number) => this.setCurrency(currency)); + this.client.on('wallet', (_hasWallet: boolean, currency: number) => + this.setCurrency(currency) + ); this.client.on('loggedOn', () => this.onLogin()); - this.client.on('disconnected', (_eResult: number, msg: string) => this.onDisconnect(msg)); + this.client.on('disconnected', (_eResult: number, msg: string) => + this.onDisconnect(msg) + ); this.client.on('steamGuard', (_domain: any, callback: (code: string) => void) => callback(this.getAuthCode()) ); diff --git a/app/src/logger.ts b/app/src/logger.ts index be71174..1fe4e77 100644 --- a/app/src/logger.ts +++ b/app/src/logger.ts @@ -17,7 +17,10 @@ function _createLogger(account: string, ..._transports: Transport[]) { return winston.createLogger({ ...levelFormat, defaultMeta: { account }, - transports: [new transports.Console({ format: combine(colorize(), cli()) }), ..._transports] + transports: [ + new transports.Console({ format: combine(colorize(), cli()) }), + ..._transports + ] }); } diff --git a/app/src/server/routes/users.ts b/app/src/server/routes/users.ts index 07c8069..54c77de 100644 --- a/app/src/server/routes/users.ts +++ b/app/src/server/routes/users.ts @@ -1,5 +1,13 @@ import { json, Router } from 'express'; -import { create, edit, getAll, getByName, login, logout, remove } from '../../accounts/controller'; +import { + create, + edit, + getAll, + getByName, + login, + logout, + remove +} from '../../accounts/controller'; const router = Router(); diff --git a/app/src/steam/market.ts b/app/src/steam/market.ts index 56d64e5..f8fa242 100644 --- a/app/src/steam/market.ts +++ b/app/src/steam/market.ts @@ -25,7 +25,10 @@ export function getItemName({ market_name, market_hash_name, name }: Item) { return name; } -function parseData({ success, lowest_price, median_price }: any, { parse }: ICurrency): ItemPrice { +function parseData( + { success, lowest_price, median_price }: any, + { parse }: ICurrency +): ItemPrice { return { success, lowest_price: parse(lowest_price), @@ -33,6 +36,9 @@ function parseData({ success, lowest_price, median_price }: any, { parse }: ICur }; } -export async function getAllItemsPrice(items: Item[], currency?: ICurrency): Promise { +export async function getAllItemsPrice( + items: Item[], + currency?: ICurrency +): Promise { return Promise.all(items.map((item) => getItemPrice(item, currency))); } diff --git a/app/src/storage/accounts.ts b/app/src/storage/accounts.ts index aac1067..849b6da 100644 --- a/app/src/storage/accounts.ts +++ b/app/src/storage/accounts.ts @@ -34,7 +34,9 @@ async function checkAccountOptions(options: AccountOptions[]) { async function handleInvalidAccountFile() { const newName = `accounts-invalid-${new Date().getTime()}.json`; - logger.error(`Invalid accounts.json, Renaming it to ${newName} and creating a new empty one...`); + logger.error( + `Invalid accounts.json, Renaming it to ${newName} and creating a new empty one...` + ); await fs.rename(accountsPath, join(configPath, newName)); await createAccountFileIfNeeded(); } @@ -47,7 +49,9 @@ async function createAccountFileIfNeeded() { fs .writeFile(accountsPath, '[]') .catch((err) => - logger.error(`Occurred an error while creating the config/accounts.json: ${err}`) + logger.error( + `Occurred an error while creating the config/accounts.json: ${err}` + ) ) ); } diff --git a/app/src/storage/logs.ts b/app/src/storage/logs.ts index 20ea3a5..e8e9a8e 100644 --- a/app/src/storage/logs.ts +++ b/app/src/storage/logs.ts @@ -10,7 +10,9 @@ function getPath(...paths: string[]) { fs.mkdir(getPath()).catch(() => {}); function getDate(fileName: string) { - return fileName !== 'system' ? '' : `-${new Date().toLocaleDateString().replace(/\//gi, '')}`; + return fileName !== 'system' + ? '' + : `-${new Date().toLocaleDateString().replace(/\//gi, '')}`; } export function getFileTransport(fileName: string) { diff --git a/app/src/storage/trades.ts b/app/src/storage/trades.ts index 771711b..86836d1 100644 --- a/app/src/storage/trades.ts +++ b/app/src/storage/trades.ts @@ -7,7 +7,11 @@ import { simplifyOffer } from './util'; const filePath = path.resolve(__dirname, `../../output/trades/`); fs.mkdir(filePath).catch(() => {}); -export async function writeOffer(context: OfferContext, reason: string, accepted: boolean) { +export async function writeOffer( + context: OfferContext, + reason: string, + accepted: boolean +) { const account = context.processor.account.options.login.username; context.processor.account.logger.debug(`Saving transaction ${context.id}`); @@ -18,11 +22,22 @@ export async function writeOffer(context: OfferContext, reason: string, accepted ); } -export async function emitOffer(context: OfferContext, reason: string, accepted: boolean) { +export async function emitOffer( + context: OfferContext, + reason: string, + accepted: boolean +) { const account = context.processor.account.options.login.username; io.emit('trade', simplifyOffer({ account, context, reason, accepted, mapItems: true })); } -export async function saveOffer(context: OfferContext, reason: string, accepted: boolean) { - return Promise.all([writeOffer(context, reason, accepted), emitOffer(context, reason, accepted)]); +export async function saveOffer( + context: OfferContext, + reason: string, + accepted: boolean +) { + return Promise.all([ + writeOffer(context, reason, accepted), + emitOffer(context, reason, accepted) + ]); } diff --git a/app/src/storage/util.ts b/app/src/storage/util.ts index 86642b7..0a46c66 100644 --- a/app/src/storage/util.ts +++ b/app/src/storage/util.ts @@ -9,7 +9,13 @@ type simplifyOptions = { mapItems: boolean; }; -export function simplifyOffer({ account, context, reason, accepted, mapItems }: simplifyOptions) { +export function simplifyOffer({ + account, + context, + reason, + accepted, + mapItems +}: simplifyOptions) { const { partner, id: offerId, itemsToGive, itemsToReceive, profit } = context; return { account, diff --git a/app/src/transactions/logic/calculatePrices.ts b/app/src/transactions/logic/calculatePrices.ts index 06224af..ac7646f 100644 --- a/app/src/transactions/logic/calculatePrices.ts +++ b/app/src/transactions/logic/calculatePrices.ts @@ -8,12 +8,9 @@ import { ItemPrice, OfferContext } from '../types'; export default async function middleware(context: OfferContext, next: NextFunction) { const { processor, itemsToReceive, itemsToGive } = context; const { options } = processor.account; - const currency = Currency[options.status.currency || 'USD'] + const currency = Currency[options.status.currency || 'USD']; - context.receiveItemsPrices = await getAllItemsPrice( - itemsToReceive, - currency - ); + context.receiveItemsPrices = await getAllItemsPrice(itemsToReceive, currency); if (context.receiveItemsPrices.some((item) => isTrash(item, options))) { processor.decline(context, Reason.TRASH); diff --git a/web/src/components/accounts/account.tsx b/web/src/components/accounts/account.tsx index e6fb2c9..431a285 100644 --- a/web/src/components/accounts/account.tsx +++ b/web/src/components/accounts/account.tsx @@ -1,6 +1,10 @@ import React, { useEffect, useState } from 'react'; import { Person, Power } from 'react-bootstrap-icons'; -import { getAccount, login as loginAcc, logout as logoutAcc } from '../../services/accounts'; +import { + getAccount, + login as loginAcc, + logout as logoutAcc +} from '../../services/accounts'; import socket from '../../services/socket'; import { AccountOptions } from '../../types'; import { ColoredButton, ColoredIconButton } from '../button'; diff --git a/web/src/components/accounts/forms/edit.tsx b/web/src/components/accounts/forms/edit.tsx index 5a8e89a..00b0a43 100644 --- a/web/src/components/accounts/forms/edit.tsx +++ b/web/src/components/accounts/forms/edit.tsx @@ -26,7 +26,9 @@ export const EditForm = (({ data = emptyAccount() }) => { }; const onChangeFactory = (cb: (val: any) => any) => { - return ({ target: { type, checked, value } }: React.ChangeEvent) => { + return ({ + target: { type, checked, value } + }: React.ChangeEvent) => { cb(type === 'checkbox' ? checked : value); setData({ login, status, trading }); }; diff --git a/web/src/components/accounts/forms/login.tsx b/web/src/components/accounts/forms/login.tsx index 8655b8d..3a1a363 100644 --- a/web/src/components/accounts/forms/login.tsx +++ b/web/src/components/accounts/forms/login.tsx @@ -21,7 +21,9 @@ export const LoginForm = (({}) => { }; const onChangeFactory = (cb: (val: any) => any) => { - return ({ target: { type, checked, value } }: React.ChangeEvent) => { + return ({ + target: { type, checked, value } + }: React.ChangeEvent) => { cb(type === 'checkbox' ? checked : value); setData({ login, status, trading }); }; diff --git a/web/src/components/button.tsx b/web/src/components/button.tsx index b9f12db..40072cb 100644 --- a/web/src/components/button.tsx +++ b/web/src/components/button.tsx @@ -15,7 +15,11 @@ const ButtonTemplate = (({ children, classes, ...props }) => { export const CloseButton = (({ classes, ariaLabel = 'Close', children, ...props }) => { return ( - + {children} ); diff --git a/web/src/components/offcanvas.tsx b/web/src/components/offcanvas.tsx index f7a350e..8005869 100644 --- a/web/src/components/offcanvas.tsx +++ b/web/src/components/offcanvas.tsx @@ -3,7 +3,11 @@ import { CloseButton } from './button'; export const Offcanvas = (({ id, title, children }) => { return ( -
+
{title} diff --git a/web/src/components/trades/items.tsx b/web/src/components/trades/items.tsx index 1a9b3b6..3c4df67 100644 --- a/web/src/components/trades/items.tsx +++ b/web/src/components/trades/items.tsx @@ -23,7 +23,9 @@ const ItemPicture = (({ item, received }) => { return (
  • {name} { return (