not many additions but whatev

This commit is contained in:
May 2023-02-27 16:48:43 -08:00
parent f9480d543b
commit 12f56d5b51
5 changed files with 101 additions and 24 deletions

View file

@ -13,6 +13,8 @@ import * as auth from "./lib/auth"
import * as Accounts from "./lib/accounts" import * as Accounts from "./lib/accounts"
import { authRoutes } from "./routes/authRoutes"; import { authRoutes } from "./routes/authRoutes";
import { fileApiRoutes, setFilesObj } from "./routes/fileApiRoutes";
require("dotenv").config() require("dotenv").config()
const multerSetup = multer({storage:memoryStorage()}) const multerSetup = multer({storage:memoryStorage()})
@ -28,6 +30,7 @@ app.use(bodyParser.text({limit:(config.maxDiscordFileSize*config.maxDiscordFiles
app.use(cookieParser()) app.use(cookieParser())
app.use("/auth",authRoutes) app.use("/auth",authRoutes)
app.use("/files",fileApiRoutes)
// funcs // funcs
// init data // init data
@ -45,6 +48,8 @@ let client = new Client({intents:[
let files = new Files(client,config) let files = new Files(client,config)
setFilesObj(files)
// routes (could probably make these use routers) // routes (could probably make these use routers)
// index, clone // index, clone
@ -125,6 +130,11 @@ app.get("/download/:fileId",(req,res) => {
if (files.getFilePointer(req.params.fileId)) { if (files.getFilePointer(req.params.fileId)) {
let file = files.getFilePointer(req.params.fileId) let file = files.getFilePointer(req.params.fileId)
if (file.visibility == "private" && Accounts.getFromToken(req.cookies.auth)?.id != file.owner) {
ServeError(res,403,"you do not own this file")
return
}
fs.readFile(process.cwd()+"/pages/download.html",(err,buf) => { fs.readFile(process.cwd()+"/pages/download.html",(err,buf) => {
if (err) {res.sendStatus(500);console.log(err);return} if (err) {res.sendStatus(500);console.log(err);return}
res.send( res.send(
@ -159,7 +169,7 @@ app.get("/download/:fileId",(req,res) => {
: "" : ""
) )
) )
.replace(/\$Uploader/g,file.anonymous||!file.owner ? "Anonymous" : `@${Accounts.getFromId(file.owner)?.username || "Deleted User"}`) .replace(/\$Uploader/g,!file.owner||file.visibility=="anonymous" ? "Anonymous" : `@${Accounts.getFromId(file.owner)?.username || "Deleted User"}`)
) )
}) })
} else { } else {
@ -168,16 +178,31 @@ app.get("/download/:fileId",(req,res) => {
}) })
let fgRQH = async (req:express.Request,res:express.Response) => { let fgRQH = async (req:express.Request,res:express.Response) => {
files.readFileStream(req.params.fileId).then(f => {
res.setHeader("Content-Type",f.contentType) let file = files.getFilePointer(req.params.fileId)
if (f.byteSize) {
res.setHeader("Content-Length",f.byteSize) if (file) {
if (file.visibility == "private" && Accounts.getFromToken(req.cookies.auth)?.id != file.owner) {
ServeError(res,403,"you do not own this file")
return
} }
res.status(200)
f.dataStream.pipe(res) // todo: make readfilestream just the stream since we already have filepointer
}).catch((err) => { files.readFileStream(req.params.fileId).then(f => {
ServeError(res,err.status,err.message) res.setHeader("Content-Type",f.contentType)
}) if (f.byteSize) {
res.setHeader("Content-Length",f.byteSize)
}
res.status(200)
f.dataStream.pipe(res)
}).catch((err) => {
ServeError(res,err.status,err.message)
})
}
} }
app.get("/server",(req,res) => { app.get("/server",(req,res) => {

View file

@ -1,6 +1,7 @@
import crypto from "crypto" import crypto from "crypto"
import * as auth from "./auth"; import * as auth from "./auth";
import { readFile, writeFile } from "fs/promises" import { readFile, writeFile } from "fs/promises"
import { FileVisibility } from "./files";
// this is probably horrible // this is probably horrible
// but i don't even care anymore // but i don't even care anymore
@ -8,15 +9,16 @@ import { readFile, writeFile } from "fs/promises"
export let Accounts: Account[] = [] export let Accounts: Account[] = []
export interface Account { export interface Account {
id : string id : string
username : string username : string
password : { password : {
hash : string hash : string
salt : string salt : string
} }
files : string[] files : string[]
collections : string[] collections : string[]
admin : boolean admin : boolean
defaultFileVisibility : FileVisibility
} }
export function create(username:string,pwd:string,admin:boolean=false) { export function create(username:string,pwd:string,admin:boolean=false) {
@ -29,7 +31,8 @@ export function create(username:string,pwd:string,admin:boolean=false) {
password: password.hash(pwd), password: password.hash(pwd),
files: [], files: [],
collections: [], collections: [],
admin: admin admin: admin,
defaultFileVisibility: "public"
} }
) )

View file

@ -4,11 +4,15 @@ import { readFile, writeFile } from "fs";
import { Readable } from "node:stream"; import { Readable } from "node:stream";
import { files } from "./accounts"; import { files } from "./accounts";
import * as Accounts from "./accounts";
export let id_check_regex = /[A-Za-z0-9_\-\.\!]+/ export let id_check_regex = /[A-Za-z0-9_\-\.\!]+/
export let alphanum = Array.from("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") export let alphanum = Array.from("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
// bad solution but whatever // bad solution but whatever
export type FileVisibility = "public" | "anonymous" | "private"
export function generateFileId() { export function generateFileId() {
let fid = "" let fid = ""
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
@ -21,8 +25,7 @@ export interface FileUploadSettings {
name?: string, name?: string,
mime: string, mime: string,
uploadId?: string, uploadId?: string,
owner?:string, owner?:string
anonymous?:boolean
} }
export interface Configuration { export interface Configuration {
@ -46,7 +49,7 @@ export interface FilePointer {
owner?:string, owner?:string,
sizeInBytes?:number, sizeInBytes?:number,
tag?:string, tag?:string,
anonymous?:boolean visibility?:FileVisibility
} }
export interface StatusCodeError { export interface StatusCodeError {
@ -185,7 +188,7 @@ export default class Files {
sizeInBytes:fBuffer.byteLength, sizeInBytes:fBuffer.byteLength,
owner:settings.owner, owner:settings.owner,
anonymous: typeof settings.anonymous == "boolean" ? settings.anonymous : false visibility: settings.owner ? Accounts.getFromId(settings.owner)?.defaultFileVisibility : undefined
} }
)) ))
}) })

View file

@ -0,0 +1,41 @@
import bodyParser from "body-parser";
import { Router } from "express";
import * as Accounts from "../lib/accounts";
import * as auth from "../lib/auth";
import ServeError from "../lib/errors";
import Files from "../lib/files";
let parser = bodyParser.json({
type: ["text/plain","application/json"]
})
export let fileApiRoutes = Router();
let files:Files
export function setFilesObj(newFiles:Files) {
files = newFiles
}
let config = require(`${process.cwd()}/config.json`)
fileApiRoutes.get("/list", (req,res) => {
if (!auth.validate(req.cookies.auth)) {
ServeError(res, 401, "not logged in")
return
}
let acc = Accounts.getFromToken(req.cookies.auth)
if (!acc) return
res.send(JSON.stringify(acc.files.map((e) => {
return {
...files.getFilePointer(e),
messageids: null,
id:e
}
})))
})

View file

@ -121,7 +121,7 @@
<button> <button>
<img src="/static/assets/icons/change_password.svg" alt="change password"> <img src="/static/assets/icons/change_password.svg" alt="change password">
<p>Change password<span><br />You will be logged out</span></p> <p>Change password<span><br />You will be logged out of all sessions</span></p>
</button> </button>
{#if !$account.admin} {#if !$account.admin}
@ -180,6 +180,11 @@
<p>Elevate account to admin</p> <p>Elevate account to admin</p>
</button> </button>
<button>
<img src="/static/assets/icons/link.svg" alt="delete file">
<p>Change file owner</p>
</button>
<button> <button>
<img src="/static/assets/icons/admin/delete_file.svg" alt="delete file"> <img src="/static/assets/icons/admin/delete_file.svg" alt="delete file">
<p>Delete file</p> <p>Delete file</p>