This commit is contained in:
May 2023-02-26 12:37:02 -08:00
parent dcd76a1449
commit 2a09405645
10 changed files with 81 additions and 21 deletions

View file

@ -4,6 +4,7 @@
"targetGuild": "1024080490677936248",
"targetChannel": "1024080525993971913",
"requestTimeout":120000,
"maxUploadIdLength":30,
"accounts": {
"registrationEnabled": true,

14
package-lock.json generated
View file

@ -14,6 +14,7 @@
"@types/multer": "^1.4.7",
"axios": "^0.27.2",
"body-parser": "^1.20.0",
"bytes": "^3.1.2",
"cookie-parser": "^1.4.6",
"discord.js": "^14.7.1",
"dotenv": "^16.0.2",
@ -23,6 +24,7 @@
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
"@types/bytes": "^3.1.1",
"@types/cookie-parser": "^1.4.3",
"rollup": "^3.11.0",
"rollup-plugin-svelte": "^7.1.0",
@ -181,6 +183,12 @@
"@types/node": "*"
}
},
"node_modules/@types/bytes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.1.tgz",
"integrity": "sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w==",
"dev": true
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@ -1772,6 +1780,12 @@
"@types/node": "*"
}
},
"@types/bytes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.1.tgz",
"integrity": "sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w==",
"dev": true
},
"@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",

View file

@ -19,6 +19,7 @@
"@types/multer": "^1.4.7",
"axios": "^0.27.2",
"body-parser": "^1.20.0",
"bytes": "^3.1.2",
"cookie-parser": "^1.4.6",
"discord.js": "^14.7.1",
"dotenv": "^16.0.2",
@ -28,6 +29,7 @@
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
"@types/bytes": "^3.1.1",
"@types/cookie-parser": "^1.4.3",
"rollup": "^3.11.0",
"rollup-plugin-svelte": "^7.1.0",

View file

@ -6,11 +6,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>monofile</title>
$metaTags
<!--metaTags-->
<meta name="og:site_name" content="monofile $Version">
<meta name="title" content="$FileName">
<meta name="description" content="ID: $FileId">
<meta name="description" content="$FileSize file on monofile, the Discord-based file sharing service">
<link
rel="stylesheet"
@ -24,9 +24,11 @@
$FileName
</h1>
<p style="color:#999999">
file id <span class="number">$FileId</span>
<span class="number">$FileSize</span>&nbsp;&nbsp;&nbsp;&nbsp;file id <span class="number">$FileId</span>
</p>
<!-- todo: previews -->
<button style="position:relative;width:100%;top:10px;">
<a id="dlbtn" href="/file/$FileId" download="$FileName" style="position:absolute;left:0px;top:0px;height:100%;width:100%;"></a>
download

View file

