mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-21 21:36:26 -08:00
this code actually sucks ass
god bless anyone who reads this 1.2.1 i'll need to clean this shit up lmao
This commit is contained in:
parent
0aad03c50e
commit
3ef9eeaf4c
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
|
@ -12,7 +12,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command":"npx tsc\nnode ./out/index.js\ndel ./server_out/* -Recurse",
|
"command":"npx tsc\nnode ./out/index.js\ndel ./out/* -Recurse",
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
|
|
|
@ -17,10 +17,11 @@ TOKEN=KILL-YOURSELF.NOW
|
||||||
- [X] 1.1.2 fix file cloning with binary data
|
- [X] 1.1.2 fix file cloning with binary data
|
||||||
- [X] 1.1.3 display current version on pages
|
- [X] 1.1.3 display current version on pages
|
||||||
- [X] 1.1.4 serve /assets as static files & make /server endpoint
|
- [X] 1.1.4 serve /assets as static files & make /server endpoint
|
||||||
- [ ] 1.2.0 add simple moderation tools
|
- [X] 1.2.0 add file parameters section + custom ids
|
||||||
- [ ] 1.2.1 prevent cloning of local/private ip addresses
|
- [ ] 1.2.1 clean up this shitty code
|
||||||
- [ ] 1.3.0 allow custom file ids
|
- [ ] 1.2.2 add id locks, allowing you to set a key for a file that allows you to overwrite the file in the future
|
||||||
- [ ] 1.4.0 accounts??? maybe?? (this probably won't happen)
|
- [ ] 1.2.3 prevent cloning of local/private ip addresses
|
||||||
|
- [ ] 1.3.0 add simple moderation tools
|
||||||
- [ ] 2.0.0 rewrite using theUnfunny's code as a base/rewrite using monofile-core
|
- [ ] 2.0.0 rewrite using theUnfunny's code as a base/rewrite using monofile-core
|
||||||
|
|
||||||
also todo: monofile-core (written in eris)
|
also todo: monofile-core (written in eris)
|
||||||
|
|
30
assets/script/clone_file.js
Normal file
30
assets/script/clone_file.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
document.getElementById("uploadButton").addEventListener("click",() => {
|
||||||
|
let ask = prompt("Input a URL to clone.")
|
||||||
|
|
||||||
|
if (ask) {
|
||||||
|
let opt = getOptionsForUploading()
|
||||||
|
updateBtnTxt("Requesting clone. Please wait.")
|
||||||
|
|
||||||
|
let xmlhttp = new XMLHttpRequest()
|
||||||
|
|
||||||
|
xmlhttp.addEventListener("error",function(e) {
|
||||||
|
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
||||||
|
console.error(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
xmlhttp.addEventListener("load",function() {
|
||||||
|
if (xmlhttp.status == 200) {
|
||||||
|
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
||||||
|
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
||||||
|
} else {
|
||||||
|
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
xmlhttp.open("POST","/clone")
|
||||||
|
xmlhttp.send(JSON.stringify({
|
||||||
|
url: ask,
|
||||||
|
...opt
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
37
assets/script/upload_file.js
Normal file
37
assets/script/upload_file.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
let FileUpload = document.createElement("input")
|
||||||
|
FileUpload.setAttribute("type","file")
|
||||||
|
|
||||||
|
document.getElementById("uploadButton").addEventListener("click",() => FileUpload.click())
|
||||||
|
|
||||||
|
FileUpload.addEventListener("input",() => {
|
||||||
|
if (FileUpload.files[0]) {
|
||||||
|
let opt = getOptionsForUploading()
|
||||||
|
let file = FileUpload.files[0]
|
||||||
|
|
||||||
|
updateBtnTxt("Uploading file. This may take a while, so stay put.")
|
||||||
|
|
||||||
|
let xmlhttp = new XMLHttpRequest()
|
||||||
|
|
||||||
|
xmlhttp.addEventListener("error",function(e) {
|
||||||
|
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
||||||
|
console.error(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
xmlhttp.addEventListener("load",function() {
|
||||||
|
if (xmlhttp.status == 200) {
|
||||||
|
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
||||||
|
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
||||||
|
} else {
|
||||||
|
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let fd = new FormData()
|
||||||
|
fd.append('file',file)
|
||||||
|
|
||||||
|
xmlhttp.open("POST","/upload")
|
||||||
|
xmlhttp.setRequestHeader("monofile-upload-id",opt.uploadId)
|
||||||
|
xmlhttp.send(fd)
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
|
@ -37,31 +37,70 @@
|
||||||
left:50%;
|
left:50%;
|
||||||
transform:translate(-50%,0);
|
transform:translate(-50%,0);
|
||||||
}
|
}
|
||||||
#uploadButton {
|
|
||||||
width:100%;
|
button {
|
||||||
height:100%;
|
|
||||||
background-color: #66AAFF;
|
|
||||||
color:black;
|
color:black;
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
border:none;
|
border:none;
|
||||||
position:absolute;
|
position:absolute;
|
||||||
left:0px;
|
|
||||||
top:0px;
|
|
||||||
font-size:20px;
|
font-size:20px;
|
||||||
}
|
}
|
||||||
#uploadButton:hover {
|
|
||||||
|
button:hover {
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#uploadButton {
|
||||||
|
width:calc( 100% - 50px );
|
||||||
|
height:100%;
|
||||||
|
background-color: #66AAFF;
|
||||||
|
left:0px;
|
||||||
|
top:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#optionsButton {
|
||||||
|
width:50px;
|
||||||
|
height:100%;
|
||||||
|
background-color: #AAAAAA;
|
||||||
|
left:calc( 100% - 50px );
|
||||||
|
top:0px;
|
||||||
|
font-size:15px;
|
||||||
|
}
|
||||||
|
|
||||||
.note {
|
.note {
|
||||||
padding:5px;
|
padding:5px;
|
||||||
position:relative;
|
position:relative;
|
||||||
width:calc( 100% - 60px );
|
width:calc( 100% - 62px );
|
||||||
left:25px;
|
left:25px;
|
||||||
border:1px solid #AAAAAAFF;
|
border:1px solid #AAAAAAFF;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #AAAAAA66;
|
background-color: #AAAAAA66;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this is horrible css lmao */
|
||||||
|
|
||||||
|
#options > input {
|
||||||
|
font-family:monospace;
|
||||||
|
width:250px;
|
||||||
|
font-size:14px;
|
||||||
|
border: 1px solid #777777;
|
||||||
|
background-color:#AAAAAA;
|
||||||
|
outline:none;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#options {
|
||||||
|
height:30px;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customId {
|
||||||
|
position:absolute;
|
||||||
|
left:50%;
|
||||||
|
top:50%;
|
||||||
|
transform:translate(-50%,-50%)
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 450px) {
|
@media only screen and (max-width: 450px) {
|
||||||
#content {
|
#content {
|
||||||
position:fixed;
|
position:fixed;
|
||||||
|
@ -92,53 +131,41 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div style="width:100%;height:25px"></div>
|
<div style="width:100%;height:25px"></div>
|
||||||
<div id="btnContainer"><button id="uploadButton">Upload file</button></div>
|
<div id="btnContainer">
|
||||||
|
<button id="uploadButton">$UploadButtonText</button>
|
||||||
|
<button id="optionsButton">• • •</button>
|
||||||
|
</div>
|
||||||
|
<div id="options" class="note" style="border-radius:0px;">
|
||||||
|
<input id="customId" autocomplete="off" placeholder = "custom id (30char, no spaces)" maxlength="30">
|
||||||
|
</div>
|
||||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">
|
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">
|
||||||
Max filesize on instance: $MaxInstanceFilesize
|
Max filesize on instance: $MaxInstanceFilesize
|
||||||
</p>
|
</p>
|
||||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;font-size:12px;color:gray;">made by nbitzz — <a style="color:gray;font-family:monospace;font-size:12px;" href="https://github.com/nbitzz/monofile">github</a> — <a style="color:gray;font-family:monospace;font-size:12px;" href="/clone">clone from url...</a></p>
|
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;font-size:12px;color:gray;">made by nbitzz — <a style="color:gray;font-family:monospace;font-size:12px;" href="https://github.com/nbitzz/monofile">github</a> — <a style="color:gray;font-family:monospace;font-size:12px;" href="$otherPath">$otherText</a></p>
|
||||||
<div style="width:100%;height:25px"></div>
|
<div style="width:100%;height:25px"></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<!-- bad thing to do but i'm being rushed -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let updateBtnTxt = (btntxt) => {document.getElementById("btnContainer").innerHTML = `<div class="note" style="width:calc( 100% - 10px );height:calc( 100% - 10px );position:absolute;left:0px;top:0px;"><p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">${btntxt}</p></div>`}
|
let uploading = false
|
||||||
|
const updateBtnTxt = (btntxt) => {document.getElementById("btnContainer").innerHTML = `<div class="note" style="width:calc( 100% - 10px );height:calc( 100% - 10px );position:absolute;left:0px;top:0px;"><p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">${btntxt}</p></div>`}
|
||||||
let FileUpload = document.createElement("input")
|
const getOptionsForUploading = () => {
|
||||||
FileUpload.setAttribute("type","file")
|
uploading = true
|
||||||
|
document.getElementById("options").style.display = "none"
|
||||||
document.getElementById("uploadButton").addEventListener("click",() => FileUpload.click())
|
|
||||||
|
return {
|
||||||
FileUpload.addEventListener("input",() => {
|
uploadId: document.getElementById("customId").value
|
||||||
if (FileUpload.files[0]) {
|
|
||||||
let file = FileUpload.files[0]
|
|
||||||
|
|
||||||
updateBtnTxt("Uploading file. This may take a while, so stay put.")
|
|
||||||
|
|
||||||
let xmlhttp = new XMLHttpRequest()
|
|
||||||
|
|
||||||
xmlhttp.addEventListener("error",function(e) {
|
|
||||||
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
xmlhttp.addEventListener("load",function() {
|
|
||||||
if (xmlhttp.status == 200) {
|
|
||||||
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
|
||||||
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
|
||||||
} else {
|
|
||||||
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let fd = new FormData()
|
|
||||||
fd.append('file',file)
|
|
||||||
|
|
||||||
xmlhttp.open("POST","/upload")
|
|
||||||
xmlhttp.send(fd)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("optionsButton").addEventListener("click",() => {
|
||||||
|
let display = document.getElementById("options").style.display
|
||||||
|
if (!uploading) document.getElementById("options").style.display = !display || display == "none" ? "block" : "none"
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="/static/script/$Handler.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
135
pages/clone.html
135
pages/clone.html
|
@ -1,135 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>monofile</title>
|
|
||||||
|
|
||||||
<meta name="og:site_name" content="$Version">
|
|
||||||
<meta name="application-name" content="monofile">
|
|
||||||
<meta name="description" content="Discord-based filesharing">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
h1,h2 {
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
#content {
|
|
||||||
position:fixed;
|
|
||||||
left:50%;
|
|
||||||
top:50%;
|
|
||||||
transform:translate(-50%,-50%);
|
|
||||||
background-color:white;
|
|
||||||
width:450px;
|
|
||||||
/*height:100%;*/
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background-color: darkgray;
|
|
||||||
}
|
|
||||||
#btnContainer {
|
|
||||||
width:calc( 100% - 50px );
|
|
||||||
height:50px;
|
|
||||||
position:relative;
|
|
||||||
left:50%;
|
|
||||||
transform:translate(-50%,0);
|
|
||||||
}
|
|
||||||
#uploadButton {
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
background-color: #66AAFF;
|
|
||||||
color:black;
|
|
||||||
font-weight:bold;
|
|
||||||
border:none;
|
|
||||||
position:absolute;
|
|
||||||
left:0px;
|
|
||||||
top:0px;
|
|
||||||
font-size:20px;
|
|
||||||
}
|
|
||||||
#uploadButton:hover {
|
|
||||||
border: 1px solid gray;
|
|
||||||
}
|
|
||||||
.note {
|
|
||||||
padding:5px;
|
|
||||||
position:relative;
|
|
||||||
width:calc( 100% - 60px );
|
|
||||||
left:25px;
|
|
||||||
border:1px solid #AAAAAAFF;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #AAAAAA66;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 450px) {
|
|
||||||
#content {
|
|
||||||
position:fixed;
|
|
||||||
left:0%;
|
|
||||||
top:0%;
|
|
||||||
transform:translate(0%,0%);
|
|
||||||
background-color:white;
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<input type="text" id="CopyTB" value="" readonly style="opacity:0;width:10px;height:0%;">
|
|
||||||
<div id="content">
|
|
||||||
<h1>
|
|
||||||
monofile<span style="font-style:italic;font-weight:bold;font-size:16px;color:#999999"> $Version</span>
|
|
||||||
</h1>
|
|
||||||
<h2><em>Discord-based file sharing</em></h2>
|
|
||||||
<div class="note" style="border-color:#FFAAAAFF;background-color:#FFAAAA66">
|
|
||||||
Before sharing files, please remember:
|
|
||||||
<ul>
|
|
||||||
<li>Do NOT share sensitive information via monofile</li>
|
|
||||||
<li>Do NOT share illegal content via monofile</li>
|
|
||||||
<li>The owner of this instance reserves the right to remove your files</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div style="width:100%;height:25px"></div>
|
|
||||||
<div id="btnContainer"><button id="uploadButton">Input a URL</button></div>
|
|
||||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">
|
|
||||||
Max filesize on instance: $MaxInstanceFilesize
|
|
||||||
</p>
|
|
||||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;font-size:12px;color:gray;">made by nbitzz — <a style="color:gray;font-family:monospace;font-size:12px;" href="https://github.com/nbitzz/monofile">github</a> — <a style="color:gray;font-family:monospace;font-size:12px;" href="/">upload a file...</a></p>
|
|
||||||
<div style="width:100%;height:25px"></div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let updateBtnTxt = (btntxt) => {document.getElementById("btnContainer").innerHTML = `<div class="note" style="width:calc( 100% - 10px );height:calc( 100% - 10px );position:absolute;left:0px;top:0px;"><p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">${btntxt}</p></div>`}
|
|
||||||
|
|
||||||
document.getElementById("uploadButton").addEventListener("click",() => {
|
|
||||||
let ask = prompt("Input a URL to clone.")
|
|
||||||
|
|
||||||
if (ask) {
|
|
||||||
updateBtnTxt("Requesting clone. Please wait.")
|
|
||||||
|
|
||||||
let xmlhttp = new XMLHttpRequest()
|
|
||||||
|
|
||||||
xmlhttp.addEventListener("error",function(e) {
|
|
||||||
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
xmlhttp.addEventListener("load",function() {
|
|
||||||
if (xmlhttp.status == 200) {
|
|
||||||
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
|
||||||
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
|
||||||
} else {
|
|
||||||
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
xmlhttp.open("POST","/clone")
|
|
||||||
xmlhttp.send(ask)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
|
73
src/index.ts
73
src/index.ts
|
@ -1,3 +1,7 @@
|
||||||
|
/*
|
||||||
|
i really should split this up into different modules
|
||||||
|
*/
|
||||||
|
|
||||||
import bodyParser from "body-parser"
|
import bodyParser from "body-parser"
|
||||||
import multer, {memoryStorage} from "multer"
|
import multer, {memoryStorage} from "multer"
|
||||||
import Discord, { IntentsBitField, Client } from "discord.js"
|
import Discord, { IntentsBitField, Client } from "discord.js"
|
||||||
|
@ -55,9 +59,11 @@ let uploadFile = (settings:FileUploadSettings,fBuffer:Buffer) => {
|
||||||
return new Promise<string>(async (resolve,reject) => {
|
return new Promise<string>(async (resolve,reject) => {
|
||||||
if (!settings.name || !settings.mime) {reject({status:400,message:"missing name/mime"});return}
|
if (!settings.name || !settings.mime) {reject({status:400,message:"missing name/mime"});return}
|
||||||
|
|
||||||
let uploadId = settings.uploadId || Math.random().toString().slice(2)
|
let uploadId = (settings.uploadId || Math.random().toString().slice(2)).toString();
|
||||||
|
|
||||||
|
if ((uploadId.match(/[A-Za-z0-9_\-]+/)||[])[0] != uploadId || uploadId.length > 30) {reject({status:400,message:"invalid id"});return}
|
||||||
|
|
||||||
if (files[uploadId]) {reject({status:500,message:"please try again"});return}
|
if (files[uploadId]) {reject({status:400,message:"a file with this id already exists"});return}
|
||||||
if (settings.name.length > 128) {reject({status:400,message:"name too long"}); return}
|
if (settings.name.length > 128) {reject({status:400,message:"name too long"}); return}
|
||||||
if (settings.name.length > 128) {reject({status:400,message:"mime too long"}); return}
|
if (settings.name.length > 128) {reject({status:400,message:"mime too long"}); return}
|
||||||
|
|
||||||
|
@ -104,24 +110,45 @@ let uploadFile = (settings:FileUploadSettings,fBuffer:Buffer) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
app.get("/", function(req,res) {
|
app.get("/", function(req,res) {
|
||||||
fs.readFile(__dirname+"/../pages/upload.html",(err,buf) => {
|
fs.readFile(__dirname+"/../pages/base.html",(err,buf) => {
|
||||||
if (err) {res.sendStatus(500);console.log(err);return}
|
if (err) {res.sendStatus(500);console.log(err);return}
|
||||||
res.send(buf.toString().replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`).replace(/\$Version/g,pkg.version))
|
res.send(
|
||||||
|
buf.toString()
|
||||||
|
.replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`)
|
||||||
|
.replace(/\$Version/g,pkg.version)
|
||||||
|
.replace(/\$Handler/g,"upload_file")
|
||||||
|
.replace(/\$UploadButtonText/g,"Upload file")
|
||||||
|
.replace(/\$otherPath/g,"/clone")
|
||||||
|
.replace(/\$otherText/g,"clone from url...")
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get("/clone", function(req,res) {
|
app.get("/clone", function(req,res) {
|
||||||
fs.readFile(__dirname+"/../pages/clone.html",(err,buf) => {
|
fs.readFile(__dirname+"/../pages/base.html",(err,buf) => {
|
||||||
if (err) {res.sendStatus(500);console.log(err);return}
|
if (err) {res.sendStatus(500);console.log(err);return}
|
||||||
res.send(buf.toString().replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`).replace(/\$Version/g,pkg.version))
|
res.send(
|
||||||
|
buf.toString()
|
||||||
|
.replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`)
|
||||||
|
.replace(/\$Version/g,pkg.version)
|
||||||
|
.replace(/\$Handler/g,"clone_file")
|
||||||
|
.replace(/\$UploadButtonText/g,"Input a URL")
|
||||||
|
.replace(/\$otherPath/g,"/")
|
||||||
|
.replace(/\$otherText/g,"upload file...")
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
app.post("/upload",multerSetup.single('file'),async (req,res) => {
|
app.post("/upload",multerSetup.single('file'),async (req,res) => {
|
||||||
if (req.file) {
|
if (req.file) {
|
||||||
uploadFile({name:req.file.originalname,mime:req.file.mimetype},req.file.buffer)
|
try {
|
||||||
.then((uID) => res.send(uID))
|
uploadFile({name:req.file.originalname,mime:req.file.mimetype,uploadId:req.header("monofile-upload-id")},req.file.buffer)
|
||||||
.catch((stat) => {res.status(stat.status);res.send(`[err] ${stat.message}`)})
|
.then((uID) => res.send(uID))
|
||||||
|
.catch((stat) => {res.status(stat.status);res.send(`[err] ${stat.message}`)})
|
||||||
|
} catch {
|
||||||
|
res.status(400)
|
||||||
|
res.send("[err] bad request")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res.status(400)
|
res.status(400)
|
||||||
res.send("[err] bad request")
|
res.send("[err] bad request")
|
||||||
|
@ -129,14 +156,24 @@ app.post("/upload",multerSetup.single('file'),async (req,res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
app.post("/clone",(req,res) => {
|
app.post("/clone",(req,res) => {
|
||||||
axios.get(req.body,{responseType:"arraybuffer"}).then((data:AxiosResponse) => {
|
try {
|
||||||
uploadFile({name:req.body.split("/")[req.body.split("/").length-1] || "generic",mime:data.headers["content-type"]},Buffer.from(data.data))
|
let j = JSON.parse(req.body)
|
||||||
.then((uID) => res.send(uID))
|
if (!j.url) {
|
||||||
.catch((stat) => {res.status(stat.status);res.send(`[err] ${stat.message}`)})
|
res.status(400)
|
||||||
}).catch((err) => {
|
res.send("[err] invalid url")
|
||||||
res.status(400)
|
}
|
||||||
res.send(`[err] failed to fetch data`)
|
axios.get(j.url,{responseType:"arraybuffer"}).then((data:AxiosResponse) => {
|
||||||
})
|
uploadFile({name:req.body.split("/")[req.body.split("/").length-1] || "generic",mime:data.headers["content-type"],uploadId:j.uploadId},Buffer.from(data.data))
|
||||||
|
.then((uID) => res.send(uID))
|
||||||
|
.catch((stat) => {res.status(stat.status);res.send(`[err] ${stat.message}`)})
|
||||||
|
}).catch((err) => {
|
||||||
|
res.status(400)
|
||||||
|
res.send(`[err] failed to fetch data`)
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
res.status(500)
|
||||||
|
res.send("[err] an error occured")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get("/download/:fileId",(req,res) => {
|
app.get("/download/:fileId",(req,res) => {
|
||||||
|
@ -192,8 +229,6 @@ app.get("*",(req,res) => {
|
||||||
ThrowError(res,404,"Page not found.")
|
ThrowError(res,404,"Page not found.")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
client.on("ready",() => {
|
client.on("ready",() => {
|
||||||
console.log("Discord OK!")
|
console.log("Discord OK!")
|
||||||
|
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
hi, this is a port of nbitzz/theUnfunny@fb57d8d65f
|
|
||||||
so the code is pretty bad
|
|
||||||
(but let's be real, all of my code is bad lmao)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Client, SlashCommandBuilder, Routes, ChatInputCommandInteraction } from "discord.js";
|
|
||||||
|
|
||||||
export class SlashCommand {
|
|
||||||
readonly builder: SlashCommandBuilder|Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">|Omit<SlashCommandBuilder, "addBooleanOption" | "addUserOption" | "addChannelOption" | "addRoleOption" | "addAttachmentOption" | "addMentionableOption" | "addStringOption" | "addIntegerOption" | "addNumberOption">
|
|
||||||
readonly assetPath: string
|
|
||||||
readonly type:string = "SCM.SlashCommand"
|
|
||||||
action?: (interaction:ChatInputCommandInteraction) => Promise<any>
|
|
||||||
|
|
||||||
ephmeralReply?:boolean
|
|
||||||
allowInDMs?:boolean
|
|
||||||
|
|
||||||
constructor(command:SlashCommandBuilder|Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">|Omit<SlashCommandBuilder, "addBooleanOption" | "addUserOption" | "addChannelOption" | "addRoleOption" | "addAttachmentOption" | "addMentionableOption" | "addStringOption" | "addIntegerOption" | "addNumberOption">) {
|
|
||||||
this.builder = command
|
|
||||||
this.assetPath = `${process.cwd()}/assets/commands/${command.name}/`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SlashCommandManager {
|
|
||||||
private commands:SlashCommand[] = []
|
|
||||||
private readonly client: Client
|
|
||||||
readonly type:string = "SCM.SlashCommandManager"
|
|
||||||
|
|
||||||
constructor(client: Client) {
|
|
||||||
this.client = client
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Register slash commands
|
|
||||||
*/
|
|
||||||
register() {
|
|
||||||
return new Promise(async (resolve,reject) => {
|
|
||||||
console.log("[SlashCommandManager] Registering commands...")
|
|
||||||
|
|
||||||
if (this.client.user) {
|
|
||||||
this.commands.forEach((e) => {
|
|
||||||
e.builder.setDMPermission(e.allowInDMs)
|
|
||||||
})
|
|
||||||
|
|
||||||
let result = await this.client.rest.put(
|
|
||||||
Routes.applicationCommands(this.client.user.id),
|
|
||||||
{ body: this.commands.map(e => e.builder.toJSON()) }
|
|
||||||
)
|
|
||||||
|
|
||||||
console.log(`[SlashCommandManager] Slash commands registered.`)
|
|
||||||
resolve(result)
|
|
||||||
} else {
|
|
||||||
console.error("[SlashCommandManager] Not logged in")
|
|
||||||
reject("Not logged in")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Process a command
|
|
||||||
*/
|
|
||||||
|
|
||||||
call(int:ChatInputCommandInteraction) {
|
|
||||||
let command = this.commands.find(e => e.builder.name == int.commandName)
|
|
||||||
if (command && command.action) {
|
|
||||||
int.deferReply({
|
|
||||||
ephemeral:command.ephmeralReply
|
|
||||||
}).then(() => {
|
|
||||||
if (command && command.action) {
|
|
||||||
command.action(int).catch((err) => {
|
|
||||||
// error handling
|
|
||||||
int.editReply({
|
|
||||||
embeds:[
|
|
||||||
{description:"Oops, something broke. Maybe try that again?",color:0xff0000}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
console.error(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Add a slash command to the manager
|
|
||||||
*/
|
|
||||||
add(command:SlashCommand) {
|
|
||||||
this.commands.push(command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// type guard
|
|
||||||
|
|
||||||
export let isSlashCommand = (sc: any): sc is SlashCommand => {return sc&&sc.type=="SCM.SlashCommand"}
|
|
Loading…
Reference in a new issue