From 9aa850db6f9960d1ee4a791e7df3b4ea85012bd5 Mon Sep 17 00:00:00 2001 From: JeelRajodiya Date: Sun, 20 Aug 2023 18:49:12 +0530 Subject: [PATCH 1/5] refactor: added shell for api --- server/app.ts | 24 +++++++++++++----------- server/util/functions.ts | 8 ++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/server/app.ts b/server/app.ts index 7b8c139..5260788 100644 --- a/server/app.ts +++ b/server/app.ts @@ -1,5 +1,4 @@ -import { loadEnvVariables } from "./util/functions"; - +import { loadEnvVariables, updateLeaderboard } from "./util/functions"; loadEnvVariables(__dirname); // keep the above imports always at the top they are used to load the environment variables @@ -9,7 +8,6 @@ import WebSocket from "ws"; import redisClient from "./util/redis"; var app = express(); - app.use("/", async function (req: Request, res: Response, next) { const count = await redisClient.incr("count"); @@ -17,14 +15,17 @@ app.use("/", async function (req: Request, res: Response, next) { }); function webSocketHandler(ws: WebSocket) { - ws.on("message", function (message: string) { - console.log("received: %s", message); - }); - let i = 0; - let interval = setInterval(() => { - ws.send(i); - i += 10; - }, 10000); + let interval = setInterval(async () => { + const leaderboard = await redisClient.get("leaderboard"); + if (!leaderboard) + return ws.send( + JSON.stringify({ + leaderboard: [], + }) + ); + + ws.send(leaderboard); + }, 1000); ws.send("something"); ws.on("close", function () { @@ -32,5 +33,6 @@ function webSocketHandler(ws: WebSocket) { clearInterval(interval); }); } +setInterval(() => updateLeaderboard(redisClient as any), 10000); export default app; export { webSocketHandler }; diff --git a/server/util/functions.ts b/server/util/functions.ts index 295d984..c528b53 100644 --- a/server/util/functions.ts +++ b/server/util/functions.ts @@ -1,6 +1,8 @@ import fs from "fs"; import dotenv from "dotenv"; import path from "path"; +import { RedisClientType } from "redis"; + const requiredEnvVariables = ["REDIS_PASS", "REDIS_HOST"]; export function loadEnvVariables(dirname: string): void { try { @@ -42,3 +44,9 @@ export function normalizePort(val: string) { return false; } + +export async function updateLeaderboard(redisClient: RedisClientType) { + // fetch the json data from the codeforces api + const data = {}; // fetched data + await redisClient.set("leaderboard", JSON.stringify(data)); +} From 75889fee6c164fb6f6e657f83eabb9b7ac781737 Mon Sep 17 00:00:00 2001 From: Saumya Date: Sun, 20 Aug 2023 21:58:36 +0530 Subject: [PATCH 2/5] fetching standings data from cf --- server/app.ts | 6 +++++- server/package-lock.json | 12 ++++++++++++ server/package.json | 1 + server/util/functions.ts | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/app.ts b/server/app.ts index 7b8c139..d105b7c 100644 --- a/server/app.ts +++ b/server/app.ts @@ -1,4 +1,5 @@ import { loadEnvVariables } from "./util/functions"; +import { updateLeaderboard } from "./util/functions"; loadEnvVariables(__dirname); // keep the above imports always at the top they are used to load the environment variables @@ -32,5 +33,8 @@ function webSocketHandler(ws: WebSocket) { clearInterval(interval); }); } + +setInterval(() => updateLeaderboard(redisClient as any, 468732)); + export default app; -export { webSocketHandler }; +export { webSocketHandler }; \ No newline at end of file diff --git a/server/package-lock.json b/server/package-lock.json index 7b2678a..adeb00f 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@types/express": "^4.17.17", "cookie-parser": "^1.4.6", + "crypto": "^1.0.1", "dotenv": "^16.3.1", "express": "^4.18.2", "morgan": "^1.10.0", @@ -512,6 +513,12 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." + }, "node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -1891,6 +1898,11 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" + }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", diff --git a/server/package.json b/server/package.json index 26452a4..e6f610f 100644 --- a/server/package.json +++ b/server/package.json @@ -16,6 +16,7 @@ "dependencies": { "@types/express": "^4.17.17", "cookie-parser": "^1.4.6", + "crypto": "^1.0.1", "dotenv": "^16.3.1", "express": "^4.18.2", "morgan": "^1.10.0", diff --git a/server/util/functions.ts b/server/util/functions.ts index 295d984..c42c9e2 100644 --- a/server/util/functions.ts +++ b/server/util/functions.ts @@ -1,6 +1,9 @@ import fs from "fs"; import dotenv from "dotenv"; import path from "path"; +import { RedisClientType } from "redis"; +import crypto from 'crypto'; + const requiredEnvVariables = ["REDIS_PASS", "REDIS_HOST"]; export function loadEnvVariables(dirname: string): void { try { @@ -42,3 +45,17 @@ export function normalizePort(val: string) { return false; } + +export async function updateLeaderboard(redisClient: RedisClientType, contestId: number) { + const curr_time = Math.floor(new Date().getTime()/1000); + const apiKey = process.env.CF_API_KEY + const secret = process.env.CF_SECRET + + const signature = crypto.createHash('sha512').update(`123456/contest.standings?apiKey=${apiKey}&contestId=${contestId}&time=${curr_time}#${secret}`).digest('hex'); + + const requestUrl = `https://codeforces.com/api/contest.standings?contestId=${contestId}&apiKey=${apiKey}&time=${curr_time}&apiSig=123456${signature}`; + + const resp = await fetch(requestUrl); + const data = await resp.json(); + await redisClient.set("leaderboard", JSON.stringify(data)); +} \ No newline at end of file From 3ac80884d90d36b9bc6147e20ddd38176693bd29 Mon Sep 17 00:00:00 2001 From: JeelRajodiya Date: Sun, 20 Aug 2023 23:04:14 +0530 Subject: [PATCH 3/5] fix: fetch not defined --- server/app.ts | 3 +- server/package-lock.json | 270 ++++++++++++++++++++++++++++++--------- server/package.json | 4 +- server/server.ts | 2 +- server/util/functions.ts | 34 +++-- 5 files changed, 242 insertions(+), 71 deletions(-) diff --git a/server/app.ts b/server/app.ts index 8da8f43..311bb72 100644 --- a/server/app.ts +++ b/server/app.ts @@ -35,4 +35,5 @@ function webSocketHandler(ws: WebSocket) { } setInterval(() => updateLeaderboard(redisClient as any, 468732), 10000); export default app; -export { webSocketHandler}; \ No newline at end of file + +export { webSocketHandler }; diff --git a/server/package-lock.json b/server/package-lock.json index 618d97d..d77872d 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,11 +10,13 @@ "dependencies": { "@types/express": "^4.17.17", "cookie-parser": "^1.4.6", + "cross-fetch": "^4.0.0", "crypto": "^1.0.1", - "cryptos": "^1.2.4", + "cryptos": "^1.0.0", "dotenv": "^16.3.1", "express": "^4.18.2", "morgan": "^1.10.0", + "node-fetch": "^3.3.2", "nodemon": "^3.0.1", "redis": "^4.6.7", "typescript": "^5.1.6", @@ -312,11 +314,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "node_modules/asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha512-6i37w/+EhlWlGUJff3T/Q8u1RGmP5wgbiwYnOnbOqvtrPxT63/sYFyP9RcpxtxGymtfA075IvmOnL7ycNOWl3w==" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -519,27 +516,50 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/crypto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." }, - "node_modules/cryptojs": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/cryptojs/-/cryptojs-2.5.3.tgz", - "integrity": "sha512-+rdPl1UCxE8s3R94NNn+zMKOiI4MJ7dyh3X0c5uBL3btDr4zQ6acd7f9mY7Wb5MrccZEi2Rrha3OEtLcc5XXog==", - "engines": { - "node": "*" - } - }, "node_modules/cryptos": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/cryptos/-/cryptos-1.2.4.tgz", - "integrity": "sha512-vMbNQPQpCkZajEte1m/IB2LIZMCkI0+IpEk7S2zHssz2t3N3MjgKoUf7TkXIfyDmPiWkVazHHhShgAyNcXK9ug==", - "dependencies": { - "cryptojs": "~2.5.3", - "node-rsa": "^0.2.25" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cryptos/-/cryptos-1.0.0.tgz", + "integrity": "sha512-f3QBXSYMhpDmy68vFp7nu6IH0Dd+okUJ9AMu9H0pDP8deUdjRWgG7bzkPbqzRo5INRdin38s8tI+cgo9AhvTCA==" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" } }, "node_modules/debug": { @@ -667,6 +687,28 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -708,6 +750,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -898,11 +951,6 @@ "node": ">=0.12.0" } }, - "node_modules/lodash": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.3.0.tgz", - "integrity": "sha512-gpux6tVfBHsUdUIciz5HoV0ChAxUTvi0ChpQMIjAsKtg6FTYFtd1B1G0JlqHvAio3teaMVGPDPk2seVq1INwOQ==" - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1034,13 +1082,39 @@ "node": ">= 0.6" } }, - "node_modules/node-rsa": { - "version": "0.2.30", - "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-0.2.30.tgz", - "integrity": "sha512-Tg5XrlbigFm6rek1UoIIPRHRbisJL8MhVvzx6xl/bNMaW3qRKQYJSswHsQOnoa/zTLaRG/uKht+XisA71P8U4Q==", + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dependencies": { - "asn1": "0.2.3", - "lodash": "3.3.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/nodemon": { @@ -1386,6 +1460,11 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -1488,6 +1567,28 @@ "node": ">= 0.8" } }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", @@ -1775,11 +1876,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha512-6i37w/+EhlWlGUJff3T/Q8u1RGmP5wgbiwYnOnbOqvtrPxT63/sYFyP9RcpxtxGymtfA075IvmOnL7ycNOWl3w==" - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1940,24 +2036,38 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "requires": { + "node-fetch": "^2.6.12" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "requires": { + "whatwg-url": "^5.0.0" + } + } + } + }, "crypto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" }, - "cryptojs": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/cryptojs/-/cryptojs-2.5.3.tgz", - "integrity": "sha512-+rdPl1UCxE8s3R94NNn+zMKOiI4MJ7dyh3X0c5uBL3btDr4zQ6acd7f9mY7Wb5MrccZEi2Rrha3OEtLcc5XXog==" - }, "cryptos": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/cryptos/-/cryptos-1.2.4.tgz", - "integrity": "sha512-vMbNQPQpCkZajEte1m/IB2LIZMCkI0+IpEk7S2zHssz2t3N3MjgKoUf7TkXIfyDmPiWkVazHHhShgAyNcXK9ug==", - "requires": { - "cryptojs": "~2.5.3", - "node-rsa": "^0.2.25" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cryptos/-/cryptos-1.0.0.tgz", + "integrity": "sha512-f3QBXSYMhpDmy68vFp7nu6IH0Dd+okUJ9AMu9H0pDP8deUdjRWgG7bzkPbqzRo5INRdin38s8tI+cgo9AhvTCA==" + }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" }, "debug": { "version": "3.2.7", @@ -2061,6 +2171,15 @@ } } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2098,6 +2217,14 @@ } } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2227,11 +2354,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, - "lodash": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.3.0.tgz", - "integrity": "sha512-gpux6tVfBHsUdUIciz5HoV0ChAxUTvi0ChpQMIjAsKtg6FTYFtd1B1G0JlqHvAio3teaMVGPDPk2seVq1INwOQ==" - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2332,13 +2454,19 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, - "node-rsa": { - "version": "0.2.30", - "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-0.2.30.tgz", - "integrity": "sha512-Tg5XrlbigFm6rek1UoIIPRHRbisJL8MhVvzx6xl/bNMaW3qRKQYJSswHsQOnoa/zTLaRG/uKht+XisA71P8U4Q==", + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "requires": { - "asn1": "0.2.3", - "lodash": "3.3.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" } }, "nodemon": { @@ -2586,6 +2714,11 @@ "nopt": "~1.0.10" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -2647,6 +2780,25 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", diff --git a/server/package.json b/server/package.json index 0c2b6d5..e29afb4 100644 --- a/server/package.json +++ b/server/package.json @@ -16,11 +16,13 @@ "dependencies": { "@types/express": "^4.17.17", "cookie-parser": "^1.4.6", + "cross-fetch": "^4.0.0", "crypto": "^1.0.1", - "cryptos": "^1.2.4", + "cryptos": "^1.0.0", "dotenv": "^16.3.1", "express": "^4.18.2", "morgan": "^1.10.0", + "node-fetch": "^3.3.2", "nodemon": "^3.0.1", "redis": "^4.6.7", "typescript": "^5.1.6", diff --git a/server/server.ts b/server/server.ts index d2c2a57..da237fa 100644 --- a/server/server.ts +++ b/server/server.ts @@ -30,7 +30,7 @@ app.use(function ( res.render("error"); }); -var port = normalizePort(process.env.PORT || "3000"); +var port = normalizePort(process.env.PORT || "3001"); app.set("port", port); /** diff --git a/server/util/functions.ts b/server/util/functions.ts index c42c9e2..6f8729b 100644 --- a/server/util/functions.ts +++ b/server/util/functions.ts @@ -2,9 +2,14 @@ import fs from "fs"; import dotenv from "dotenv"; import path from "path"; import { RedisClientType } from "redis"; -import crypto from 'crypto'; - -const requiredEnvVariables = ["REDIS_PASS", "REDIS_HOST"]; +import crypto from "crypto"; +import fetch from "cross-fetch"; +const requiredEnvVariables = [ + "REDIS_PASS", + "REDIS_HOST", + "CF_SECRET", + "CF_API_KEY", +]; export function loadEnvVariables(dirname: string): void { try { const envFilePath = path.resolve(dirname, ".env"); @@ -46,16 +51,27 @@ export function normalizePort(val: string) { return false; } -export async function updateLeaderboard(redisClient: RedisClientType, contestId: number) { - const curr_time = Math.floor(new Date().getTime()/1000); - const apiKey = process.env.CF_API_KEY - const secret = process.env.CF_SECRET +export async function updateLeaderboard( + redisClient: RedisClientType, + contestId: number +) { + const curr_time = Math.floor(new Date().getTime() / 1000); + const apiKey = process.env.CF_API_KEY; + const secret = process.env.CF_SECRET; + if (!apiKey || !secret) { + throw new Error("API key or secret is missing"); + } - const signature = crypto.createHash('sha512').update(`123456/contest.standings?apiKey=${apiKey}&contestId=${contestId}&time=${curr_time}#${secret}`).digest('hex'); + const signature = crypto + .createHash("sha512") + .update( + `123456/contest.standings?apiKey=${apiKey}&contestId=${contestId}&time=${curr_time}#${secret}` + ) + .digest("hex"); const requestUrl = `https://codeforces.com/api/contest.standings?contestId=${contestId}&apiKey=${apiKey}&time=${curr_time}&apiSig=123456${signature}`; const resp = await fetch(requestUrl); const data = await resp.json(); await redisClient.set("leaderboard", JSON.stringify(data)); -} \ No newline at end of file +} From 2f584275dbabf78269a7b5a4c1e3e699ee1099b0 Mon Sep 17 00:00:00 2001 From: JeelRajodiya Date: Sun, 20 Aug 2023 23:33:48 +0530 Subject: [PATCH 4/5] feat: web socket works perfectly --- client/app/Test/page.tsx | 19 +++++++++++++++++++ server/app.ts | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 client/app/Test/page.tsx diff --git a/client/app/Test/page.tsx b/client/app/Test/page.tsx new file mode 100644 index 0000000..fb0091b --- /dev/null +++ b/client/app/Test/page.tsx @@ -0,0 +1,19 @@ +"use client"; +import { useEffect, useState } from "react"; + +export default function Test() { + const ws = new WebSocket("ws://localhost:3001"); + const [data, setData] = useState(null); + useEffect(() => { + ws.onmessage = (e) => { + // a message was received + + setData(e.data); + }; + return () => { + ws.close(); + }; + }, []); + + return
{data}
; +} diff --git a/server/app.ts b/server/app.ts index 311bb72..d1be599 100644 --- a/server/app.ts +++ b/server/app.ts @@ -33,7 +33,8 @@ function webSocketHandler(ws: WebSocket) { clearInterval(interval); }); } -setInterval(() => updateLeaderboard(redisClient as any, 468732), 10000); + +setInterval(() => updateLeaderboard(redisClient as any, 468732), 1000); export default app; export { webSocketHandler }; From 50164ca4af1ecb456ce63c6f98f73d23d9a69448 Mon Sep 17 00:00:00 2001 From: JeelRajodiya Date: Sun, 20 Aug 2023 23:36:45 +0530 Subject: [PATCH 5/5] refactor: dependencies --- server/app.ts | 2 +- server/package-lock.json | 127 --------------------------------------- server/package.json | 1 - 3 files changed, 1 insertion(+), 129 deletions(-) diff --git a/server/app.ts b/server/app.ts index d1be599..b670265 100644 --- a/server/app.ts +++ b/server/app.ts @@ -34,7 +34,7 @@ function webSocketHandler(ws: WebSocket) { }); } -setInterval(() => updateLeaderboard(redisClient as any, 468732), 1000); +setInterval(() => updateLeaderboard(redisClient as any, 468732), 4000); export default app; export { webSocketHandler }; diff --git a/server/package-lock.json b/server/package-lock.json index d77872d..1fa6c1d 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -16,7 +16,6 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "morgan": "^1.10.0", - "node-fetch": "^3.3.2", "nodemon": "^3.0.1", "redis": "^4.6.7", "typescript": "^5.1.6", @@ -554,14 +553,6 @@ "resolved": "https://registry.npmjs.org/cryptos/-/cryptos-1.0.0.tgz", "integrity": "sha512-f3QBXSYMhpDmy68vFp7nu6IH0Dd+okUJ9AMu9H0pDP8deUdjRWgG7bzkPbqzRo5INRdin38s8tI+cgo9AhvTCA==" }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "engines": { - "node": ">= 12" - } - }, "node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -687,28 +678,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -750,17 +719,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1082,41 +1040,6 @@ "node": ">= 0.6" } }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, "node_modules/nodemon": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", @@ -1567,14 +1490,6 @@ "node": ">= 0.8" } }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -2064,11 +1979,6 @@ "resolved": "https://registry.npmjs.org/cryptos/-/cryptos-1.0.0.tgz", "integrity": "sha512-f3QBXSYMhpDmy68vFp7nu6IH0Dd+okUJ9AMu9H0pDP8deUdjRWgG7bzkPbqzRo5INRdin38s8tI+cgo9AhvTCA==" }, - "data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" - }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -2171,15 +2081,6 @@ } } }, - "fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2217,14 +2118,6 @@ } } }, - "formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "requires": { - "fetch-blob": "^3.1.2" - } - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2454,21 +2347,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" - }, - "node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, "nodemon": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", @@ -2780,11 +2658,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, - "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" - }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/server/package.json b/server/package.json index e29afb4..8147ccd 100644 --- a/server/package.json +++ b/server/package.json @@ -22,7 +22,6 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "morgan": "^1.10.0", - "node-fetch": "^3.3.2", "nodemon": "^3.0.1", "redis": "^4.6.7", "typescript": "^5.1.6",