diff --git a/README.md b/README.md index c62c440..cf8cbc3 100644 --- a/README.md +++ b/README.md @@ -51,10 +51,15 @@ This app is a simplified version of **Vinted**, following a similar layout. Belo - **Frontend:** - React using Vite. + + ## Integration with discord **Discord commands** +- You can check your top tokens in binance wallet, however **BINANCE_API_KEY** and **BINANCE_SECRET_KEY** is required in **ENV** file + ![BinanceTokens](/readmeImages/BinanceAccountCommand.png) + - Profile ![Profile Command](/readmeImages/Profile%20command.png) - Inventory + removing product ![Inventory command](/readmeImages/Inventory%20command.png) diff --git a/client/ecommerce/.env.production b/client/ecommerce/.env.production new file mode 100644 index 0000000..60062d6 --- /dev/null +++ b/client/ecommerce/.env.production @@ -0,0 +1 @@ +VITE_BASE_URL=https://ecommerce-123.onrender.com \ No newline at end of file diff --git a/client/ecommerce/src/api/axios.tsx b/client/ecommerce/src/api/axios.tsx index 7040276..06cf3e8 100644 --- a/client/ecommerce/src/api/axios.tsx +++ b/client/ecommerce/src/api/axios.tsx @@ -26,12 +26,8 @@ import { ResponseOAuthInterceptor } from "./response-auth.interceptor"; import { FeedbackFormData } from "../components/FeedbackDialog"; import { ResponseErrorInterceptor } from "./responseError.interceptor"; const LIMIT = 8; -const baseUrl = "http://localhost:3000"; -// if (import.meta.env.VITE_NETLIFY == "true") { -// baseUrl = "https://ecommerce-123.onrender.com"; -// } else { -// baseUrl = "http://localhost:3000"; -// } +const baseUrl = import.meta.env.VITE_BASE_URL; + const ACCESS_TOKEN_KEY = "accessToken"; export const axiosApi = axios.create({ diff --git a/client/ecommerce/src/components/DiscordSignInButton.tsx b/client/ecommerce/src/components/DiscordSignInButton.tsx index b7c66fa..d4a57d6 100644 --- a/client/ecommerce/src/components/DiscordSignInButton.tsx +++ b/client/ecommerce/src/components/DiscordSignInButton.tsx @@ -2,10 +2,11 @@ import { Box, BoxProps, Link, Typography } from "@mui/material"; import { DiscordIcon } from "./DiscordIcon"; export const DiscordSignInButton = (props: BoxProps) => { + const baseURL = import.meta.env.VITE_BASE_URL; return ( { }, }} > - + SIGN IN diff --git a/client/ecommerce/src/components/pages/MainPage.tsx b/client/ecommerce/src/components/pages/MainPage.tsx index d648fa1..9f10737 100644 --- a/client/ecommerce/src/components/pages/MainPage.tsx +++ b/client/ecommerce/src/components/pages/MainPage.tsx @@ -6,8 +6,11 @@ import { useAllProducts } from "../../hooks/useAllProducts"; import { PaginatedProducts } from "../PaginatedProducts"; import { MainPageSkeleton } from "../skeletons/MainPageSkeleton"; import { NotAuthed } from "../NotAuthed"; +import { useLocation } from "wouter"; export const MainPage = () => { + const location = useLocation(); + console.log(location); const { user, setUser } = useUserContext(); const { data: products, isLoading: isProductsDataLoading } = useAllProducts(); const { diff --git a/readmeImages/BinanceAccountCommand.png b/readmeImages/BinanceAccountCommand.png new file mode 100644 index 0000000..b1cd74a Binary files /dev/null and b/readmeImages/BinanceAccountCommand.png differ diff --git a/server/ecommerce/package-lock.json b/server/ecommerce/package-lock.json index 25f44a4..5cc16a5 100644 --- a/server/ecommerce/package-lock.json +++ b/server/ecommerce/package-lock.json @@ -22,6 +22,7 @@ "@types/jsonwebtoken": "^9.0.5", "@types/passport-oauth2": "^1.4.15", "bcrypt": "^5.1.1", + "binance-api-node": "^0.12.7", "cookie-parser": "^1.4.6", "discord-api-types": "^0.37.84", "discord.js": "^14.15.2", @@ -4823,6 +4824,51 @@ "node": ">=0.6" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binance-api-node": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/binance-api-node/-/binance-api-node-0.12.7.tgz", + "integrity": "sha512-hEIPaZg1YwZClOznAJo5Zb1JyxsqdYjT8twG48rhOwhbNVrLJRxkeGj+PTa881wFXOtyOtyrXsDytsEcI2EUHA==", + "dependencies": { + "https-proxy-agent": "^5.0.0", + "isomorphic-fetch": "^3.0.0", + "isomorphic-ws": "^4.0.1", + "json-bigint": "^1.0.0", + "lodash.zipobject": "^4.1.3", + "reconnecting-websocket": "^4.2.0", + "ws": "^7.2.0" + }, + "engines": { + "yarn": ">= 1.0.0" + } + }, + "node_modules/binance-api-node/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -8114,6 +8160,23 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -8859,6 +8922,14 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -9080,6 +9151,11 @@ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" }, + "node_modules/lodash.zipobject": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz", + "integrity": "sha512-A9SzX4hMKWS25MyalwcOnNoplyHbkNVsjidhTp8ru0Sj23wY9GWBKS8gAIGDSAqeWjIjvE4KBEl24XXAs+v4wQ==" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -10933,6 +11009,11 @@ "node": ">= 0.10" } }, + "node_modules/reconnecting-websocket": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz", + "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==" + }, "node_modules/reflect-metadata": { "version": "0.1.14", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", @@ -12984,6 +13065,11 @@ "node": ">=4.0" } }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", diff --git a/server/ecommerce/package.json b/server/ecommerce/package.json index 4a9c046..df948cb 100644 --- a/server/ecommerce/package.json +++ b/server/ecommerce/package.json @@ -39,6 +39,7 @@ "@types/jsonwebtoken": "^9.0.5", "@types/passport-oauth2": "^1.4.15", "bcrypt": "^5.1.1", + "binance-api-node": "^0.12.7", "cookie-parser": "^1.4.6", "discord-api-types": "^0.37.84", "discord.js": "^14.15.2", diff --git a/server/ecommerce/src/auth/auth.controller.ts b/server/ecommerce/src/auth/auth.controller.ts index 5798eb8..08eefe5 100644 --- a/server/ecommerce/src/auth/auth.controller.ts +++ b/server/ecommerce/src/auth/auth.controller.ts @@ -96,10 +96,11 @@ export class AuthController { httpOnly: true, maxAge: 60 * 60 * 1000, }); + if (process.env.IS_DEV == 'true') { - response.redirect('http://localhost:5173'); + return response.redirect('http://localhost:5173'); } else { - response.redirect('https://exquisite-pasca-338883.netlify.app'); + return response.redirect('https://exquisite-pasca-338883.netlify.app'); } } } diff --git a/server/ecommerce/src/auth/utils/DiscordStrategy.ts b/server/ecommerce/src/auth/utils/DiscordStrategy.ts index 9da00b4..ef9a567 100644 --- a/server/ecommerce/src/auth/utils/DiscordStrategy.ts +++ b/server/ecommerce/src/auth/utils/DiscordStrategy.ts @@ -29,7 +29,10 @@ export class DiscordStrategy extends PassportStrategy(Strategy, 'discord') { tokenURL: TOKEN_URL, clientID: process.env.DISCORD_CLIENT_ID ?? '', clientSecret: process.env.DISCORD_CLIENT_SECRET ?? '', - callbackURL: process.env.DISCORD_REDIRECT_URL ?? '', + callbackURL: + process.env.IS_DEV == 'true' + ? process.env.DISCORD_REDIRECT_URL_DEV + : process.env.DISCORD_REDIRECT_URL_PRO, scope: ['identify', 'guilds'], } as StrategyOptions); this.logger = new Logger(DiscordStrategy.name); diff --git a/server/ecommerce/src/binance/binance.service.ts b/server/ecommerce/src/binance/binance.service.ts index 796bc55..5f85f7a 100644 --- a/server/ecommerce/src/binance/binance.service.ts +++ b/server/ecommerce/src/binance/binance.service.ts @@ -69,9 +69,7 @@ export class BinanceService { balancesWithTotalValueCalculated, ); - const revertedBalances = this.revertBalances(sortedBalances); - - const topBalances = revertedBalances.slice(0, numberOfTopBalances); + const topBalances = sortedBalances.slice(0, numberOfTopBalances); return topBalances; }; @@ -84,18 +82,6 @@ export class BinanceService { ); }; - private revertBalances = ( - balances: BinanceBalanceWithTotalValueAndSymbol[], - ) => { - return balances.map((balance) => ({ - asset: balance.asset, - free: balance.free, - locked: balance.locked, - symbol: balance.symbol, - totalValue: balance.totalValue, - })); - }; - private addTotalValueAndCurrencySymbolToBalances = async ( balances: BinanceBalance[], currencyName?: string, diff --git a/server/ecommerce/src/discord-bot/src/discordbot.ts b/server/ecommerce/src/discord-bot/src/discordbot.ts index f9442a8..738866c 100644 --- a/server/ecommerce/src/discord-bot/src/discordbot.ts +++ b/server/ecommerce/src/discord-bot/src/discordbot.ts @@ -59,8 +59,19 @@ export class DiscordBot { }; private handleCommand = async (interaction: ChatInputCommandInteraction) => { + const userId = interaction.user.id; const command = this.commands.get(interaction.commandName); + const commandName = interaction.commandName; if (!command) return; + if ( + commandName == 'binance-account' && + userId !== process.env.MY_DISCORD_ID + ) { + await interaction.reply({ + content: + 'You are not authorized to use this command! Only project owner can use this command', + }); + } try { await command.execute(interaction); } catch (error) {