this is without a doubt the worst code ive written

next commit will probably be me trying to fix this mess
or just the file menu but good idea to fix early
This commit is contained in:
split / May 2023-03-01 16:39:11 -08:00
parent 57081398e6
commit aa715fa868
5 changed files with 165 additions and 7 deletions

View file

@ -12,7 +12,7 @@ import Files from "./lib/files"
import * as auth from "./lib/auth" 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, auth_setFilesObj } from "./routes/authRoutes";
import { fileApiRoutes, setFilesObj } from "./routes/fileApiRoutes"; import { fileApiRoutes, setFilesObj } from "./routes/fileApiRoutes";
require("dotenv").config() require("dotenv").config()
@ -49,6 +49,7 @@ let client = new Client({intents:[
let files = new Files(client,config) let files = new Files(client,config)
setFilesObj(files) setFilesObj(files)
auth_setFilesObj(files)
// routes (could probably make these use routers) // routes (could probably make these use routers)

View file

@ -127,6 +127,21 @@ export default class Files {
reject({status:400,message:"mime too long"}); reject({status:400,message:"mime too long"});
return return
} }
// reserve file, hopefully should prevent
// large files breaking
let ogf = this.files[uploadId]
this.files[uploadId] = {
filename:settings.name,
messageids:[],
mime:settings.mime,
sizeInBytes:0,
owner:settings.owner,
visibility: settings.owner ? "private" : "public"
}
// get buffer // get buffer
if (fBuffer.byteLength >= (this.config.maxDiscordFileSize*this.config.maxDiscordFiles)) { if (fBuffer.byteLength >= (this.config.maxDiscordFileSize*this.config.maxDiscordFiles)) {
@ -169,6 +184,8 @@ export default class Files {
if (ms) { if (ms) {
msgIds.push(ms.id) msgIds.push(ms.id)
} else { } else {
if (!ogf) delete this.files[uploadId]
else this.files[uploadId] = ogf
reject({status:500,message:"please try again"}); return reject({status:500,message:"please try again"}); return
} }
} }
@ -204,7 +221,7 @@ export default class Files {
writeFile(process.cwd()+"/.data/files.json",JSON.stringify(this.files),(err) => { writeFile(process.cwd()+"/.data/files.json",JSON.stringify(this.files),(err) => {
if (err) { if (err) {
reject({status:500,message:"please try again"}); reject({status:500,message:"server may be misconfigured, contact admin for help"});
delete this.files[uploadId]; delete this.files[uploadId];
return return
} }

View file

@ -4,6 +4,7 @@ import * as Accounts from "../lib/accounts";
import * as auth from "../lib/auth"; import * as auth from "../lib/auth";
import ServeError from "../lib/errors"; import ServeError from "../lib/errors";
import Files, { FileVisibility } from "../lib/files";
let parser = bodyParser.json({ let parser = bodyParser.json({
type: ["text/plain","application/json"] type: ["text/plain","application/json"]
@ -13,6 +14,11 @@ export let authRoutes = Router();
let config = require(`${process.cwd()}/config.json`) let config = require(`${process.cwd()}/config.json`)
let files:Files
export function auth_setFilesObj(newFiles:Files) {
files = newFiles
}
authRoutes.post("/login", parser, (req,res) => { authRoutes.post("/login", parser, (req,res) => {
let body:{[key:string]:any} let body:{[key:string]:any}
@ -123,6 +129,101 @@ authRoutes.post("/logout", (req,res) => {
res.send("logged out") res.send("logged out")
}) })
authRoutes.post("/dfv", (req,res) => {
let acc = Accounts.getFromToken(req.cookies.auth)
if (!acc) {
ServeError(res, 401, "not logged in")
return
}
let body:{[key:string]:any}
try {
body = JSON.parse(req.body)
} catch {
ServeError(res,400,"bad request")
return
}
if (['public','private','anonymous'].find(e => e == body.defaultFileVisibility)) {
acc.defaultFileVisibility = body.defaultFileVisibility
Accounts.save()
res.send(`dfv has been set to ${acc.defaultFileVisibility}`)
} else {
res.status(400)
res.send("invalid dfv")
}
})
authRoutes.post("/delete_account", (req,res) => {
let acc = Accounts.getFromToken(req.cookies.auth)
if (!acc) {
ServeError(res, 401, "not logged in")
return
}
let body:{[key:string]:any}
try {
body = JSON.parse(req.body)
} catch {
ServeError(res,400,"bad request")
return
}
let accId = acc.id
auth.AuthTokens.filter(e => e.account == accId).forEach((v) => {
auth.invalidate(v.token)
})
if (body.deleteFiles) {
acc.files.forEach((v) => {
files.unlink(v)
})
}
Accounts.deleteAccount(accId)
res.send("account deleted")
})
authRoutes.post("/change_username", (req,res) => {
let acc = Accounts.getFromToken(req.cookies.auth)
if (!acc) {
ServeError(res, 401, "not logged in")
return
}
let body:{[key:string]:any}
try {
body = JSON.parse(req.body)
} catch {
ServeError(res,400,"bad request")
return
}
if (typeof body.username != "string" || body.username.length < 3 || body.username.length > 20) {
ServeError(res,400,"username must be between 3 and 20 characters in length")
return
}
let _acc = Accounts.getFromUsername(body.username)
if (_acc) {
ServeError(res,400,"account with this username already exists")
return
}
if ((body.username.match(/[A-Za-z0-9_\-\.]+/) || [])[0] != body.username) {
ServeError(res,400,"username contains invalid characters")
return
}
acc.username = body.username
Accounts.save()
res.send("username changed")
})
authRoutes.post("/change_password", (req,res) => { authRoutes.post("/change_password", (req,res) => {
let acc = Accounts.getFromToken(req.cookies.auth) let acc = Accounts.getFromToken(req.cookies.auth)
if (!acc) { if (!acc) {

View file

@ -0,0 +1,38 @@
import { fetchAccountData, account } from "../stores.mjs"
import { get } from "svelte/store";
export function dfv(optPicker) {
optPicker.picker("Default file visibility",[
{
name: "Public",
icon: "/static/assets/icons/public.svg",
description: "Everyone can view your uploads",
id: "public"
},
{
name: "Anonymous",
icon: "/static/assets/icons/anonymous.svg",
description: "Your username will be hidden",
id: "anonymous"
},
{
name: "Private",
icon: "/static/assets/icons/private.svg",
description: "Nobody but you can view your uploads",
id: "private"
}
]).then((exp) => {
if (exp && exp.selected) {
fetch(`/auth/dfv`,{method:"POST", body:JSON.stringify({
defaultFileVisibility: exp.selected
})}).then((response) => {
if (response.status != 200) {
optPicker.picker(`${response.status} ${response.statusText}`,[])
}
fetchAccountData()
})
}
})
}

View file

@ -6,6 +6,7 @@
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import OptionPicker from "../prompts/OptionPicker.svelte"; import OptionPicker from "../prompts/OptionPicker.svelte";
import * as accOpts from "../prompts/account"; import * as accOpts from "../prompts/account";
import * as uplOpts from "../prompts/uploads";
let targetAction let targetAction
let inProgress let inProgress
@ -119,7 +120,7 @@
<p>Account</p> <p>Account</p>
</div> </div>
<button> <button on:click={() => accOpts.userChange(optPicker)}>
<img src="/static/assets/icons/change_username.svg" alt="change username"> <img src="/static/assets/icons/change_username.svg" alt="change username">
<p>Change username</p> <p>Change username</p>
</button> </button>
@ -140,14 +141,14 @@
<p>Uploads</p> <p>Uploads</p>
</div> </div>
<button> <button on:click={() => uplOpts.dfv(optPicker)}>
<img src="/static/assets/icons/public.svg" alt="public"> <img src={`/static/assets/icons/${$account.defaultFileVisibility || "public"}.svg`} alt={$account.defaultFileVisibility || "public"}>
<p>Default file visibility<span><br />Uploads will be <strong>public</strong> by default</span></p> <p>Default file visibility<span><br />Uploads will be <strong>{$account.defaultFileVisibility || "public"}</strong> by default</span></p>
</button> </button>
<button> <button>
<img src="/static/assets/icons/update.svg" alt="update"> <img src="/static/assets/icons/update.svg" alt="update">
<p>Make all of my files public<span><br />Matches your default file visibility</p> <p>Make all of my files {$account.defaultFileVisibility || "public"}<span><br />Matches your default file visibility</p>
</button> </button>
<div class="category"> <div class="category">