removed buffer polyfill, rewrite with js web standards
This commit is contained in:
@@ -17,22 +17,19 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-router-dom": "^6.13.0",
|
"react-router-dom": "^6.17.0",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1"
|
||||||
"uuid": "^9.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@modyfi/vite-plugin-yaml": "^1.0.4",
|
"@modyfi/vite-plugin-yaml": "^1.0.4",
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.8.7",
|
||||||
"@types/react": "^18.2.13",
|
"@types/react": "^18.2.29",
|
||||||
"@types/react-dom": "^18.2.6",
|
"@types/react-dom": "^18.2.14",
|
||||||
"@types/react-helmet": "^6.1.6",
|
"@types/react-helmet": "^6.1.8",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/uuid": "^9.0.2",
|
"@vitejs/plugin-react-swc": "^3.4.0",
|
||||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
"typescript": "^5.2.2",
|
||||||
"buffer": "^6.0.3",
|
"vite": "^4.5.0"
|
||||||
"typescript": "^5.1.3",
|
|
||||||
"vite": "^4.4.7"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,8 +14,7 @@ import {
|
|||||||
MenuItem,
|
MenuItem,
|
||||||
Paper,
|
Paper,
|
||||||
Select,
|
Select,
|
||||||
TextField,
|
TextField
|
||||||
styled
|
|
||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import AppBar from '@mui/material/AppBar'
|
import AppBar from '@mui/material/AppBar'
|
||||||
import Dialog from '@mui/material/Dialog'
|
import Dialog from '@mui/material/Dialog'
|
||||||
@@ -23,7 +22,6 @@ import Slide from '@mui/material/Slide'
|
|||||||
import Toolbar from '@mui/material/Toolbar'
|
import Toolbar from '@mui/material/Toolbar'
|
||||||
import Typography from '@mui/material/Typography'
|
import Typography from '@mui/material/Typography'
|
||||||
import { TransitionProps } from '@mui/material/transitions'
|
import { TransitionProps } from '@mui/material/transitions'
|
||||||
import { Buffer } from 'buffer'
|
|
||||||
import {
|
import {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useMemo,
|
useMemo,
|
||||||
@@ -32,6 +30,7 @@ import {
|
|||||||
useTransition
|
useTransition
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
|
import { downloadTemplateState } from '../atoms/downloadTemplate'
|
||||||
import { settingsState } from '../atoms/settings'
|
import { settingsState } from '../atoms/settings'
|
||||||
import { availableDownloadPathsState, connectedState } from '../atoms/status'
|
import { availableDownloadPathsState, connectedState } from '../atoms/status'
|
||||||
import FormatsGrid from '../components/FormatsGrid'
|
import FormatsGrid from '../components/FormatsGrid'
|
||||||
@@ -40,7 +39,6 @@ import { useRPC } from '../hooks/useRPC'
|
|||||||
import { CliArguments } from '../lib/argsParser'
|
import { CliArguments } from '../lib/argsParser'
|
||||||
import type { DLMetadata } from '../types'
|
import type { DLMetadata } from '../types'
|
||||||
import { isValidURL, toFormatArgs } from '../utils'
|
import { isValidURL, toFormatArgs } from '../utils'
|
||||||
import { downloadTemplateState } from '../atoms/downloadTemplate'
|
|
||||||
|
|
||||||
const Transition = forwardRef(function Transition(
|
const Transition = forwardRef(function Transition(
|
||||||
props: TransitionProps & {
|
props: TransitionProps & {
|
||||||
@@ -169,19 +167,18 @@ export default function DownloadDialog({
|
|||||||
localStorage.setItem("last-input-args", e.target.value)
|
localStorage.setItem("last-input-args", e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseUrlListFile = (event: any) => {
|
const parseUrlListFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const urlList = event.target.files
|
const files = e.currentTarget.files
|
||||||
const reader = new FileReader()
|
if (!files || files.length < 1) {
|
||||||
reader.addEventListener('load', $event => {
|
return
|
||||||
const base64 = $event.target?.result!.toString().split(',')[1]
|
}
|
||||||
Buffer.from(base64!, 'base64')
|
|
||||||
.toString()
|
const file = await files[0].text()
|
||||||
.trimEnd()
|
|
||||||
.split('\n')
|
file
|
||||||
.filter(_url => isValidURL(_url))
|
.split('\n')
|
||||||
.forEach(_url => sendUrl(_url))
|
.filter(u => isValidURL(u))
|
||||||
})
|
.forEach(u => sendUrl(u))
|
||||||
reader.readAsDataURL(urlList[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetInput = () => {
|
const resetInput = () => {
|
||||||
@@ -191,12 +188,6 @@ export default function DownloadDialog({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------- styled components -------------------- */
|
|
||||||
|
|
||||||
const Input = styled('input')({
|
|
||||||
display: 'none',
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -249,11 +240,12 @@ export default function DownloadDialog({
|
|||||||
endAdornment: (
|
endAdornment: (
|
||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
<label htmlFor="icon-button-file">
|
<label htmlFor="icon-button-file">
|
||||||
<Input
|
<input
|
||||||
|
hidden
|
||||||
id="icon-button-file"
|
id="icon-button-file"
|
||||||
type="file"
|
type="file"
|
||||||
accept=".txt"
|
accept=".txt"
|
||||||
onChange={parseUrlListFile}
|
onChange={e => parseUrlListFile(e)}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import FolderIcon from '@mui/icons-material/Folder'
|
|||||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'
|
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'
|
||||||
import VideoFileIcon from '@mui/icons-material/VideoFile'
|
import VideoFileIcon from '@mui/icons-material/VideoFile'
|
||||||
|
|
||||||
import { Buffer } from 'buffer'
|
|
||||||
import { useEffect, useMemo, useState, useTransition } from 'react'
|
import { useEffect, useMemo, useState, useTransition } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
@@ -138,7 +137,11 @@ export default function Downloaded() {
|
|||||||
}, [serverAddr])
|
}, [serverAddr])
|
||||||
|
|
||||||
const onFileClick = (path: string) => startTransition(() => {
|
const onFileClick = (path: string) => startTransition(() => {
|
||||||
window.open(`${serverAddr}/archive/d/${Buffer.from(path).toString('hex')}`)
|
const encoded = btoa(
|
||||||
|
String.fromCodePoint(...new TextEncoder().encode(path))
|
||||||
|
)
|
||||||
|
|
||||||
|
window.open(`${serverAddr}/archive/d/${encoded}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
const onFolderClick = (path: string) => startTransition(() => {
|
const onFolderClick = (path: string) => startTransition(() => {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -129,22 +130,23 @@ func SendFile(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
decoded, err := hex.DecodeString(path)
|
decoded, err := base64.StdEncoding.DecodeString(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
decodedStr := string(decoded)
|
decodedStr := string(decoded)
|
||||||
|
fmt.Println(decodedStr)
|
||||||
|
|
||||||
root := config.Instance().GetConfig().DownloadPath
|
root := config.Instance().GetConfig().DownloadPath
|
||||||
|
|
||||||
// TODO: further path / file validations
|
// TODO: further path / file validations
|
||||||
if strings.Contains(filepath.Dir(decodedStr), root) {
|
if strings.Contains(filepath.Dir(decodedStr), root) {
|
||||||
// ctx.Response().Header.Set(
|
w.Header().Add(
|
||||||
// "Content-Disposition",
|
"Content-Disposition",
|
||||||
// "inline; filename="+filepath.Base(decodedStr),
|
"inline; filename="+filepath.Base(decodedStr),
|
||||||
// )
|
)
|
||||||
|
|
||||||
http.ServeFile(w, r, decodedStr)
|
http.ServeFile(w, r, decodedStr)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user