Add signature checking to requests
This commit is contained in:
10 files changed
+118
-40
No files matched your search
@@ -2,12 +2,13 @@
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { BirdColor } from '@/types/BerryDash/BirdColor'
|
||||
import axios from 'axios'
|
||||
import { GetIconForUser } from '@/lib/BerryDash'
|
||||
import Image from 'next/image'
|
||||
import './styles.css'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { platform } from '@tauri-apps/plugin-os'
|
||||
import { fetch } from '@tauri-apps/plugin-http'
|
||||
import { verifySignature } from '@/lib/Util'
|
||||
|
||||
interface BaseEntry {
|
||||
id: number
|
||||
@@ -90,11 +91,16 @@ export default function BerryDashLeaderboards () {
|
||||
const Refresh = useCallback(async () => {
|
||||
try {
|
||||
if (selected == 3 || selected == 4) {
|
||||
const result = await axios.get(
|
||||
const response = await fetch(
|
||||
'https://games.lncvrt.xyz/api/berrydash/account?username='
|
||||
)
|
||||
if (result.data.success) {
|
||||
let accounts = result.data.data as Account[]
|
||||
const signature = response.headers.get('x-signature') ?? ''
|
||||
const data = await response.json()
|
||||
if (
|
||||
(await verifySignature(JSON.stringify(data), signature)) &&
|
||||
data.success
|
||||
) {
|
||||
let accounts = data.data as Account[]
|
||||
|
||||
accounts = accounts.map(acc => {
|
||||
const xp = calculateXP(
|
||||
@@ -114,9 +120,9 @@ export default function BerryDashLeaderboards () {
|
||||
accounts.sort((a, b) => (b.xp > a.xp ? 1 : b.xp < a.xp ? -1 : 0))
|
||||
|
||||
setEntries(accounts)
|
||||
}
|
||||
} else console.log('Failed')
|
||||
} else {
|
||||
const result = await axios.get(
|
||||
const response = await fetch(
|
||||
'https://games.lncvrt.xyz/api/berrydash/leaderboard/' +
|
||||
(selected == 0
|
||||
? 'score'
|
||||
@@ -128,9 +134,13 @@ export default function BerryDashLeaderboards () {
|
||||
? 'legacy'
|
||||
: 'total')
|
||||
)
|
||||
if (result.data.success) {
|
||||
setEntries(result.data.data as LeaderboardEntry[])
|
||||
}
|
||||
const signature = response.headers.get('x-signature') ?? ''
|
||||
const data = await response.json()
|
||||
if (
|
||||
(await verifySignature(JSON.stringify(data), signature)) &&
|
||||
data.success
|
||||
)
|
||||
setEntries(data.data as LeaderboardEntry[])
|
||||
}
|
||||
} catch {
|
||||
setEntries([])
|
||||
|
||||
+30
-10
@@ -15,7 +15,6 @@ import {
|
||||
import { VersionsConfig } from '@/types/VersionsConfig'
|
||||
import { NormalConfig } from '@/types/NormalConfig'
|
||||
import { app } from '@tauri-apps/api'
|
||||
import axios from 'axios'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { GlobalProvider } from './GlobalProvider'
|
||||
import { Roboto } from 'next/font/google'
|
||||
@@ -36,6 +35,8 @@ import VersionsDownloadPopup from '@/componets/popups/VersionsDownload'
|
||||
import GamesDownloadPopup from '@/componets/popups/GamesDownload'
|
||||
import DownloadsPopup from '@/componets/popups/Downloads'
|
||||
import VersionVersionPopup from '@/componets/popups/VersionVersion'
|
||||
import { fetch } from '@tauri-apps/plugin-http'
|
||||
import { verifySignature } from '@/lib/Util'
|
||||
|
||||
const roboto = Roboto({
|
||||
subsets: ['latin']
|
||||
@@ -252,11 +253,18 @@ export default function RootLayout ({
|
||||
setVersion(client)
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
const response = await fetch(
|
||||
'https://games.lncvrt.xyz/api/launcher/latest'
|
||||
)
|
||||
if (response.data !== client) {
|
||||
setOutdated(true)
|
||||
const signature = response.headers.get('x-signature') ?? ''
|
||||
const data = await response.text()
|
||||
if (await verifySignature(data, signature)) {
|
||||
if (data !== client) {
|
||||
setOutdated(true)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
setLoadingText('Failed to check latest version.')
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
@@ -265,10 +273,17 @@ export default function RootLayout ({
|
||||
}
|
||||
}
|
||||
try {
|
||||
const res = await axios.get(
|
||||
const response = await fetch(
|
||||
`https://games.lncvrt.xyz/api/launcher/versions?platform=${platform()}&arch=${arch()}`
|
||||
)
|
||||
setServerVersionList(res.data)
|
||||
const signature = response.headers.get('x-signature') ?? ''
|
||||
const data = await response.json()
|
||||
if (await verifySignature(JSON.stringify(data), signature)) {
|
||||
setServerVersionList(data)
|
||||
} else {
|
||||
setLoadingText('Failed to download versions list.')
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
setLoadingText('Failed to download versions list.')
|
||||
return
|
||||
@@ -348,13 +363,18 @@ export default function RootLayout ({
|
||||
prev.map(d => (d.version === versionId ? { ...d, queued: false } : d))
|
||||
)
|
||||
|
||||
const downloadInfoRequest = await axios.get(
|
||||
const downloadInfoRequest = await fetch(
|
||||
'https://games.lncvrt.xyz/api/launcher/download?gameId=' +
|
||||
info.id +
|
||||
'&downloadId=' +
|
||||
info.download
|
||||
)
|
||||
if (!downloadInfoRequest.data.success) {
|
||||
const signature = downloadInfoRequest.headers.get('x-signature') ?? ''
|
||||
const data = await downloadInfoRequest.json()
|
||||
if (
|
||||
!(await verifySignature(JSON.stringify(data), signature)) ||
|
||||
!data.success
|
||||
) {
|
||||
setDownloadProgress(prev =>
|
||||
prev.map(d =>
|
||||
d.version === versionId
|
||||
@@ -371,10 +391,10 @@ export default function RootLayout ({
|
||||
}
|
||||
|
||||
const res = await invoke<string>('download', {
|
||||
url: downloadInfoRequest.data.data.url,
|
||||
url: data.data.url,
|
||||
name: info.id,
|
||||
executable: info.executable,
|
||||
hash: downloadInfoRequest.data.data.hash
|
||||
hash: data.data.hash
|
||||
})
|
||||
|
||||
if (res === '1') {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { message } from '@tauri-apps/plugin-dialog'
|
||||
import { BaseDirectory, exists, stat } from '@tauri-apps/plugin-fs'
|
||||
import { openPath } from '@tauri-apps/plugin-opener'
|
||||
import { join, appLocalDataDir } from '@tauri-apps/api/path'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
export const openFolder = async (name: string) => {
|
||||
const relativePath = await join('game', name)
|
||||
@@ -48,3 +49,16 @@ export const formatEtaSmart = (seconds: number) => {
|
||||
const h = Math.floor((seconds % 86400) / 3600)
|
||||
return `${d}d ${h}h`
|
||||
}
|
||||
|
||||
export const verifySignature = async (body: string, signature: string) => {
|
||||
try {
|
||||
const result = await invoke<boolean>('verify_signature', {
|
||||
body: body ?? '',
|
||||
signature: signature ?? '',
|
||||
publicKey: process.env.NEXT_PUBLIC_PUBLIC_SIGNING_KEY ?? ''
|
||||
})
|
||||
return Boolean(result)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user