From f3bc9a957069c2c20aef90019f0ae5fa9a2c302a Mon Sep 17 00:00:00 2001 From: Lncvrt Date: Mon, 21 Jul 2025 18:44:22 -0700 Subject: [PATCH] Use encrypted endpoint --- package.json | 2 ++ src/enums/Keys.ts | 4 ++++ src/routes/Leaderboards.tsx | 37 ++++++++++++++++++++++++++------ src/types/LeaderboardEntry.ts | 8 +++++-- src/util/Encryption.ts | 40 +++++++++++++++++++++++++++++++++++ yarn.lock | 10 +++++++++ 6 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/enums/Keys.ts create mode 100644 src/util/Encryption.ts diff --git a/package.json b/package.json index 6760159..41c36fb 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,11 @@ "@fortawesome/react-fontawesome": "0.2.2", "@tailwindcss/postcss": "4.1.11", "@tauri-apps/cli": "2.7.0", + "@types/crypto-js": "4.2.2", "@types/react": "19.1.8", "@types/react-dom": "19.1.6", "@vitejs/plugin-react": "4.7.0", + "crypto-js": "4.2.0", "postcss": "8.5.6", "tailwindcss": "4.1.11", "typescript": "5.8.3", diff --git a/src/enums/Keys.ts b/src/enums/Keys.ts new file mode 100644 index 0000000..0a5d523 --- /dev/null +++ b/src/enums/Keys.ts @@ -0,0 +1,4 @@ +export enum Keys { + SERVER_RECEIVE_TRANSFER_KEY = '', + SERVER_SEND_TRANSFER_KEY = '' +} diff --git a/src/routes/Leaderboards.tsx b/src/routes/Leaderboards.tsx index e0cd437..cda9ca7 100644 --- a/src/routes/Leaderboards.tsx +++ b/src/routes/Leaderboards.tsx @@ -2,15 +2,34 @@ import { useEffect, useState } from 'react' import './Leaderboards.css' import axios from 'axios' import { LeaderboardEntry } from '../types/LeaderboardEntry' +import { app } from '@tauri-apps/api' +import { platform } from '@tauri-apps/plugin-os' +import { decrypt, encrypt } from '../util/Encryption' -export default function Leaderboards() { +export default function Leaderboards () { const [leaderboardData, setLeaderboardData] = useState([]) - function refresh() { + async function refresh () { setLeaderboardData([]) + const launcherVersion = await app.getVersion() axios - .get('https://berrydash.lncvrt.xyz/database/getTopPlayersAPI.php') - .then(res => setLeaderboardData(res.data)) + .post( + 'https://berrydash.lncvrt.xyz/database/getTopPlayers.php', + { + [encrypt('type')]: encrypt('0') + }, + { + headers: { + Requester: 'BerryDashLauncher', + LauncherVersion: launcherVersion, + ClientPlatform: platform() + } + } + ) + .then(res => { + const decrypted = decrypt(res.data) + setLeaderboardData(JSON.parse(decrypted)) + }) .catch(e => console.error('Error fetching leaderboard data:', e)) } @@ -22,15 +41,19 @@ export default function Leaderboards() {

Leaderboards

- +
{leaderboardData.length ? ( leaderboardData.map((entry, i) => (
-

#{i + 1} {entry.username}

-

{entry.scoreFormatted}

+

+ #{i + 1} {entry.username} +

+

{entry.value}

)) ) : ( diff --git a/src/types/LeaderboardEntry.ts b/src/types/LeaderboardEntry.ts index aa742a5..eb5245c 100644 --- a/src/types/LeaderboardEntry.ts +++ b/src/types/LeaderboardEntry.ts @@ -1,5 +1,9 @@ export interface LeaderboardEntry { username: string - score: bigint - scoreFormatted: string + userid: bigint + value: bigint + icon: number + overlay: number + birdColor: number[] + overlayColor: number[] } diff --git a/src/util/Encryption.ts b/src/util/Encryption.ts new file mode 100644 index 0000000..27b13ed --- /dev/null +++ b/src/util/Encryption.ts @@ -0,0 +1,40 @@ +import CryptoJS from 'crypto-js' +import { Keys } from '../enums/Keys' + +export function encrypt (plainText: string): string { + const iv = CryptoJS.lib.WordArray.random(16) + const encrypted = CryptoJS.AES.encrypt( + plainText, + CryptoJS.enc.Utf8.parse(Keys.SERVER_SEND_TRANSFER_KEY), + { + iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + } + ) + const combined = iv.concat(encrypted.ciphertext) + return CryptoJS.enc.Base64.stringify(combined) +} + +export function decrypt (dataB64: string): string { + const data = CryptoJS.enc.Base64.parse(dataB64) + const iv = CryptoJS.lib.WordArray.create(data.words.slice(0, 4), 16) + const ciphertext = CryptoJS.lib.WordArray.create( + data.words.slice(4), + data.sigBytes - 16 + ) + const cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext }) + + const decrypted = CryptoJS.AES.decrypt( + cipherParams, + CryptoJS.enc.Utf8.parse(Keys.SERVER_RECEIVE_TRANSFER_KEY), + { + iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + } + ) + const result = decrypted.toString(CryptoJS.enc.Utf8) + if (!result) throw new Error(encrypt('-997')) + return result +} diff --git a/yarn.lock b/yarn.lock index 41fa05a..778ceca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -779,6 +779,11 @@ dependencies: "@babel/types" "^7.20.7" +"@types/crypto-js@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.2.2.tgz#771c4a768d94eb5922cc202a3009558204df0cea" + integrity sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ== + "@types/estree@1.0.8": version "1.0.8" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" @@ -862,6 +867,11 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +crypto-js@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + csstype@^3.0.2: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"