Compare commits
7 Commits
6de2baa38e
...
168f45337f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
168f45337f | ||
|
|
21693e8fe4 | ||
|
|
6e3d6b45ac | ||
|
|
393bea6185 | ||
|
|
9bbc0b8263 | ||
|
|
8e85028076 | ||
|
|
6e1573e6d0 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
node_modules
|
||||
uploads/*
|
||||
database.sqlite*
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
A simple file sharing platform
|
||||
|
||||
# NOT FINISHED, im doing my best
|
||||
# NOT FINISHED, i am doing my best
|
||||
83
app.js
83
app.js
@@ -11,60 +11,99 @@ const app = express()
|
||||
const http = require('http');
|
||||
const server = http.createServer(app);
|
||||
const { Server } = require("socket.io");
|
||||
const { SqliteHandler, UploadObject } = require('./handlers/sqliteHandler');
|
||||
var fs = require('fs')
|
||||
const io = new Server(server);
|
||||
|
||||
sqliteobj = new SqliteHandler("database.sqlite");
|
||||
db = sqliteobj.getDatabaseObj();
|
||||
|
||||
// Make your Express server:
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(__dirname + "/forms/select.html");
|
||||
})
|
||||
|
||||
app.get('/api', (req, res) => {
|
||||
res.status(200).json({status:"ok", code:200})
|
||||
})
|
||||
|
||||
app.get('/api/download/:hash', (req, res) => {
|
||||
if(handler == undefined) {
|
||||
var handler = new UploadObject(db);
|
||||
}
|
||||
handler.load(req.params.hash);
|
||||
if(handler.isLoaded()){
|
||||
res.status(200).json({result: {
|
||||
files: handler.getFiles()
|
||||
}, code:200})
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/upload', (req, res) => {
|
||||
res.sendFile(__dirname + "/forms/upload.html");
|
||||
})
|
||||
|
||||
app.get('/download', (req, res) => {
|
||||
app.get('/download/(*)', (req, res) => {
|
||||
res.sendFile(__dirname + "/forms/download.html");
|
||||
})
|
||||
|
||||
app.get('/download/:hash', (req, res) => {
|
||||
mac = req.params.hash;
|
||||
res.send("sdadsd");
|
||||
})
|
||||
// app.get('/download/:hash', (req, res) => {
|
||||
// if(handler == undefined) {
|
||||
// var handler = new UploadObject(db);
|
||||
// }
|
||||
// console.log(handler)
|
||||
// handler.load(req.params.hash)
|
||||
// if(handler.isLoaded()) {
|
||||
// res.send("Found");
|
||||
// } else {
|
||||
// notFound();
|
||||
// }
|
||||
|
||||
app.get('/upload', (req, res) => {
|
||||
// parsedUrl = req.socket.handshake.headers.referer.split(req.socket.handshake.headers.host, 2);
|
||||
// console.log(parsedUrl[0]);
|
||||
// console.log(parsedUrl[1]);
|
||||
|
||||
// Make an instance of SocketIOFileUpload and listen on this socket:
|
||||
res.send("upload");
|
||||
})
|
||||
|
||||
// })
|
||||
// app.get('/download/:hash/:adminhash', (req, res) => {
|
||||
// handler.load(req.params.hash, req.params.adminhash)
|
||||
// res.send("sdadsd");
|
||||
// })
|
||||
|
||||
|
||||
// Start up Socket.IO:
|
||||
// var io = new socketio.Server(app.listen(port));
|
||||
io.sockets.on("connection", function(socket){
|
||||
var handler = new UploadObject(db);
|
||||
console.log(handler);
|
||||
if(socket.handshake.url.startsWith("/socket.io")) {
|
||||
|
||||
var uploader = new SocketIOFileUpload();
|
||||
uploader.dir = "uploads";
|
||||
uploader.dir = "tmp";
|
||||
|
||||
uploader.uploadValidator = function(event, callback){
|
||||
// asynchronous operations allowed here; when done,
|
||||
console.log(event);
|
||||
if (false) {
|
||||
if (true) {
|
||||
callback(true);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
};
|
||||
|
||||
uploader.listen(socket);
|
||||
uploader.on("start", function(event){
|
||||
// console.log(handler);
|
||||
handler.new();
|
||||
});
|
||||
|
||||
|
||||
// Do something when a file is saved:
|
||||
uploader.on("saved", function(event){
|
||||
if (event.file.success) {
|
||||
fs.renameSync(event.file.pathName, "uploads/"+handler.getDir()+"/"+event.file.name)
|
||||
handler.registerFile(event.file.name);
|
||||
}
|
||||
console.log(event.file);
|
||||
|
||||
});
|
||||
uploader.on("complete", function(event){
|
||||
socket.emit("linkCreated", handler.getHash(), handler.getAdminHash());
|
||||
});
|
||||
// Error handler:
|
||||
uploader.on("error", function(event){
|
||||
@@ -73,10 +112,8 @@ io.sockets.on("connection", function(socket){
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.use(function (req, res, next) {
|
||||
function notFound(req, res) {
|
||||
res.status(404);
|
||||
console.log(req.query);
|
||||
ans = { error: 'Not found', code: 404 }
|
||||
if (req.query.format == "xml"){
|
||||
res.set('Content-Type', 'text/xml');
|
||||
@@ -101,8 +138,14 @@ app.use(function (req, res, next) {
|
||||
|
||||
// default to plain-text. send()
|
||||
res.send('404');
|
||||
}
|
||||
|
||||
app.use(function (req, res, next) {
|
||||
notFound(req,res)
|
||||
});
|
||||
|
||||
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log('listening on *:8000');
|
||||
});
|
||||
|
||||
BIN
database.mwb
Normal file
BIN
database.mwb
Normal file
Binary file not shown.
73
forms/download.html
Normal file
73
forms/download.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!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>Kakubovna: Download</title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Geologica:wght@800&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="flex-container">
|
||||
<div id="code-view" class="container vertical" style="display:none">
|
||||
<input id="code" type="text" placeholder="Enter code">
|
||||
<button onclick="loadUpload()">Submit</button>
|
||||
<p id="status"></p>
|
||||
</div>
|
||||
<div id="file-view" class="container vertical" style="display:none">
|
||||
<input id="code" type="text" placeholder="Enter code">
|
||||
<button onclick="loadUpload()">Submit</button>
|
||||
<p id="status"></p>
|
||||
</div>
|
||||
<div id="admin-file-view" class="container vertical" style="display:none">
|
||||
<input id="code" type="text" placeholder="Enter code">
|
||||
<button onclick="loadUpload()">Submit</button>
|
||||
<p id="status"></p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var hash = "";
|
||||
var adminHash = "";
|
||||
handleUrl();
|
||||
function handleUrl() {
|
||||
console.log(document.location.pathname.split("/", 4));
|
||||
path = document.location.pathname.split("/", 4)
|
||||
if(path[2].length > 10 && path[2] === path[2].toUpperCase()) {
|
||||
hash = path[2];
|
||||
if(path[3].length == 10 && path[3] === path[3].toUpperCase()) {
|
||||
adminHash = path[3];
|
||||
}
|
||||
} else {
|
||||
document.getElementById("code-view").style = "";
|
||||
}
|
||||
}
|
||||
codeInput = document.getElementById("code");
|
||||
statusText = document.getElementById("status");
|
||||
function loadUpload() {
|
||||
if (!(codeInput.value.length > 10 && codeInput.value === codeInput.value.toUpperCase())) {
|
||||
statusText.innerHTML = 'Wrong Code';
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/api/download/' + codeInput.value)
|
||||
.then(
|
||||
response => response.json()
|
||||
).then(jsonResponse => {
|
||||
console.log(jsonResponse);
|
||||
|
||||
if (jsonResponse.code == 404) {
|
||||
statusText.innerHTML = 'Not Found';
|
||||
} else if (jsonResponse.code == 200) {
|
||||
statusText.innerHTML = 'Found';
|
||||
} else {
|
||||
statusText.innerHTML = 'Error';
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
82
forms/select.html
Normal file
82
forms/select.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<!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>Kakubovna: Select</title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Geologica:wght@800&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="flex-container">
|
||||
<div id="select" class="container">
|
||||
<div class="card-button-box">
|
||||
<div class="card-button" onclick="window.location.href = document.URL+'upload'"><img src="/img/add-sharp-white.svg" alt="Upload"></div>
|
||||
<div class="card-button" onclick="window.location.href = document.URL+'download'"><img src="/img/arrow-down-white.svg" alt="Download"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <canvas id="c" style="width: 100%; height: 100%; position: absolute;"></canvas> -->
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// geting canvas by Boujjou Achraf
|
||||
var c = document.getElementById("c");
|
||||
var ctx = c.getContext("2d");
|
||||
|
||||
//making the canvas full screen
|
||||
c.height = window.innerHeight;
|
||||
c.width = window.innerWidth;
|
||||
|
||||
//chinese characters - taken from the unicode charset
|
||||
var matrix = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789@#$%^&*()*&^%+-/~{[|`]}";
|
||||
//converting the string into an array of single characters
|
||||
matrix = matrix.split("");
|
||||
|
||||
var font_size = 10;
|
||||
var columns = c.width / font_size; //number of columns for the rain
|
||||
//an array of drops - one per column
|
||||
var drops = [];
|
||||
//x below is the x coordinate
|
||||
//1 = y co-ordinate of the drop(same for every drop initially)
|
||||
for (var x = 0; x < columns; x++)
|
||||
drops[x] = 1;
|
||||
|
||||
//drawing the characters
|
||||
function draw() {
|
||||
rainbow = ['#ff0000', '#ffa500', '#ffff00', '#008000', '#00FFFF', '#4b0082', '#ee82ee'];
|
||||
//Black BG for the canvas
|
||||
//translucent BG to show trail
|
||||
ctx.fillStyle = "rgba(0, 0, 0, 0.04)";
|
||||
ctx.fillRect(0, 0, c.width, c.height);
|
||||
|
||||
ctx.fillStyle = rainbow[Math.floor(Math.random() * 5)];//green text
|
||||
ctx.font = font_size + "px arial";
|
||||
//looping over drops
|
||||
for (var i = 0; i < drops.length; i++) {
|
||||
//a random chinese character to print
|
||||
var text = matrix[Math.floor(Math.random() * matrix.length)];
|
||||
//x = i*font_size, y = value of drops[i]*font_size
|
||||
ctx.fillText(text, i * font_size, drops[i] * font_size);
|
||||
|
||||
//sending the drop back to the top randomly after it has crossed the screen
|
||||
//adding a randomness to the reset to make the drops scattered on the Y axis
|
||||
if (drops[i] * font_size > c.height && Math.random() > 0.975)
|
||||
drops[i] = 0;
|
||||
|
||||
//incrementing Y coordinate
|
||||
drops[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(draw, 35);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
144
forms/upload.html
Normal file
144
forms/upload.html
Normal file
@@ -0,0 +1,144 @@
|
||||
<!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>Kakubovna: Upload</title>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Geologica:wght@800&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="flex-container">
|
||||
<div id="upload" class="container vertical">
|
||||
<div class="dropZoneContainer">
|
||||
<input type="file" title="" id="drop_zone" class="FileUpload" onchange="addFiles(this.files)" multiple/>
|
||||
<div class="dropZoneOverlay"><p>Drag and drop your files <br />or<br />Click to add</p></div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<table class="filelist"></table>
|
||||
</div>
|
||||
<button style="vertical-align:middle" class="button" onclick="startUpload()"><span>Upload </span></button>
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="c" style="width: 100%; height: 100%; position: absolute;"></canvas>
|
||||
|
||||
<script src="js/socket.io.js"></script>
|
||||
<script src="js/siofu-client.js"></script>
|
||||
<script>
|
||||
var selectedFiles = [];
|
||||
|
||||
function addFiles(files) {
|
||||
Array.from(files).forEach(file => {
|
||||
addFile(file);
|
||||
});
|
||||
}
|
||||
|
||||
function addFile(file) {
|
||||
console.log(selectedFiles.find((element) => element.name == file.name))
|
||||
if(selectedFiles.find((element) => element.name == file.name) == undefined) {
|
||||
selectedFiles.push(file);
|
||||
}
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
function shortString(str, maxlen = 13) {
|
||||
if(str.length > maxlen) {
|
||||
shortstr = str.slice(0, (maxlen-3)/2)+"..."+str.slice(-(maxlen-3)/2);
|
||||
} else {
|
||||
shortstr = str;
|
||||
}
|
||||
return shortstr;
|
||||
}
|
||||
|
||||
function updateFileList(maxlen = 30) {
|
||||
filelist = document.getElementsByClassName("filelist")[0];
|
||||
filelist.innerHTML = "";
|
||||
i = 0
|
||||
selectedFiles.forEach(file => {
|
||||
filelist.innerHTML += "<tr title=\""+file.name+"\"><td>"+shortString(file.name, maxlen)+"</td></tr>";
|
||||
i++;
|
||||
});
|
||||
}
|
||||
|
||||
var socket = io.connect(
|
||||
{
|
||||
forceNew: true,
|
||||
extraHeaders: {
|
||||
Authorization: "bsadsds"
|
||||
}
|
||||
}
|
||||
);
|
||||
var uploader = new SocketIOFileUpload(socket);
|
||||
uploader.addEventListener("choose", function (event) {
|
||||
console.log("Files Chosen: " + event.files);
|
||||
});
|
||||
uploader.addEventListener("progress", function (event) {
|
||||
console.log("Files Chosen: " + event.bytesLoaded / event.file.size);
|
||||
});
|
||||
|
||||
function startUpload() {
|
||||
uploader.submitFiles(selectedFiles);
|
||||
}
|
||||
socket.once("linkCreated", (hash, adminhash) => {
|
||||
console.log("Link Created");
|
||||
window.location.href = document.location.protocol+"//"+document.location.host+"/api/download/"+hash+'/'
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// geting canvas by Boujjou Achraf
|
||||
var c = document.getElementById("c");
|
||||
var ctx = c.getContext("2d");
|
||||
|
||||
//making the canvas full screen
|
||||
c.height = window.innerHeight;
|
||||
c.width = window.innerWidth;
|
||||
|
||||
//chinese characters - taken from the unicode charset
|
||||
var matrix = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789@#$%^&*()*&^%+-/~{[|`]}";
|
||||
//converting the string into an array of single characters
|
||||
matrix = matrix.split("");
|
||||
|
||||
var font_size = 10;
|
||||
var columns = c.width / font_size; //number of columns for the rain
|
||||
//an array of drops - one per column
|
||||
var drops = [];
|
||||
//x below is the x coordinate
|
||||
//1 = y co-ordinate of the drop(same for every drop initially)
|
||||
for (var x = 0; x < columns; x++)
|
||||
drops[x] = 1;
|
||||
|
||||
//drawing the characters
|
||||
function draw() {
|
||||
rainbow = ['#ff0000', '#ffa500', '#ffff00', '#008000', '#00FFFF', '#4b0082', '#ee82ee'];
|
||||
//Black BG for the canvas
|
||||
//translucent BG to show trail
|
||||
ctx.fillStyle = "rgba(0, 0, 0, 0.04)";
|
||||
ctx.fillRect(0, 0, c.width, c.height);
|
||||
|
||||
ctx.fillStyle = rainbow[Math.floor(Math.random() * 5)];//green text
|
||||
ctx.font = font_size + "px arial";
|
||||
//looping over drops
|
||||
for (var i = 0; i < drops.length; i++) {
|
||||
//a random chinese character to print
|
||||
var text = matrix[Math.floor(Math.random() * matrix.length)];
|
||||
//x = i*font_size, y = value of drops[i]*font_size
|
||||
ctx.fillText(text, i * font_size, drops[i] * font_size);
|
||||
|
||||
//sending the drop back to the top randomly after it has crossed the screen
|
||||
//adding a randomness to the reset to make the drops scattered on the Y axis
|
||||
if (drops[i] * font_size > c.height && Math.random() > 0.975)
|
||||
drops[i] = 0;
|
||||
|
||||
//incrementing Y coordinate
|
||||
drops[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(draw, 35);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
0
handlers/fileHandler.js
Normal file
0
handlers/fileHandler.js
Normal file
168
handlers/sqliteHandler.js
Normal file
168
handlers/sqliteHandler.js
Normal file
@@ -0,0 +1,168 @@
|
||||
module.exports = {
|
||||
|
||||
UploadObject: class UploadObject {
|
||||
constructor(db) {
|
||||
this.db = db;
|
||||
this.absrc = ['E', 'T', 'X', 'W', 'U', 'R', 'J', 'I', 'N', 'C'];
|
||||
this.loaded = false;
|
||||
this.fileCache = {};
|
||||
}
|
||||
|
||||
new() {
|
||||
if (!this.loaded) {
|
||||
this.hashsalt = this.makeHash(10);
|
||||
this.adminhash = this.makeHash(10);
|
||||
var sql = this.db.prepare(`INSERT INTO "upload" (hashsalt, adminhash, upload_unix) VALUES (?, ?, ?)`);
|
||||
var result = sql.run(this.hashsalt, this.adminhash, Math.floor(Date.now() / 1000));
|
||||
this.id = result.lastInsertRowid;
|
||||
this.hashid = this.id2hashid(result.lastInsertRowid);
|
||||
this.dir = this.hashid+this.hashsalt;
|
||||
var fs = require('fs');
|
||||
|
||||
if (!fs.existsSync("uploads/"+this.dir)){
|
||||
fs.mkdirSync("uploads/"+this.dir);
|
||||
}
|
||||
|
||||
this.loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
load(hash) {
|
||||
if (!this.loaded) {
|
||||
var shash = this.splitHash(hash);
|
||||
this.hashid = shash[0];
|
||||
this.id = this.hashid2id(this.hashid)
|
||||
this.hashsalt = shash[1];
|
||||
this.dir = this.hashid+this.hashsalt;
|
||||
|
||||
var sql = this.db.prepare(`SELECT EXISTS(SELECT 1 FROM "upload" WHERE id=? AND hashsalt=? LIMIT 1) AS "exists"`);
|
||||
var result = sql.get(this.id, this.hashsalt);
|
||||
if (result["exists"]) {
|
||||
console.log("LOADED: ", result);
|
||||
this.loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isLoaded() {
|
||||
return this.loaded;
|
||||
}
|
||||
|
||||
getDir() {
|
||||
return this.dir;
|
||||
}
|
||||
|
||||
loadFiles() {
|
||||
this.files = this.db.prepare(`SELECT filename FROM "file" WHERE upload_id=?`).all(this.id);
|
||||
console.log(this.files);
|
||||
}
|
||||
|
||||
getFiles() {
|
||||
this.loadFiles();
|
||||
return this.files;
|
||||
}
|
||||
|
||||
registerFile(filename) {
|
||||
var sql = this.db.prepare(`INSERT INTO "file" (filename, upload_id) VALUES (?, ?)`);
|
||||
var result = sql.run(filename, this.id);
|
||||
return result;
|
||||
}
|
||||
|
||||
delete() {
|
||||
|
||||
}
|
||||
|
||||
getHash() {
|
||||
return this.hashid+this.hashsalt;
|
||||
}
|
||||
|
||||
getHashId() {
|
||||
return this.hashid;
|
||||
}
|
||||
|
||||
getAdminHash() {
|
||||
return this.adminhash;
|
||||
}
|
||||
|
||||
|
||||
id2hashid(id) {
|
||||
var hashid = "";
|
||||
id = id.toString();
|
||||
for (var i = 0; i < id.length; i++) {
|
||||
hashid += this.absrc[id.charAt(i)];
|
||||
}
|
||||
return hashid;
|
||||
}
|
||||
|
||||
hashid2id(hashid) {
|
||||
var id = "";
|
||||
for (var i = 0; i < hashid.length; i++) {
|
||||
var index = this.absrc.findIndex((letter) => letter == hashid.charAt(i));
|
||||
if (!(index < 0)) {
|
||||
id = id + index.toString();
|
||||
};
|
||||
}
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
|
||||
makeHash(len = 10) {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const charactersLength = characters.length;
|
||||
let counter = 0;
|
||||
while (counter < len) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
counter += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
splitHash(hash) {
|
||||
return [hash.slice(0, hash.length - 10), hash.slice(hash.length - 10, hash.length)]
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
SqliteHandler: class SqliteHandler {
|
||||
constructor(path) {
|
||||
this.loaded = false;
|
||||
this.path = path;
|
||||
this.db = require('better-sqlite3')(this.path);
|
||||
this.db.prepare(`CREATE TABLE IF NOT EXISTS "user" (
|
||||
"id" INTEGER NOT NULL UNIQUE,
|
||||
"name" TEXT NOT NULL UNIQUE,
|
||||
"password" TEXT NOT NULL,
|
||||
"email" INTEGER,
|
||||
"admin" INTEGER,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
)`).run();
|
||||
|
||||
this.db.prepare(`CREATE TABLE IF NOT EXISTS "upload" (
|
||||
"id" INTEGER NOT NULL UNIQUE,
|
||||
"hashsalt" TEXT NOT NULL UNIQUE,
|
||||
"adminhash" TEXT NOT NULL UNIQUE,
|
||||
"desc" TEXT,
|
||||
"password" TEXT,
|
||||
"owner_id" INTEGER,
|
||||
"upload_unix" INTEGER,
|
||||
PRIMARY KEY("id" AUTOINCREMENT),
|
||||
FOREIGN KEY("owner_id") REFERENCES "user"("id")
|
||||
)`).run();
|
||||
|
||||
this.db.prepare(`CREATE TABLE IF NOT EXISTS "file" (
|
||||
"id" INTEGER NOT NULL UNIQUE,
|
||||
"filename" TEXT NOT NULL,
|
||||
"upload_id" INTEGER NOT NULL,
|
||||
"state" INTEGER NOT NULL,
|
||||
PRIMARY KEY("id" AUTOINCREMENT),
|
||||
FOREIGN KEY("upload_id") REFERENCES "upload"("id")
|
||||
)`).run();
|
||||
}
|
||||
|
||||
getDatabaseObj() {
|
||||
return this.db;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
0
handlers/userHandler.js
Normal file
0
handlers/userHandler.js
Normal file
@@ -9,10 +9,10 @@
|
||||
"author": "Dzejkobik",
|
||||
"license": "",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^8.4.0",
|
||||
"express": "^4.18.2",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"socket.io": "^4.6.2",
|
||||
"socketio-file-upload": "^0.7.3",
|
||||
"sqlite3": "^5.1.6"
|
||||
"socketio-file-upload": "^0.7.3"
|
||||
}
|
||||
}
|
||||
|
||||
164
public/css/style.css
Normal file
164
public/css/style.css
Normal file
@@ -0,0 +1,164 @@
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
background-color: #1b1b1b;
|
||||
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.box__dragndrop,
|
||||
.box__uploading,
|
||||
.box__success,
|
||||
.box__error {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
font-family: 'Geologica', sans-serif;
|
||||
border-radius: 4px;
|
||||
border-color: black;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
background-color: #f16d01;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.vertical {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.filelist {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 0;
|
||||
}
|
||||
.filelist p {
|
||||
color:#FFFFFF;
|
||||
}
|
||||
|
||||
.list p {
|
||||
color:#FFFFFF;
|
||||
}
|
||||
|
||||
#select {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
background-color: #e42200;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
padding: 20px;
|
||||
width: 200px;
|
||||
transition: all 0.5s;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.button span {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.button span:after {
|
||||
content: '\00bb';
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
top: 0;
|
||||
right: -20px;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.button:hover span {
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.button:hover span:after {
|
||||
opacity: 1;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.card-button-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 50px;
|
||||
}
|
||||
|
||||
.card-button {
|
||||
background-color: rgba(88, 88, 88, 0.2);
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
width: 200px;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.card-button:hover {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.card-button p {
|
||||
position: absolute;
|
||||
color:#FFFFFF;
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
.dropZoneContainer {
|
||||
display: grid;
|
||||
margin-left: 100px;
|
||||
margin-right: 100px;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.dropZoneOverlay, .FileUpload {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.dropZoneOverlay {
|
||||
margin-top: -3px;
|
||||
margin-left: -3px;
|
||||
border: dotted 3px;
|
||||
font-size: 110%;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.FileUpload {
|
||||
opacity: 0;
|
||||
}
|
||||
1
public/img/add-sharp.svg
Normal file
1
public/img/add-sharp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="square" stroke-linejoin="round" stroke-width="32" d="M256 112v288M400 256H112"/></svg>
|
||||
|
After Width: | Height: | Size: 220 B |
1
public/img/arrow-down.svg
Normal file
1
public/img/arrow-down.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48" d="M112 268l144 144 144-144M256 392V100"/></svg>
|
||||
|
After Width: | Height: | Size: 231 B |
1
public/script.js
Normal file
1
public/script.js
Normal file
@@ -0,0 +1 @@
|
||||
// script.js
|
||||
Reference in New Issue
Block a user