@ -1,4 +1,10 @@
<!DOCTYPE html>
<!--
for some reason (don't know why)
certain things break
when not in quirks mode
so i'm not adding in the
doctype html
-->
<html lang="en">
<head>
@ -23,7 +29,6 @@
<title>monofile</title>
<meta name="og:site_name" content="monofile $Version">
<meta name="title" content="monofile">
<meta name="description" content="Discord based file sharing">

View file

@ -5,6 +5,7 @@ import Discord, { IntentsBitField, Client } from "discord.js"
import express from "express"
import fs, { link } from "fs"
import axios, { AxiosResponse } from "axios"
import bytes from "bytes";
import ServeError from "./lib/errors"
import Files from "./lib/files"
@ -130,13 +131,14 @@ app.get("/download/:fileId",(req,res) => {
buf.toString()
.replace(/\$FileId/g,req.params.fileId)
.replace(/\$Version/g,pkg.version)
.replace(/\$FileSize/g,file.sizeInBytes ? bytes(file.sizeInBytes) : "[File size unknown]")
.replace(/\$FileName/g,
file.filename
.replace(/\&/g,"&amp;")
.replace(/\</g,"&lt;")
.replace(/\>/g,"&gt;")
)
.replace(/\$metaTags/g,
.replace(/\<\!\-\-metaTags\-\-\>/g,
file.mime.startsWith("image/")
? `<meta name="og:image" content="https://${req.headers.host}/file/${req.params.fileId}" />`
: (

View file

@ -84,6 +84,30 @@ export namespace password {
}
}
export namespace files {
export function index(accountId:string,fileId:string) {
// maybe replace with a obj like
// { x:true }
// for faster lookups? not sure if it would be faster
let acc = Accounts.find(e => e.id == accountId)
if (!acc) return
if (acc.files.find(e => e == fileId)) return
acc.files.push(fileId)
save()
}
export function deindex(accountId:string,fileId:string) {
let acc = Accounts.find(e => e.id == accountId)
if (!acc) return
let fi = acc.files.findIndex(e => e == fileId)
if (fi) {
acc.files.splice(fi,1)
save()
}
}
}
export function save() {
writeFile(`${process.cwd()}/.data/accounts.json`,JSON.stringify(Accounts))
.catch((err) => console.error(err))

View file

@ -1,9 +1,10 @@
import axios from "axios";
import Discord, { Client, TextBasedChannel } from "discord.js";
import { readFile, writeFile } from "fs";
import { Readable } from "node:stream"
import { Readable } from "node:stream";
import { files } 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")
// bad solution but whatever
@ -29,6 +30,7 @@ export interface Configuration {
targetGuild: string,
targetChannel: string,
requestTimeout: number,
maxUploadIdLength: number,
accounts: {
registrationEnabled: boolean,
@ -40,7 +42,8 @@ export interface FilePointer {
filename:string,
mime:string,
messageids:string[],
owner?:string
owner?:string,
sizeInBytes?:number
}
export interface StatusCodeError {
@ -100,12 +103,12 @@ export default class Files {
let uploadId = (settings.uploadId || generateFileId()).toString();
if ((uploadId.match(id_check_regex) || [])[0] != uploadId || uploadId.length > 30) {
if ((uploadId.match(id_check_regex) || [])[0] != uploadId || uploadId.length > this.config.maxUploadIdLength) {
reject({status:400,message:"invalid id"});return
}
if (this.files[uploadId]) {
reject({status:400,message:"a file with this id already exists"});
if (this.files[uploadId] && (settings.owner ? this.files[uploadId].owner != settings.owner : true)) {
reject({status:400,message:"you are not the owner of this file id"});
return
}
@ -166,12 +169,17 @@ export default class Files {
// save
if (settings.owner) {
files.index(settings.owner,uploadId)
}
resolve(await this.writeFile(
uploadId,
{
filename:settings.name,
messageids:msgIds,
mime:settings.mime,
sizeInBytes:fBuffer.byteLength,
owner:settings.owner
}

View file

@ -123,7 +123,7 @@
<div id="uploadWindow">
<h1>monofile</h1>
<p style:color="#999999">
<span class="number">{$serverStats.version ? `v${$serverStats.version}` : "•••"}</span>&nbsp;&nbsp—&nbsp;&nbsp;Discord based file sharing
<span class="number">{$serverStats.version ? `v${$serverStats.version}` : "•••"}</span>&nbsp;&nbsp;&nbsp;&nbsp;Discord based file sharing
</p>
<div style:min-height="10px" />

View file

@ -1,17 +1,19 @@
<script>
import Pulldown from "./Pulldown.svelte"
import { pulldownManager } from "../stores.mjs";
import { account, pulldownManager } from "../stores.mjs";
</script>
<Pulldown name="files">
<div class="notLoggedIn">
<div style:height="2px" style:background-color="#66AAFF" />
<div style:height="10px" />
<p class="flavor">Log in to view uploads & collections</p>
<button on:click={$pulldownManager.openPulldown("account")}>OK</button>
<div style:height="14px" />
</div>
{#if !$account.username}
<div class="notLoggedIn">
<div style:height="2px" style:background-color="#66AAFF" />
<div style:height="10px" />
<p class="flavor">Log in to view uploads & collections</p>
<button on:click={$pulldownManager.openPulldown("account")}>OK</button>
<div style:height="14px" />
</div>
{/if}
<!--
put scrolling div containing options here