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", "targetGuild": "1024080490677936248",
"targetChannel": "1024080525993971913", "targetChannel": "1024080525993971913",
"requestTimeout":120000, "requestTimeout":120000,
"maxUploadIdLength":30,
"accounts": { "accounts": {
"registrationEnabled": true, "registrationEnabled": true,

14
package-lock.json generated
View file

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

View file

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

View file

@ -6,11 +6,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>monofile</title> <title>monofile</title>
$metaTags <!--metaTags-->
<meta name="og:site_name" content="monofile $Version"> <meta name="og:site_name" content="monofile $Version">
<meta name="title" content="$FileName"> <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 <link
rel="stylesheet" rel="stylesheet"
@ -24,9 +24,11 @@
$FileName $FileName
</h1> </h1>
<p style="color:#999999"> <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> </p>
<!-- todo: previews -->
<button style="position:relative;width:100%;top:10px;"> <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> <a id="dlbtn" href="/file/$FileId" download="$FileName" style="position:absolute;left:0px;top:0px;height:100%;width:100%;"></a>
download 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"> <html lang="en">
<head> <head>
@ -23,7 +29,6 @@
<title>monofile</title> <title>monofile</title>
<meta name="og:site_name" content="monofile $Version">
<meta name="title" content="monofile"> <meta name="title" content="monofile">
<meta name="description" content="Discord based file sharing"> <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 express from "express"
import fs, { link } from "fs" import fs, { link } from "fs"
import axios, { AxiosResponse } from "axios" import axios, { AxiosResponse } from "axios"
import bytes from "bytes";
import ServeError from "./lib/errors" import ServeError from "./lib/errors"
import Files from "./lib/files" import Files from "./lib/files"
@ -130,13 +131,14 @@ app.get("/download/:fileId",(req,res) => {
buf.toString() buf.toString()
.replace(/\$FileId/g,req.params.fileId) .replace(/\$FileId/g,req.params.fileId)
.replace(/\$Version/g,pkg.version) .replace(/\$Version/g,pkg.version)
.replace(/\$FileSize/g,file.sizeInBytes ? bytes(file.sizeInBytes) : "[File size unknown]")
.replace(/\$FileName/g, .replace(/\$FileName/g,
file.filename file.filename
.replace(/\&/g,"&amp;") .replace(/\&/g,"&amp;")
.replace(/\</g,"&lt;") .replace(/\</g,"&lt;")
.replace(/\>/g,"&gt;") .replace(/\>/g,"&gt;")
) )
.replace(/\$metaTags/g, .replace(/\<\!\-\-metaTags\-\-\>/g,
file.mime.startsWith("image/") file.mime.startsWith("image/")
? `<meta name="og:image" content="https://${req.headers.host}/file/${req.params.fileId}" />` ? `<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() { export function save() {
writeFile(`${process.cwd()}/.data/accounts.json`,JSON.stringify(Accounts)) writeFile(`${process.cwd()}/.data/accounts.json`,JSON.stringify(Accounts))
.catch((err) => console.error(err)) .catch((err) => console.error(err))

View file

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

View file

@ -123,7 +123,7 @@
<div id="uploadWindow"> <div id="uploadWindow">
<h1>monofile</h1> <h1>monofile</h1>
<p style:color="#999999"> <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> </p>
<div style:min-height="10px" /> <div style:min-height="10px" />

View file

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