typescripting2

This commit is contained in:
waveringana 2022-12-03 23:48:16 +00:00
parent 850a3bf4d2
commit aacc685da1
12 changed files with 381 additions and 128 deletions

View file

@ -1,30 +1,29 @@
import type {MediaRow, UserRow} from './types';
require("dotenv").config();
const express = require("express");
const passport = require("passport");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const SQLiteStore = require("connect-sqlite3")(session);
import express from "express";
import passport from "passport";
import session from "express-session";
import cookieParser from "cookie-parser";
import sqlite3 from "connect-sqlite3";
const SQLiteStore = sqlite3(session);
const fs = require("fs");
const http = require("http");
const path = require("path");
import fs from "fs";
import http from "http";
import path from "path";
const authRouter = require("./routes/auth");
const indexRouter = require("./routes/index");
import authRouter from "./routes/auth";
import indexRouter from "./routes/index";
const db = require("./db").db;
import {createUser} from "./db";
import db from "./db"
let app = express();
let server = http.createServer(app);
let port = normalizePort(process.env.EBPORT || "3000");
app.set("port", port);
server.listen(port);
server.on("error", onError);
server.on("listening", onListening);
function normalizePort(val) {
function normalizePort(val: string) {
var port = parseInt(val, 10);
if (isNaN(port)) {
@ -40,7 +39,12 @@ function normalizePort(val) {
return false;
}
function onError(error) {
app.set("port", port);
server.listen(port);
server.on("error", onError);
server.on("listening", onListening);
function onError(error: any) {
if (error.syscall !== "listen") {
throw error;
}
@ -64,6 +68,24 @@ function onError(error) {
}
}
db.serialize(function() {
// create the database schema for the todos app
db.run("CREATE TABLE IF NOT EXISTS users ( \
id INTEGER PRIMARY KEY, \
username TEXT UNIQUE, \
hashed_password BLOB, \
salt BLOB \
)");
db.run("CREATE TABLE IF NOT EXISTS media ( \
id INTEGER PRIMARY KEY, \
path TEXT NOT NULL, \
expire INTEGER \
)");
createUser("admin", process.env.EBPASS || "changeme");
});
function onListening() {
var addr = server.address();
var bind = typeof addr === "string"
@ -90,6 +112,7 @@ app.use(session({
secret: process.env.EBSECRET || "pleasechangeme",
resave: false,
saveUninitialized: false,
// @ts-ignore
store: new SQLiteStore({
db: "sessions.db",
dir: "./var/db"
@ -103,7 +126,7 @@ app.use("/", authRouter);
app.use("/uploads", express.static("uploads"));
function prune () {
db.all("SELECT * FROM media", (err, rows) => {
db.all("SELECT * FROM media", (err: Error, rows: []) => {
console.log("Uploaded files: " + rows.length);
console.log(rows);
});
@ -111,23 +134,23 @@ function prune () {
console.log("Vacuuming database...");
db.run("VACUUM");
db.all("SELECT * FROM media WHERE expire < ?", [Date.now()], (err, rows) => {
db.all("SELECT * FROM media WHERE expire < ?", [Date.now()], (err: Error, rows: []) => {
console.log("Expired rows: " + rows);
if (err) return console.error(err);
rows.forEach((row) => {
rows.forEach((row: MediaRow) => {
console.log(`Deleting ${row.path}`);
fs.unlink(`uploads/${row.path}`, (err) => {
if (err) {
if(err.errno == -4058) {
console.log("File already deleted");
db.all("DELETE FROM media WHERE path = ?", [row.path], (err) => {
db.all("DELETE FROM media WHERE path = ?", [row.path], (err: Error) => {
if (err) return console.error(err);
});
} else {
console.error(err);
}
} else {
db.all("DELETE FROM media WHERE path = ?", [row.path], (err) => {
db.all("DELETE FROM media WHERE path = ?", [row.path], (err: Error) => {
if (err) return console.error(err);
});
}
@ -137,6 +160,4 @@ function prune () {
});
}
setInterval(prune, 1000 * 60); //prune every minute
module.exports = app;
setInterval(prune, 1000 * 60); //prune every minute

View file

@ -1,37 +0,0 @@
const sqlite3 = require("sqlite3");
const mkdirp = require("mkdirp");
const crypto = require("crypto");
mkdirp.sync("./uploads");
mkdirp.sync("./var/db");
let db = new sqlite3.Database("./var/db/media.db");
db.serialize(function() {
// create the database schema for the todos app
db.run("CREATE TABLE IF NOT EXISTS users ( \
id INTEGER PRIMARY KEY, \
username TEXT UNIQUE, \
hashed_password BLOB, \
salt BLOB \
)");
db.run("CREATE TABLE IF NOT EXISTS media ( \
id INTEGER PRIMARY KEY, \
path TEXT NOT NULL, \
expire INTEGER \
)");
createUser("admin", process.env.EBPASS || "changeme");
});
function createUser(username, password) {
var salt = crypto.randomBytes(16);
db.run("INSERT OR IGNORE INTO users (username, hashed_password, salt) VALUES (?, ?, ?)", [
username,
crypto.pbkdf2Sync(password, salt, 310000, 32, "sha256"),
salt
]);
}
module.exports = {db: db, createUser: createUser};

21
app/db.ts Normal file
View file

@ -0,0 +1,21 @@
import type {RequestHandler as Middleware} from 'express';
const sqlite3 = require("sqlite3");
const mkdirp = require("mkdirp");
const crypto = require("crypto");
mkdirp.sync("./uploads");
mkdirp.sync("./var/db");
let db = new sqlite3.Database("./var/db/media.db");
export function createUser(username: string, password: string) {
var salt = crypto.randomBytes(16);
db.run("INSERT OR IGNORE INTO users (username, hashed_password, salt) VALUES (?, ?, ?)", [
username,
crypto.pbkdf2Sync(password, salt, 310000, 32, "sha256"),
salt
]);
}
export default db;

View file

@ -1,14 +1,18 @@
const crypto = require("crypto");
const express = require("express");
const passport = require("passport");
const LocalStrategy = require("passport-local");
import type {MediaRow, UserRow} from '../types';
import type {RequestHandler as Middleware} from 'express';
let db = require("../db").db;
import crypto from "crypto";
import express from "express";
import passport from "passport";
import { Strategy as LocalStrategy } from "passport-local";
import db from "../db";
let router = express.Router();
passport.use(new LocalStrategy(function verify(username, password, cb) {
db.get("SELECT * FROM users WHERE username = ?", [username], function(err, row) {
db.get("SELECT * FROM users WHERE username = ?", [username], function(err: Error, row: UserRow) {
if (err) {
return cb(err);
}
@ -35,7 +39,9 @@ passport.use(new LocalStrategy(function verify(username, password, cb) {
passport.serializeUser(function(user, cb) {
process.nextTick(function() {
cb(null, {
// @ts-ignore
id: user.id,
// @ts-ignore
username: user.username
});
});
@ -47,6 +53,7 @@ passport.deserializeUser(function(user, cb) {
});
});
// @ts-ignore
router.get("/login", function(req, res) {
res.render("login");
});
@ -66,4 +73,4 @@ router.post("/logout", function(req, res, next) {
});
});
module.exports = router;
export default router;

View file

@ -1,19 +1,24 @@
const multer = require("multer");
const express = require("express");
const ffmpeg = require("fluent-ffmpeg");
const imageProbe = require("probe-image-size");
const ffmpegpath = require("@ffmpeg-installer/ffmpeg").path;
const ffprobepath = require("@ffprobe-installer/ffprobe").path;
import type {RequestHandler as Middleware, Router, Request, Response} from 'express';
import types from 'multer';
ffmpeg.setFfmpegPath(ffmpegpath);
ffmpeg.setFfprobePath(ffprobepath);
import multer from "multer";
import express from "express";
import ffmpeg from "fluent-ffmpeg";
import imageProbe from "probe-image-size";
import ffmpegpath from "@ffmpeg-installer/ffmpeg";
// @ts-ignore
import ffprobepath from "@ffprobe-installer/ffprobe";
const fs = require("fs");
ffmpeg.setFfmpegPath(ffmpegpath.path);
ffmpeg.setFfprobePath(ffprobepath.path);
let db = require("../db").db;
let {checkAuth, convert, handleUpload} = require("./middleware");
import fs from "fs";
function extension(str){
import db from "../db";
import {checkAuth, convert, handleUpload} from "./middleware";
import { MediaRow } from '../types';
function extension(str: String){
let file = str.split("/").pop();
return [file.substr(0,file.lastIndexOf(".")),file.substr(file.lastIndexOf("."),file.length).toLowerCase()];
}
@ -24,7 +29,7 @@ const storage = multer.diskStorage({
},
filename : function(req, file, cb) {
let nameAndExtension = extension(file.originalname);
db.all("SELECT * FROM media WHERE path = ?", [nameAndExtension[0] + nameAndExtension[1]], function (err, exists) {
db.all("SELECT * FROM media WHERE path = ?", [nameAndExtension[0] + nameAndExtension[1]], function (err: Error, exists: []) {
if (exists.length != 0) {
let suffix = new Date().getTime() / 1000;
@ -65,10 +70,10 @@ const fileFilter = function(req, file, cb) {
let upload = multer({ storage: storage /**, fileFilter: fileFilter**/ }); //maybe make this a env variable?
function fetchMedia(req, res, next) {
db.all("SELECT * FROM media", (err, rows) => {
const fetchMedia: Middleware = (req, res, next) => {
db.all("SELECT * FROM media", (err: Error, rows: []) => {
if (err) return next(err);
let files = rows.map((row)=> {
let files = rows.map((row: MediaRow)=> {
return {
id: row.id,
path: row.path,
@ -84,11 +89,11 @@ function fetchMedia(req, res, next) {
let router = express.Router();
router.get("/", function (req, res, next) {
router.get("/", (req, res, next) => {
// @ts-ignore, user is part of req header
if (!req.user) { return res.render("home"); }
next();
}, fetchMedia, function(req, res) {
}, fetchMedia, (req, res) => {
res.locals.filter = null;
// @ts-ignore, user is part of req header
res.render("index", { user: req.user });
@ -125,16 +130,17 @@ router.get("/gifv/:file", async function (req, res, next) {
}
});
router.post("/", [upload.array("fileupload"), convert, handleUpload], function(req, res) {
router.post("/", [upload.array("fileupload"), convert, handleUpload], (req: Request, res: Response) => {
return res.redirect("/");
});
router.post("/sharex", [checkAuth, upload.array("fileupload"), convert, handleUpload], function(req, res) {
router.post("/sharex", [checkAuth, upload.array("fileupload"), convert, handleUpload], (req: Request, res: Response) => {
// @ts-ignore
return res.send(`${req.protocol}://${req.get("host")}/uploads/${req.files[0].filename}`);
});
router.post("/:id(\\d+)/delete", function(req, res, next) {
db.all("SELECT path FROM media WHERE id = ?", [ req.params.id ], function(err, path) {
db.all("SELECT path FROM media WHERE id = ?", [ req.params.id ], function(err: Error, path: Array<any>) {
if (err) { return next(err); }
fs.unlink(`uploads/${path[0].path}`, (err => {
if (err) {
@ -142,7 +148,7 @@ router.post("/:id(\\d+)/delete", function(req, res, next) {
if (err.errno == -4058) { //File just doesnt exist anymore
db.run("DELETE FROM media WHERE id = ?", [
req.params.id
], function(err) {
], (err: Error) => {
if (err) { return next(err); }
return res.redirect("/");
});
@ -155,7 +161,7 @@ router.post("/:id(\\d+)/delete", function(req, res, next) {
//Callback Hell :D
db.run("DELETE FROM media WHERE id = ?", [
req.params.id
], function(err) {
], (err: Error) => {
if (err) { return next(err); }
return res.redirect("/");
});
@ -164,4 +170,4 @@ router.post("/:id(\\d+)/delete", function(req, res, next) {
});
});
module.exports = router;
export default router;

View file

@ -1,21 +1,25 @@
const ffmpeg = require("fluent-ffmpeg");
const ffmpegpath = require("@ffmpeg-installer/ffmpeg").path;
const ffprobepath = require("@ffprobe-installer/ffprobe").path;
ffmpeg.setFfmpegPath(ffmpegpath);
ffmpeg.setFfprobePath(ffprobepath);
import type {MediaRow, UserRow} from '../types';
import type {RequestHandler as Middleware, Router, Request, Response} from 'express';
const fs = require("fs");
const process = require("process");
import ffmpeg from "fluent-ffmpeg";
import ffmpegpath from "@ffmpeg-installer/ffmpeg";
// @ts-ignore
import ffprobepath from "@ffprobe-installer/ffprobe";
ffmpeg.setFfmpegPath(ffmpegpath.path);
ffmpeg.setFfprobePath(ffprobepath.path);
let db = require("../db.js").db;
import fs from "fs";
import process from "process";
function extension(str){
import db from "../db";
function extension(str: String){
let file = str.split("/").pop();
return [file.substr(0,file.lastIndexOf(".")),file.substr(file.lastIndexOf("."),file.length).toLowerCase()];
}
//Checks ShareX key
function checkAuth(req, res, next) {
export const checkAuth: Middleware = (req: Request, res: Response, next: Function) => {
let auth = process.env.EBAPI_KEY || process.env.EBPASS || "pleaseSetAPI_KEY";
let key = null;
@ -36,8 +40,9 @@ function checkAuth(req, res, next) {
}
//Converts mp4 to gif and vice versa with ffmpeg
function convert(req, res, next) {
export const convert: Middleware = (req: Request, res: Response, next: Function) => {
for (let file in req.files) {
// @ts-ignore
let nameAndExtension = extension(req.files[file].originalname);
let oembed = {
type: "video",
@ -92,7 +97,7 @@ function convert(req, res, next) {
next();
}
function handleUpload(req, res, next) {
export const handleUpload: Middleware = (req: Request, res: Response, next: Function) => {
if (!req.files || Object.keys(req.files).length === 0) {
console.log("No files were uploaded");
return res.status(400).send("No files were uploaded.");
@ -100,31 +105,27 @@ function handleUpload(req, res, next) {
for (let file in req.files) {
let currentdate = Date.now();
let expireDate;
let expireDate: Date;
if (req.body.expire) {
expireDate = new Date(currentdate + (req.body.expire * 24 * 60 * 60 * 1000));
console.log(req.body.expire);
console.log(expireDate);
} else
expireDate = null;
// @ts-ignore
db.run("INSERT INTO media (path, expire) VALUES (?, ?)", [req.files[file].filename, expireDate], function (err) {
if (err) {
console.log(err);
return next(err);
}
// @ts-ignore
console.log(`Uploaded ${req.files[file].filename} to database`);
if (expireDate == null)
console.log("It will not expire");
else if (expireDate != null || expireDate != undefined || expireDate != "")
else if (expireDate != null || expireDate != undefined)
console.log(`It will expire on ${expireDate}`);
});
}
next();
}
module.exports = {
checkAuth: checkAuth,
convert: convert,
handleUpload: handleUpload
};
}

12
app/types.ts Normal file
View file

@ -0,0 +1,12 @@
export interface MediaRow {
id? : Number,
path: String,
expire: Number
}
export interface UserRow {
id? : Number,
username: String,
hashed_password: any,
salt: any
}