Add files via upload

This commit is contained in:
2021-08-18 00:12:37 -07:00
committed by GitHub
parent ecd6246099
commit 9d759573d2
55 changed files with 3098 additions and 0 deletions

309
server/app.js Normal file
View File

@ -0,0 +1,309 @@
/* eslint-disable consistent-return */
const express = require('express');
const fs = require('fs-extra');
const app = express();
const bodyParser = require('body-parser');
const Eris = require('eris');
const path = require('path');
const utils = require(`${__dirname}/../util`);
const routes = require(`${__dirname}/routes`);
const https = require('https');
const events = require(`${__dirname}/../bot/events`);
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('db.json');
const db = low(adapter);
const helmet = require('helmet');
/** Express Webserver Class */
class ShareXAPI {
/**
* Starting server and bot, handling routing, and middleware
* @param {object} c - configuration json file
*/
constructor(c) {
this.db = db;
/** Setting LowDB Defaults */
db.defaults({
files: [],
bans: [],
visitors: [],
trafficTotal: [],
passwordUploads: [],
})
.write();
/** Defintions */
this.utils = utils;
this.log = utils.log;
this.auth = utils.auth;
this.randomToken = utils.randomToken;
this.mimeType = utils.mimeType;
this.c = c;
this.monitorChannel = null;
this.checkMonth();
this.c.discordToken && this.c.discordToken !== undefined && this.c.discrdToken !== null
? this.runDiscordBot()
: this.log.verbose('No Discord Token provided...\nContinuing without Discord connection...');
this.app = app;
this.app.set('view engine', 'ejs');
this.app.set('views', path.join(__dirname, '/views'));
this.app.use(helmet());
this.app.use(bodyParser.text());
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({
extended: true,
}));
/* Don't allow access if not accessed with configured domain */
this.app.use((req, res, next) => {
if(this.c.domain === '*') {
next();
} else if(req.headers.host !== this.c.domain.toLowerCase() && !this.c.domain.includes('*')) {
res.statusCode = 401;
res.write('Error 401: Unauthorized Domain');
return res.end();
} else if(this.c.domain.includes('*')) {
let reqParts = req.headers.host.toLowerCase().split('.');
let domainParts = this.c.domain.toLowerCase().split('.')
if(reqParts[1] === domainParts[1] && reqParts[2] === domainParts[2]) {
next();
} else {
res.statusCode = 401;
res.write('Error 401: Unauthorized Domain');
return res.end();
}
} else {
next();
}
});
/** Checking to see if IP is banned */
this.app.use((req, res, next) => {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
const exists = this.db.get('bans').find({ ip: userIP }).value();
if (exists === undefined) { // if a ban was not found, then it will move on
next();
} else {
res.statusCode = 401;
res.render('unauthorized');
return res.end();
}
});
/** Set to place IPs in temporarily for ratelimiting uploads */
const ratelimited = new Set();
this.app.use((req, res, next) => {
if (req.method === 'POST') {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
if (ratelimited.has(userIP)) {
res.statusCode = 429;
res.write('Error 429: Ratelimited');
return res.end();
}
next(); // Move on if IP is not in ratelimited set
ratelimited.add(userIP);
// delete IP from ratelimit set after time specified in config.json
setTimeout(() => ratelimited.delete(userIP), c.ratelimit);
} else {
next(); // move on if request type is not POST
}
});
this.app.use((req, res, next) => {
if (req.method === 'GET') {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
let file = req.path;
// Not ignoring these files causes bloat in the db
const ignored = ['/favicon.ico', '/assets/css/styles.min.css', '/highlight.pack.js', '/highlightjs-line-numbers.min.js', '/paste.css', '/atom-one-dark.css'];
let exists = this.db.get('files').find({ path: file }).value();
// making sure ignored files aren't included
if (ignored.includes(file)) exists = true;
if (exists === undefined) {
next(); // Move on if it doesn't exist, then input data into db
this.db.get('files')
.push({ path: file, ip: 'Unknown', views: 0 })
// Set IP to unknown in case a file is visited, and not uploaded using /api/files
.write();
if (!ignored.includes(file)) {
this.db.get('visitors')
.push({ date: new Date(), ip: userIP, path: file })
.write(); // Sets correct information for files uploaded with /api/files
}
} else {
next(); // Move on if the file already exists
const trafficPeriod = this.trafficPeriod(); // Gets month and year for tracking
let viewCount;
let trafficCount;
const filesExist = this.db.get('files').find({ path: file }).value(); // traffic exists for this file
const trafficExists = this.db.get('trafficTotal').find({ month: trafficPeriod }).value(); // traffic exists for this month and year
const visitors = this.db.get('visitors').value();
// Resetting visitors in the DB every 100 requests so the DB doesn't get bloated
if (visitors.length > 100) {
this.db.set('visitors', [])
.write();
}
filesExist === undefined
? viewCount = 0
: viewCount = filesExist.views + 1;
trafficExists === undefined
? trafficCount = 0
: trafficCount = trafficExists.total + 1;
this.db.get('files')
.find({ path: file })
.assign({ views: viewCount })
.write(); // Setting viewcount for file
if (!ignored.includes(file)) {
this.db.get('visitors')
.push({ date: new Date(), ip: userIP, path: file })
.write(); // Adding vsitor information to DB
}
if (!ignored.includes(file)) {
this.db.get('trafficTotal')
.find({ month: trafficPeriod })
.assign({ total: trafficCount })
.write(); // if request isn't to an ignored file, take request into total traffic
}
}
} else {
next();
}
});
// All files in /uploads/ are publicly accessible via http
this.app.use(express.static(`${__dirname}/uploads/`, {
extensions: this.c.admin.allowed.includes("*") ? null : this.c.admin.allowed,
}));
this.app.use(express.static(`${__dirname}/views/`, {
extensions: ['css'],
}));
// routing
this.app.get('/', routes.upload.bind(this));
this.app.get('/gallery', routes.gallery.get.bind(this));
this.app.get('/short', routes.short.get.bind(this));
this.app.get('/upload', routes.upload.bind(this));
this.app.get('/ERR_FILE_TOO_BIG', routes.fileTooBig.bind(this));
this.app.get('/ERR_ILLEGAL_FILE_TYPE', routes.illegalFileType.bind(this));
this.app.get('*', routes.err404.bind(this));
this.app.post('/api/shortener', routes.shortener.bind(this));
this.app.post('/short', routes.short.post.bind(this));
this.app.post('/gallery', routes.gallery.post.bind(this));
this.app.post('/pupload', routes.pupload.bind(this));
this.app.post('/api/paste', routes.paste.bind(this));
this.app.post('/api/files', routes.files.bind(this));
// Begin server
this.startServer();
}
/** Booting up the Discord Bot
* @returns {void}
*/
async runDiscordBot() {
this.bot = new Eris(this.c.discordToken, {
maxShards: 'auto',
});
this.log.verbose('Connecting to Discord...');
this.commands = [];
this.loadCommands();
this.bot
.on('messageCreate', events.messageCreate.bind(this))
.on('ready', events.ready.bind(this));
this.bot.connect();
}
/** Loads the commands for the discord bot to use in /bot/commands
* into an array defined before the calling of this function
* @returns {void}
*/
async loadCommands() {
fs.readdir(`${__dirname}/../bot/commands`, (err, files) => {
/** Commands are pushed to an array */
files.forEach(file => {
if (file.toString().includes('.js')) {
// eslint-disable-next-line global-require
this.commands.push(require(`${__dirname}/../bot/commands/${file.toString()}`));
this.log.verbose(`Loaded Command: ${file.toString()}`);
}
});
});
}
/** Start's the Express server
* @returns {void}
*/
async startServer() {
if (this.c.secure) {
/** if the secure option is set to true in config,
* it will boot in https so long as it detects
* key.pem and cert.pem in the src directory
*/
if (fs.existsSync(`${__dirname}/../key.pem`) && fs.existsSync(`${__dirname}/../cert.pem`)) {
const privateKey = fs.readFileSync(`${__dirname}/../key.pem`);
const certificate = fs.readFileSync(`${__dirname}/../cert.pem`);
https.createServer({
key: privateKey,
cert: certificate,
}, this.app).listen(this.c.securePort, '0.0.0.0');
} else {
// CF Flexible SSL
/** if no key & cert pem files are detected,
* it will still run in secure mode (returning urls with https)
* so that it's compatible with CF flexible SSL
* and SSL configurations via a reverse proxy */
this.app.listen(this.c.securePort, '0.0.0.0', () => {
this.log.warning('Server using flexible SSL secure setting\nTo run a full SSL setting, ensure key.pem and cert.pem are in the /src folder');
});
}
this.log.success(`Secure server listening on port ${this.c.securePort}`);
} else {
this.app.listen(this.c.port, '0.0.0.0', () => {
this.log.success(`Server listening on port ${this.c.port}`);
});
}
}
/** Checks to see if any DB entry is available for this month and year
* Then inserts a new object into the array if no data is available for
* that month/year
* @returns {void}
*/
async checkMonth() {
const trafficPeriod = this.trafficPeriod();
const dbMonth = this.db.get('trafficTotal').find({ month: trafficPeriod }).value();
if (dbMonth === undefined) {
this.db.get('trafficTotal')
.push({ month: trafficPeriod, total: 0 })
.write();
}
}
/** Gets the current month, and the current year
* then combines the two into a string
* this string is inserted into the database to be used
* for collecting traffic data on a per month basis
* @returns {string} 4/2019
*/
// eslint-disable-next-line class-methods-use-this
trafficPeriod() {
const date = new Date();
const currentMonth = date.getMonth() + 1;
const currentYear = date.getFullYear();
return `${currentMonth}/${currentYear}`;
}
/** Checks to see if server administrator wants to return http or https
* Using this function instead of req.secure because of
* Certain possible SSL configurations (CF Flexible SSL)
* @returns {string} http OR https
*/
protocol() {
if (this.c.secure) {
return 'https';
}
return 'http';
}
}
module.exports = ShareXAPI;

7
server/routes/err404.js Normal file
View File

@ -0,0 +1,7 @@
async function err404(req, res) {
res.setHeader('Content-Type', 'text/html');
res.statusCode = 404;
res.render('404');
res.end();
}
module.exports = err404;

View File

@ -0,0 +1,7 @@
async function fileTooBig(req, res) {
res.setHeader('Content-Type', 'text/html');
res.statusCode = 413;
res.render('ERR_FILE_TOO_BIG');
res.end();
}
module.exports = fileTooBig;

267
server/routes/files.js Normal file
View File

@ -0,0 +1,267 @@
/* eslint-disable no-lonely-if */
const formidable = require('formidable');
const fs = require('fs-extra');
const { Remarkable } = require('remarkable');
const ejs = require('ejs');
const exif = require('exif2');
const md = new Remarkable('full', {
html: false,
linkify: true,
typographer: true,
});
async function files(req, res) {
res.setHeader('Content-Type', 'text/text');
const fileName = this.randomToken(this.c.fileNameLength, false);
const form = new formidable.IncomingForm();
const protocol = this.protocol();
// eslint-disable-next-line no-shadow
form.parse(req, (err, fields, files) => {
let userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress.split(",")[0]; userIP = userIP.split(",")[0];
const authKey = fields.key;
let usingUploader = false;
if (files.fdataUploader && !fields.key) {
usingUploader = true;
// eslint-disable-next-line no-param-reassign
files.fdata = files.fdataUploader;
}
if (files.file) {
files.fdata = files.file;
}
if (!this.auth(this.c.key, fields.key, this.c) && usingUploader === false) {
res.statusCode = 401;
res.write('Unauthorized');
res.end();
return this.log.warning(`Unauthorized User | File Upload | ${userIP} | ${authKey}`);
} if (!this.auth(this.c.key, fields.password, this.c) && usingUploader === true) {
this.log.warning(this.auth(this.c.key, fields.password, this.c));
res.statusCode = 401;
res.redirect('/?error=Incorrect_Password');
res.end();
return this.log.warning(`Unauthorized User | File Upload | ${userIP} | ${authKey}`);
}
const oldpath = files.fdata.path;
const fileExt = files.fdata.name.substring(files.fdata.name.lastIndexOf('.') + 1, files.fdata.name.length).toLowerCase();
let newpath;
if(this.c.dateURLPath === true) {
let currentMonth = getDate('month')
let currentYear = getDate('year')
let currentDay = getDate('day')
let baseDir = `${__dirname}/../uploads/`
let basePWDir = `${__dirname}/../passwordUploads/`
fs.access(`${baseDir}${currentYear}/${currentMonth}/${currentDay}`, err => {
if (err && err.code === 'ENOENT') {
fs.mkdirSync(`${baseDir}${currentYear}`);
fs.mkdirSync(`${baseDir}${currentYear}/${currentMonth}`);
fs.mkdirSync(`${baseDir}${currentYear}/${currentMonth}/${currentDay}`)
}
});
fs.access(`${basePWDir}${currentYear}/${currentMonth}/${currentDay}`, err => {
if (err && err.code === 'ENOENT') {
fs.mkdirSync(`${basePWDir}${currentYear}`);
fs.mkdirSync(`${basePWDir}${currentYear}/${currentMonth}`);
fs.mkdirSync(`${basePWDir}${currentYear}/${currentMonth}/${currentDay}`)
}
});
}
fields.pupload
? newpath = `${__dirname}/../passwordUploads/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${fileName}.${fileExt}`
: newpath = `${__dirname}/../uploads/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${fileName}.${fileExt}`;
let returnedFileName;
if (!fileExt.includes('png') && !fileExt.includes('jpg') && !fileExt.includes('jpeg') && !fileExt.includes('md') && !fields.pupload) {
returnedFileName = `${fileName}.${fileExt}`;
} else {
returnedFileName = fileName;
}
if(fields.showCase) {
fields.showCase = true
}
let showCaseFile;
if(fields.showCase !== false) {
showCaseFile = this.randomToken(this.c.fileNameLength, false);
}
this.db.get('files')
.push({
path: fields.showCase ? `/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${showCaseFile}` : `/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName}`,
ip: userIP,
views: 0,
original: newpath,
showCase: fields.showCase ? true : false
})
.write();
let settings;
let isAdmin = false;
if (!this.c.admin.key.includes(fields.key)) {
settings = this.c;
} else {
settings = this.c.admin;
isAdmin = true;
}
if (Math.round((files.fdata.size / 1024) / 1000) > settings.maxUploadSize && !isAdmin) {
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[FAILED UPLOAD][USER]\n[FILE](${files.fdata.name})\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[TYPE](${files.fdata.type})\n[KEY](${authKey})\n[IP](${userIP})\n\n[ERROR](ERR_FILE_TOO_BIG)\`\`\``);
res.statusCode = 413;
if (usingUploader === true) {
res.redirect('/?error=File_Too_Big');
return res.end();
}
res.write(`${protocol}://${req.headers.host}/ERR_FILE_TOO_BIG`);
return res.end();
}
if (!settings.allowed.some(ext => fileExt.endsWith(ext)) && !settings.allowed.includes("*")) {
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[FAILED UPLOAD][USER]\n[FILE](${files.fdata.name})\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[TYPE](${files.fdata.type})\n[KEY](${authKey})\n[IP](${userIP})\n\n[ERROR](ERR_ILLEGAL_FILE_TYPE)\`\`\``);
res.statusCode = 415;
if (usingUploader === true) {
res.redirect('/?error=Illegal_File_Type');
return res.end();
}
res.write(`${protocol}://${req.headers.host}/ERR_ILLEGAL_FILE_TYPE`);
return res.end();
}
if (fields.pupload) {
let altKey = this.randomToken(this.c.puploadKeyGenLength, true);
fs.move(oldpath, newpath, () => {
let puploadKey
if(fields.pupload === '*random*') {
puploadKey = altKey;
} else {
puploadKey = fields.pupload;
}
this.db.get('passwordUploads')
.push({
fileName: `${fileName}.${fileExt}`,
key: puploadKey,
})
.write();
fs.readFile(newpath, 'utf-8', () => {
const stream = fs.createWriteStream(`${__dirname}/../uploads/${fileName}.html`);
stream.once('open', () => {
ejs.renderFile(`${__dirname}/../views/puploadAuth.ejs`, {
fileName: `${fileName}.${fileExt}`,
}, {}, (_err, str) => {
stream.write(str);
});
stream.end();
});
});
});
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[NEW UPLOAD][USER]\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[TYPE](${files.fdata.type})\n[KEY](${authKey})\n[IP](${userIP})\n\`\`\`\n${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName}`);
if (err) return res.write(err);
this.log.verbose(`New File Upload: ${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName} | IP: ${userIP} | KEY: ${authKey}`);
if (usingUploader === true) {
res.redirect(`/?success=${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName}`);
return res.end();
}
fields.pupload === '*random*' ? res.write(`URL: ${protocol}://${req.headers.host}/${returnedFileName} | KEY: ${altKey}`) : res.write(`${protocol}://${req.headers.host}/${returnedFileName}`);
return res.end();
}
if (fields.showCase === true) {
if(fileExt === "png" || fileExt === "jpg" || fileExt === "gif" || fileExt === "jpeg") {
returnedFileName = `${showCaseFile}.html`
fs.move(oldpath, newpath, () => {
fs.readFile(newpath, 'utf-8', (err, data) => {
exif(newpath, (err, obj) => {
if(!obj['camera model name']) obj['camera model name'] = "N/A";
if(!obj['f number']) obj['f number'] = "N/A";
if(!obj['exposure time']) obj['exposure time'] = "N/A";
if(!obj['iso']) obj['iso'] = "N/A";
if(!obj['focal length']) obj['focal length'] = "N/A";
if(!obj['image size']) obj['image size'] = "N/A";
if(!obj['lens id']) obj['lens id'] = "N/A";
let camera = obj['camera model name'].replace(/<|>|&lt;|&gt;/gm, "")
let fstop = `f/${obj['f number']}`.replace(/<|>|&lt;|&gt;/gm, "")
let shutter = obj['exposure time'].replace(/<|>|&lt;|&gt;/gm, "")
let iso = obj['iso'].replace(/<|>|&lt;|&gt;/gm, "")
let focal = obj['focal length'].replace(/<|>|&lt;|&gt;/gm, "")
let dims = obj['image size'].replace(/<|>|&lt;|&gt;/gm, "")
let lens = obj['lens id'].replace(/<|>|&lt;|&gt;/gm, "")
let width = parseInt(dims.split('x')[0]);
let height = parseInt(dims.split('x')[1]);
if(height > 700) {
let magicNumber = height / 700;
height = height / magicNumber;
width = width / magicNumber
}
let sizing = [width, height]
const stream = fs.createWriteStream(`${__dirname}/../uploads/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${showCaseFile}.html`);
stream.once('open', () => {
ejs.renderFile(`${__dirname}/../views/photoShowCase.ejs`, {
camera: camera,
fstop, fstop,
shutter, shutter,
iso: iso,
focal: focal,
dims: dims,
lens: lens,
width: sizing[0],
height: sizing[1],
filename: `${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${fileName}.${fileExt}`
}, {}, (_err, str) => {
stream.write(str);
});
stream.end();
});
});
});
});
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[NEW UPLOAD][USER]\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[TYPE](${files.fdata.type})\n[KEY](${authKey})\n[IP](${userIP})\n\`\`\`\n${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${showCaseFile}`);
if (err) return res.write(err);
this.log.verbose(`New File Upload: ${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${showCaseFile} | IP: ${userIP} | KEY ${authKey}`);
if (usingUploader === true) {
res.redirect(`/?success=${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${showCaseFile}`);
return res.end();
}
res.write(`${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${showCaseFile}`);
return res.end();
}
}
fs.move(oldpath, newpath, () => {
if (fileExt.toLowerCase() === 'md' && this.c.markdown) {
fs.readFile(newpath, 'utf-8', (_readErr, data) => {
const stream = fs.createWriteStream(`${__dirname}/../uploads/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${fileName}.html`);
stream.once('open', () => {
ejs.renderFile(`${__dirname}/../views/md.ejs`, {
ogDesc: data.match(/.{1,297}/g)[0],
mdRender: md.render(data),
}, {}, (_renderErr, str) => {
stream.write(str);
});
stream.end();
fs.unlink(newpath, delErr => {
if (delErr) return this.log.warning(delErr);
});
});
});
}
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[NEW UPLOAD][USER]\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[TYPE](${files.fdata.type})\n[IP](${userIP})\n[KEY](${authKey})\n\`\`\`\n${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName}`);
if (err) return res.write(err);
this.log.verbose(`New File Upload: ${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName} | IP: ${userIP} | KEY: ${authKey}`);
if (usingUploader === true) {
res.redirect(`/?success=${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName}`);
return res.end();
}
res.write(`${protocol}://${req.headers.host}/${this.c.dateURLPath === true ? `${getDate('year')}/${getDate('month')}/${getDate('day')}/`: ""}${returnedFileName}`);
return res.end();
});
});
}
//const currentMonth = date.getMonth() + 1;
function getDate(type) {
if(type.toLowerCase() === 'year') {
const date = new Date();
const currentYear = date.getFullYear();
return currentYear;
}
if(type.toLowerCase() === 'month') {
const date = new Date();
let currentMonth = `${date.getMonth() + 1}`;
if(currentMonth.length === 1) currentMonth = `0${currentMonth}`
return currentMonth;
}
if(type.toLowerCase() === 'day') {
const date = new Date();
let currentDay = `${date.getDate()}`;
if(currentDay.length === 1) currentDay = `0${currentDay}`;
return currentDay;
}
}
module.exports = files;

51
server/routes/gallery.js Normal file
View File

@ -0,0 +1,51 @@
const fs = require('fs-extra');
async function get(_req, res) {
res.setHeader('Content-Type', 'text/html');
res.render('galleryLogin');
res.end();
}
async function post(req, res) {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
res.setHeader('Content-Type', 'text/html');
const protocol = this.protocol();
var password = this.c.admin.key;
// Compatibility with old config
if(typeof password == "string"){
password = [password];
}
if (!this.c.admin.key.includes(req.body.password)) {
res.statusCode = 401;
res.render('unauthorized');
res.end();
return this.log.warning(`Unauthorized User | Gallery Access | ${userIP} | ${req.body.password}`);
}
this.log.warning(`IP Address: ${userIP} successfully accessed gallery with key ${req.body.password}`);
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[GALLERY ACCESS][USER]\n[IP](${userIP})\n[KEY](${req.body.password})\n\`\`\``);
fs.readdir(`${__dirname}/../uploads`, (err, files) => {
let pics = [];
files = files.map(fileName => {
return {
name: fileName,
time: fs.statSync(`${__dirname}/../uploads/${fileName}`).mtime.getTime()
};
})
files.sort((a, b) => {
return b.time - a.time; });
files = files.map(v => {
return v.name; });
files.forEach((file, idx, array) => {
if (file.toString().includes('.jpg') || file.toString().includes('.png') || file.toString().includes('.gif')) {
pics.push(`${protocol}://${req.headers.host}/${file.toString()}`);
}
if (idx === array.length - 1) {
res.render('gallery', {
pictures: pics,
});
return res.end();
}
})
});
}
module.exports = { get, post };

View File

@ -0,0 +1,7 @@
async function illegalFileType(req, res) {
res.setHeader('Content-Type', 'text/html');
res.statusCode = 413;
res.render('ERR_FILE_TOO_BIG');
res.end();
}
module.exports = illegalFileType;

7
server/routes/index.js Normal file
View File

@ -0,0 +1,7 @@
require('fs')
.readdirSync(__dirname)
.map(filename => {
const moduleName = filename.split('.')[0];
// eslint-disable-next-line global-require
exports[moduleName] = require(`${__dirname}/${filename}`);
});

59
server/routes/paste.js Normal file
View File

@ -0,0 +1,59 @@
/* eslint-disable consistent-return */
const formidable = require('formidable');
const fs = require('fs-extra');
const ejs = require('ejs');
async function paste(req, res) {
res.setHeader('Content-Type', 'text/text');
const fileName = this.randomToken(5); // 916,132,832 possible file names
const form = new formidable.IncomingForm();
const protocol = this.protocol();
form.parse(req, (err, fields, files) => {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
if (!this.auth(this.c.key, fields.key, this.c)) {
res.statusCode = 401;
res.write('Unauthorized');
res.end();
return this.log.warning(`Unauthorized User | File Upload | ${userIP}`);
}
this.db.get('files')
.push({
path: `/${fileName}`,
ip: userIP,
views: 0,
})
.write();
const oldpath = files.fdata.path;
const newpath = `${__dirname}/../uploads/${fileName + files.fdata.name.toString().match(/(\.)+([a-zA-Z0-9]+)+/g, '').toString()}`;
if (Math.round((files.fdata.size / 1024) / 1000) > this.c.paste.max_upload_size) {
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[FAILED PASTE][USER]\n[FILE](${files.fdata.name})\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[TYPE](${files.fdata.type})\n[IP](${userIP})\n\n[ERROR](ERR_FILE_TOO_BIG)\`\`\``);
res.statusCode = 413;
res.write(`${protocol}://${req.headers.host}/ERR_FILE_TOO_BIG`);
return res.end();
}
fs.move(oldpath, newpath, () => {
fs.readFile(newpath, 'utf-8', (_err, data) => {
const stream = fs.createWriteStream(`${__dirname}/../uploads/${fileName}.html`);
stream.once('open', () => {
// eslint-disable-next-line no-unused-vars
let cleaned = data.replace(/>/g, '&gt');
cleaned = cleaned.replace(/</g, '&lt');
ejs.renderFile(`${__dirname}/../views/paste.ejs`, {
ogDesc: data.match(/.{1,297}/g)[0],
pData: data,
}, {}, (_renderErr, str) => {
stream.write(str);
});
stream.end();
fs.unlink(newpath, delErr => {
if (delErr) return this.log.warning(delErr);
});
res.write(`${protocol}://${req.headers.host}/${fileName}`);
return res.end();
});
});
});
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[NEW PASTE][USER]\n[SIZE](${Math.round(files.fdata.size / 1024)}KB)\n[IP](${userIP})\n\`\`\`\n${protocol}://${req.headers.host}/${fileName}`);
});
}
module.exports = paste;

24
server/routes/pupload.js Normal file
View File

@ -0,0 +1,24 @@
const fs = require('fs-extra');
async function pupload(req, res) {
res.setHeader('Content-Type', 'text/html');
const givenPassword = req.body.password;
const givenFileName = req.body.file;
const entry = this.db.get('passwordUploads').find({ fileName: givenFileName }).value();
if (entry.key !== givenPassword) {
res.statusCode = 401;
res.render('unauthorized');
return res.end();
}
const filePath = `${__dirname}/../passwordUploads/${entry.fileName}`;
const file = fs.readFileSync(filePath);
if(entry.fileName.includes('.mp3')) {
res.set('Content-Type', 'text/html');
let base64Str = new Buffer(file).toString('base64');
res.render('mp3', { data: base64Str })
} else {
res.set('Content-Type', this.mimeType(entry.fileName));
res.send(file);
}
}
module.exports = pupload;

36
server/routes/short.js Normal file
View File

@ -0,0 +1,36 @@
const fs = require('fs-extra');
async function get(req, res) {
res.setHeader('Content-Type', 'text/html');
res.render('short', { public: this.c.public });
res.end();
}
async function post(req, res) {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
res.setHeader('Content-Type', 'text/text');
if (!this.auth(this.c.key, req.body.password, this.c) && !this.c.public) {
res.statusCode = 401;
res.redirect('/short?error=Incorrect_Password');
res.end();
return this.log.warning(`Unauthorized User | URL Shorten | ${userIP}`);
}
const protocol = this.protocol();
const fileName = this.randomToken(this.c.shortUrlLength);
if (req.body.URL === '' || req.body.URL === null) {
res.redirect('/short?error=No URL Input');
return res.end();
}
const stream = fs.createWriteStream(`${__dirname}/../uploads/${fileName}.html`);
stream.once('open', () => {
stream.write(`<meta http-equiv="refresh" content="0;URL='${req.body.URL}'" />`);
stream.end();
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[NEW][SHORT URL]\n[URL](${req.body.URL})\n[NEW](${req.headers.host}/${fileName})\n[IP](${userIP})\n\`\`\``);
this.log.verbose(`New Short URL: ${protocol}://${req.headers.host}/${fileName} | IP: ${userIP}`);
res.redirect(`/short?success=${protocol}://${req.headers.host}/${fileName}`);
this.db.get('files')
.push({ path: `/${fileName}`, ip: userIP, views: 0 })
.write();
return res.end();
});
}
module.exports = { get, post };

View File

@ -0,0 +1,41 @@
/* eslint-disable no-useless-escape */
const formidable = require('formidable');
const fs = require('fs-extra');
async function shortener(req, res) {
const form = new formidable.IncomingForm();
// eslint-disable-next-line no-unused-vars
form.parse(req, (_err, fields, _files) => {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
const protocol = this.protocol();
if (!this.auth(this.c.key, fields.key, this.c)) {
res.statusCode = 401;
res.write('Unauthorized');
res.end();
return this.log.warning(`Unauthorized User | File Upload | ${userIP}`);
}
const fileName = this.randomToken(4); // 14,776,336 possible file names
const url = req.headers.url;
if (url == null) {
res.send('NO_URL_PROVIDED');
return res.end();
}
if (!/([-a-zA-Z0-9^\p{L}\p{C}\u00a1-\uffff@:%_\+.~#?&//=]{2,256}){1}(\.[a-z]{2,4}){1}(\:[0-9]*)?(\/[-a-zA-Z0-9\u00a1-\uffff\(\)@:%,_\+.~#?&//=]*)?([-a-zA-Z0-9\(\)@:%,_\+.~#?&//=]*)?/.test(url.toLowerCase().toString())) {
res.send('NOT_A_VALID_URL');
return res.end();
}
const stream = fs.createWriteStream(`${__dirname}/../uploads/${fileName}.html`);
stream.once('open', () => {
stream.write(`<meta http-equiv="refresh" content="0; url=${url}" />`);
stream.end();
if (this.monitorChannel !== null) this.bot.createMessage(this.monitorChannel, `\`\`\`MARKDOWN\n[NEW][SHORT URL]\n[URL](${url})\n[NEW](${req.headers.host}/${fileName})\n[IP](${userIP})\n\`\`\``);
this.log.verbose(`New Short URL: ${protocol}://${req.headers.host}/${fileName} | IP: ${userIP}`);
res.write(`${protocol}://${req.headers.host}/${fileName}`);
this.db.get('files')
.push({ path: `/${fileName}`, ip: userIP, views: 0 })
.write();
return res.end();
});
});
}
module.exports = shortener;

6
server/routes/upload.js Normal file
View File

@ -0,0 +1,6 @@
async function upload(_req, res) {
res.setHeader('Content-Type', 'text/html');
res.statusCode = 200;
res.render('upload', { public: this.c.public });
}
module.exports = upload;

BIN
server/uploads/RBTu.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1 @@
button{border-radius:0}button:focus{outline:dotted 1px;outline:-webkit-focus-ring-color auto 5px}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.125rem}.alert-success{color:#496330;background-color:#e8f2df;border-color:#dfedd2}.close{float:right;font-size:1.3125rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.mr-1,.mx-1{margin-right:.3125rem!important}.icon{width:20px;height:20px;vertical-align:middle;display:inline-block;background-size:auto}.fbox3>div[class*=col]{padding-top:5px;padding-bottom:5px}.features-clean{color:#313437;background-color:#fff;padding-bottom:30px}.features-clean p{color:#7d8285}.features-clean h2{font-weight:700;margin-bottom:40px;padding-top:40px;color:inherit}@media (max-width:767px){.features-clean{padding-bottom:10px}.features-clean h2{margin-bottom:25px;padding-top:25px;font-size:24px}}.features-clean .intro{font-size:16px;max-width:500px;margin:0 auto 60px}.features-clean .item{min-height:100px;padding-left:80px;margin-bottom:40px}@media (max-width:767px){.features-clean .intro{margin-bottom:40px}.features-clean .item{min-height:0}}.features-clean .item .name{font-size:20px;font-weight:700;margin-top:0;margin-bottom:20px;color:inherit}.features-clean .item .description{font-size:15px;margin-bottom:0}.features-clean .item .icon{font-size:40px;color:#1485ee;float:left;margin-left:-65px}.form-control.d-xl-flex.justify-content-center.align-items-center.align-content-center.align-self-end.justify-content-lg-center.justify-content-xl-center{text-align:center}.login-clean{background:#f1f7fc;padding:80px 0}.login-clean form{max-width:320px;width:90%;margin:0 auto;background-color:#fff;padding:40px;border-radius:4px;color:#505e6c;box-shadow:1px 1px 5px rgba(0,0,0,.1)}.login-clean .illustration{text-align:center;padding:0 0 20px;font-size:100px;color:#f4476b}.login-clean form .form-control{background:#f7f9fc;border:none;border-bottom:1px solid #dfe7f1;border-radius:0;box-shadow:none;outline:0;color:inherit;text-indent:8px;height:42px}.login-clean form .btn-primary{background:#f4476b;border:none;border-radius:4px;padding:11px;box-shadow:none;margin-top:26px;text-shadow:none;outline:0!important}.login-clean form .btn-primary:active,.login-clean form .btn-primary:hover{background:#eb3b60}.login-clean form .btn-primary:active{transform:translateY(1px)}.login-clean form .forgot{display:block;text-align:center;font-size:12px;color:#6f7a85;opacity:.9;text-decoration:none}.login-clean form .forgot:active,.login-clean form .forgot:hover{opacity:1;text-decoration:none}.navigation-clean{background:#fff;padding-top:.75rem;padding-bottom:.75rem;color:#333;border-radius:0;box-shadow:none;border:none;margin-bottom:0}@media (min-width:768px){.navigation-clean{padding-top:1rem;padding-bottom:1rem}}.navigation-clean .navbar-brand{font-weight:700;color:inherit}.navigation-clean .navbar-brand:hover{color:#222}.navigation-clean .navbar-toggler{border-color:#ddd;color:#888}.navigation-clean .navbar-toggler:focus,.navigation-clean .navbar-toggler:hover{background:0 0}.navigation-clean .form-inline,.navigation-clean .navbar-collapse{border-top-color:#ddd}.navigation-clean.navbar-light .navbar-nav .nav-link.active,.navigation-clean.navbar-light .navbar-nav .nav-link.active:focus,.navigation-clean.navbar-light .navbar-nav .nav-link.active:hover{color:#8f8f8f;box-shadow:none;background:0 0;pointer-events:none}.navigation-clean.navbar .navbar-nav .nav-link{padding-left:18px;padding-right:18px}.navigation-clean.navbar-light .navbar-nav .nav-link{color:#465765}.navigation-clean.navbar-light .navbar-nav .nav-link:focus,.navigation-clean.navbar-light .navbar-nav .nav-link:hover{color:#37434d!important;background-color:transparent}.navigation-clean .navbar-nav>li>.dropdown-menu{margin-top:-5px;box-shadow:none;background-color:#fff;border-radius:2px}.navigation-clean .dropdown-menu .dropdown-item,.navigation-clean .dropdown-menu .dropdown-item:focus{line-height:2;color:#37434d}.navigation-clean .dropdown-menu .dropdown-item:focus,.navigation-clean .dropdown-menu .dropdown-item:hover{background:#eee;color:inherit}.social-icons{color:#313437;background-color:#fff;text-align:center;padding:70px 0}@media (max-width:767px){.social-icons{padding:50px 0}}.social-icons i{font-size:32px;display:inline-block;color:#757980;margin:0 10px;width:60px;height:60px;border:1px solid #c8ced7;text-align:center;border-radius:50%;line-height:60px}

View File

@ -0,0 +1,110 @@
/*
Atom One Dark by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
base: #282c34
mono-1: #abb2bf
mono-2: #818896
mono-3: #5c6370
hue-1: #56b6c2
hue-2: #61aeee
hue-3: #c678dd
hue-4: #98c379
hue-5: #e06c75
hue-5-2: #be5046
hue-6: #d19a66
hue-6-2: #e6c07b
*/
.hljs {
display: block;
padding: 0.5em;
color: #abb2bf;
background: #282c34;
width: 100%;
height: 100%;
word-wrap: break-word;
}
td.hljs-ln-code {
white-space: pre-wrap;
}
body {
padding: 20px;
}
.hljs-comment,
.hljs-quote {
color: #5c6370;
font-style: italic;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #c678dd;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
color: #98c379;
}
.hljs-built_in,
.hljs-class .hljs-title {
color: #e6c07b;
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #d19a66;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}
body {
background-color: #282C34;
}

179
server/uploads/css/404.css Normal file
View File

@ -0,0 +1,179 @@
@import url(https://fonts.googleapis.com/css?family=Lato:100,300,400);
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::-webkit-input-placeholder, textarea:focus::-webkit-input-placeholder {
color: #bbb5af;
}
input::-moz-placeholder, textarea::-moz-placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::-moz-placeholder, textarea:focus::-moz-placeholder {
color: #bbb5af;
}
input::placeholder, textarea::placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::placeholder, textarea::focus:placeholder {
color: #bbb5af;
}
input::-ms-placeholder, textarea::-ms-placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::-ms-placeholder, textarea:focus::-ms-placeholder {
color: #bbb5af;
}
/* on hover placeholder */
input:hover::-webkit-input-placeholder, textarea:hover::-webkit-input-placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::-webkit-input-placeholder, textarea:hover:focus::-webkit-input-placeholder {
color: #cbc6c1;
}
input:hover::-moz-placeholder, textarea:hover::-moz-placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::-moz-placeholder, textarea:hover:focus::-moz-placeholder {
color: #cbc6c1;
}
input:hover::placeholder, textarea:hover::placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::placeholder, textarea:hover:focus::placeholder {
color: #cbc6c1;
}
input:hover::placeholder, textarea:hover::placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::-ms-placeholder, textarea:hover::focus:-ms-placeholder {
color: #cbc6c1;
}
body {
font-family: 'Lato', sans-serif;
background: #e2dedb;
color: #b3aca7;
}
header {
position: relative;
margin: 100px 0 25px 0;
font-size: 2.3em;
text-align: center;
letter-spacing: 7px;
}
return {
position: relative;
margin: 100px 0 25px 0;
font-size: 1.0em;
text-align: center;
letter-spacing: 3px;
}
#form {
position: relative;
width: 500px;
margin: 50px auto 100px auto;
}
input {
font-family: 'Lato', sans-serif;
font-size: 0.875em;
width: 470px;
height: 50px;
padding: 0px 15px 0px 15px;
background: transparent;
outline: none;
color: #726659;
border: solid 1px #b3aca7;
border-bottom: none;
transition: all 0.3s ease-in-out;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
}
input:hover {
background: #b3aca7;
color: #e2dedb;
}
textarea {
width: 470px;
max-width: 470px;
height: 110px;
max-height: 110px;
padding: 15px;
background: transparent;
outline: none;
color: #726659;
font-family: 'Lato', sans-serif;
font-size: 0.875em;
border: solid 1px #b3aca7;
transition: all 0.3s ease-in-out;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
}
textarea:hover {
background: #b3aca7;
color: #e2dedb;
}
#submit {
width: 470px;
padding: 0;
margin: -5px 0px 0px 0px;
font-family: 'Lato', sans-serif;
font-size: 0.875em;
color: #b3aca7;
outline:none;
cursor: pointer;
border: solid 1px #b3aca7;
}
#submit:hover {
color: #e2dedb;
}
a {
color: #726659;
}

BIN
server/uploads/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
!function(n,e){"use strict";function t(){var n=e.createElement("style");n.type="text/css",n.innerHTML=h(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[f,m,j]),e.getElementsByTagName("head")[0].appendChild(n)}function r(t){"complete"===e.readyState?l(t):n.addEventListener("DOMContentLoaded",function(){l(t)})}function l(t){try{var r=e.querySelectorAll("code.hljs");for(var l in r)r.hasOwnProperty(l)&&i(r[l],t)}catch(o){n.console.error("LineNumbers error: ",o)}}function i(n,e){if("object"==typeof n){e=e||{singleLine:!1};var t=e.singleLine?0:1;u(function(){s(n),n.innerHTML=o(n.innerHTML,t)})}}function o(n,e){var t=c(n);if(""===t[t.length-1].trim()&&t.pop(),t.length>e){for(var r="",l=0,i=t.length;l<i;l++)r+=h('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',[v,g,m,j,p,l+1,t[l].length>0?t[l]:" "]);return h('<table class="{0}">{1}</table>',[f,r])}return n}function s(n){var e=n.childNodes;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];d(r.textContent)>0&&(r.childNodes.length>0?s(r):a(r.parentNode))}}function a(n){var e=n.className;if(/hljs-/.test(e)){for(var t=c(n.innerHTML),r=0,l="";r<t.length;r++)l+=h('<span class="{0}">{1}</span>\n',[e,t[r]]);n.innerHTML=l.trim()}}function c(n){return 0===n.length?[]:n.split(L)}function d(n){return(n.trim().match(L)||[]).length}function u(e){n.setTimeout(e,0)}function h(n,e){return n.replace(/\{(\d+)\}/g,function(n,t){return e[t]?e[t]:n})}var f="hljs-ln",g="hljs-ln-line",p="hljs-ln-code",v="hljs-ln-numbers",m="hljs-ln-n",j="data-line-number",L=/\r\n|\r|\n/g;n.hljs?(n.hljs.initLineNumbersOnLoad=r,n.hljs.lineNumbersBlock=i,t()):n.console.error("highlight.js not detected!")}(window,document);

20
server/uploads/paste.css Normal file
View File

@ -0,0 +1,20 @@
::selection {
background: rgba(0, 0, 0, 0.46); /* WebKit/Blink Browsers */
}
::-moz-selection {
background: rgba(0, 0, 0, 0.46); /* Gecko Browsers */
}
td.hljs-ln-numbers {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
text-align: center;
color: #414754;
vertical-align: top;
padding-right: 12px !important;
}

239
server/uploads/sample.html Normal file
View File

@ -0,0 +1,239 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="atom-one-dark.css">
<link rel="stylesheet" href="paste.css">
<script src="highlight.pack.js"></script>
</head>
<body>
<pre><code id="code">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Script
{
public class ScriptVariable
{
public object Value { get; set; }
public ScriptTypes Type { get; set; }
public string Name { get; set; }
public ScriptVariable()
{
Value = null;
Type = ScriptTypes.Undefined;
}
public ScriptVariable(object value)
{
Value = value;
Type = value is string ? ScriptTypes.String
: value is int ? ScriptTypes.Integer
: value is double ? ScriptTypes.Double
: value is bool ? ScriptTypes.Boolean
: value is Regex ? ScriptTypes.Regex
: value is List<string> ? ScriptTypes.ListString
: value is List<int> ? ScriptTypes.ListInteger
: value is List<double> ? ScriptTypes.ListDouble
: value is List<bool> ? ScriptTypes.ListBoolean
: ScriptTypes.Null;
}
public ScriptVariable(object value, ScriptTypes type)
{
Value = value;
Type = type;
}
public ScriptVariable(string name, object value)
{
Name = name;
Value = value;
Type = value is string ? ScriptTypes.String
: value is int ? ScriptTypes.Integer
: value is double ? ScriptTypes.Double
: value is bool ? ScriptTypes.Boolean
: value is Regex ? ScriptTypes.Regex
: value is List<string> ? ScriptTypes.ListString
: value is List<int> ? ScriptTypes.ListInteger
: value is List<double> ? ScriptTypes.ListDouble
: value is List<bool> ? ScriptTypes.ListBoolean
: ScriptTypes.Null;
}
public ScriptVariable(string name, object value, ScriptTypes type)
{
Name = name;
Value = value;
Type = type;
}
public T Return<T>()
{
var returnT = ScriptType.ToEnum(typeof(T));
switch (returnT)
{
case ScriptTypes.String:
case ScriptTypes.Integer:
case ScriptTypes.Double:
case ScriptTypes.Boolean:
case ScriptTypes.Regex:
return (T)this.Value;
case ScriptTypes.ListString:
return (T)(object)((List<ScriptVariable>)this.Value).Select(x => x.Value.ToString()).ToList();
case ScriptTypes.ListInteger:
return (T)(object)((List<ScriptVariable>)(this.Value)).Select(x => x).ToList();
case ScriptTypes.ListDouble:
return (T)(object)((List<ScriptVariable>)(this.Value)).Select(x => x).ToList();
case ScriptTypes.ListBoolean:
return (T)(object)((List<ScriptVariable>)(this.Value)).Select(x => x).ToList();
default:
return default(T);
}
}
public ScriptVariable Cast<ReturnT>(Lexer lexer)
{
var outputType = ScriptType.ToEnum(typeof(ReturnT));
switch (outputType)
{
case ScriptTypes.String:
switch (this.Type)
{
case ScriptTypes.Integer:
case ScriptTypes.Double:
this.Value = this.Value.ToString();
break;
case ScriptTypes.Boolean:
this.Value = (bool)this.Value ? "true" : "false";
break;
case ScriptTypes.Null:
this.Value = "null";
break;
}
this.Type = ScriptTypes.String;
break;
case ScriptTypes.Integer:
switch (this.Type)
{
case ScriptTypes.String:
int tryInt = 0;
if (int.TryParse(this.Value.ToString(), out tryInt))
{
this.Value = tryInt;
}
else
{
goto castError;
}
break;
case ScriptTypes.Double:
double tryDouble = 0;
if (double.TryParse(this.Value.ToString(), out tryDouble))
{
this.Value = tryDouble;
}
else
{
goto castError;
}
break;
case ScriptTypes.Boolean:
this.Value = (bool)this.Value ? 1 : 0;
break;
}
this.Type = ScriptTypes.Integer;
break;
case ScriptTypes.Double:
switch (this.Type)
{
case ScriptTypes.String:
case ScriptTypes.Integer:
double tryDouble = 0;
if (double.TryParse(this.Value.ToString(), out tryDouble))
{
this.Value = tryDouble;
}
else
{
goto castError;
}
break;
case ScriptTypes.Boolean:
this.Value = (bool)this.Value ? 1.0 : 0.0;
break;
}
this.Type = ScriptTypes.Double;
break;
case ScriptTypes.Boolean:
switch (this.Type)
{
case ScriptTypes.String:
this.Value = this.Value.ToString() == "true";
break;
}
this.Type = ScriptTypes.Boolean;
break;
case ScriptTypes.ListString:
case ScriptTypes.ListInteger:
case ScriptTypes.ListDouble:
case ScriptTypes.ListBoolean:
break;
case ScriptTypes.Void:
this.Value = default(ReturnT);
break;
}
return this;
castError:
lexer.Prev();
lexer.Prev();
throw new ScriptException(
message: String.Format("Unable to cast value '{0}' from '{1}' to '{2}' on Line {3} Col {4}",
Value.ToString(),
Type.ToString(),
outputType.ToString(),
lexer.LineNumber,
lexer.Position),
row: lexer.LineNumber,
column: lexer.Position,
method: lexer.TokenContents
);
}
/*public ScriptVariable Cast<ReturnT>(Lexer lexer)
{
var outputType = ScriptType.ToEnum(typeof(ReturnT));
var outValue = default(ReturnT);
if (TryCast<ReturnT>(Type, Value, out outValue))
{
return this;
}
lexer.Prev();
lexer.Prev();
throw new ScriptException(
message: String.Format("Unable to cast value '{0}' from '{1}' to '{2}' on Line {3} Col {4}",
Value.ToString(),
Type.ToString(),
outputType.ToString(),
lexer.LineNumber,
lexer.Position),
row: lexer.LineNumber,
column: lexer.Position,
method: lexer.TokenContents
);
}*/
}
}</code></pre>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>

BIN
server/uploads/sample.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

39
server/views/404.ejs Normal file
View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ERROR 404</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/gallery" style="color: rgb(230,94,94);">Gallery</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<h1 class="text-center shadow-none justify-content-center align-items-center align-content-center align-self-center" style="color: rgb(230,94,94);margin: 8px;width: 99%;height: 99%;padding-top: 140px;">404</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ERROR</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/gallery" style="color: rgb(230,94,94);">Gallery</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<h1 class="text-center shadow-none justify-content-center align-items-center align-content-center align-self-center" style="color: rgb(230,94,94);margin: 8px;width: 99%;height: 99%;padding-top: 140px;"><br>The file you uploaded exceeds the file size limit<br></h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ERROR</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/gallery" style="color: rgb(230,94,94);">Gallery</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<h1 class="text-center shadow-none justify-content-center align-items-center align-content-center align-self-center" style="color: rgb(230,94,94);margin: 8px;width: 99%;height: 99%;padding-top: 140px;"><br>The file type you attempted to upload is not allowed<br></h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -0,0 +1 @@
button{border-radius:0}button:focus{outline:dotted 1px;outline:-webkit-focus-ring-color auto 5px}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.125rem}.alert-success{color:#496330;background-color:#e8f2df;border-color:#dfedd2}.close{float:right;font-size:1.3125rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.mr-1,.mx-1{margin-right:.3125rem!important}.icon{width:20px;height:20px;vertical-align:middle;display:inline-block;background-size:auto}.fbox3>div[class*=col]{padding-top:5px;padding-bottom:5px}.features-clean{color:#313437;background-color:#fff;padding-bottom:30px}.features-clean p{color:#7d8285}.features-clean h2{font-weight:700;margin-bottom:40px;padding-top:40px;color:inherit}@media (max-width:767px){.features-clean{padding-bottom:10px}.features-clean h2{margin-bottom:25px;padding-top:25px;font-size:24px}}.features-clean .intro{font-size:16px;max-width:500px;margin:0 auto 60px}.features-clean .item{min-height:100px;padding-left:80px;margin-bottom:40px}@media (max-width:767px){.features-clean .intro{margin-bottom:40px}.features-clean .item{min-height:0}}.features-clean .item .name{font-size:20px;font-weight:700;margin-top:0;margin-bottom:20px;color:inherit}.features-clean .item .description{font-size:15px;margin-bottom:0}.features-clean .item .icon{font-size:40px;color:#1485ee;float:left;margin-left:-65px}.form-control.d-xl-flex.justify-content-center.align-items-center.align-content-center.align-self-end.justify-content-lg-center.justify-content-xl-center{text-align:center}.login-clean{background:#f1f7fc;padding:80px 0}.login-clean form{max-width:320px;width:90%;margin:0 auto;background-color:#fff;padding:40px;border-radius:4px;color:#505e6c;box-shadow:1px 1px 5px rgba(0,0,0,.1)}.login-clean .illustration{text-align:center;padding:0 0 20px;font-size:100px;color:#f4476b}.login-clean form .form-control{background:#f7f9fc;border:none;border-bottom:1px solid #dfe7f1;border-radius:0;box-shadow:none;outline:0;color:inherit;text-indent:8px;height:42px}.login-clean form .btn-primary{background:#f4476b;border:none;border-radius:4px;padding:11px;box-shadow:none;margin-top:26px;text-shadow:none;outline:0!important}.login-clean form .btn-primary:active,.login-clean form .btn-primary:hover{background:#eb3b60}.login-clean form .btn-primary:active{transform:translateY(1px)}.login-clean form .forgot{display:block;text-align:center;font-size:12px;color:#6f7a85;opacity:.9;text-decoration:none}.login-clean form .forgot:active,.login-clean form .forgot:hover{opacity:1;text-decoration:none}.navigation-clean{background:#fff;padding-top:.75rem;padding-bottom:.75rem;color:#333;border-radius:0;box-shadow:none;border:none;margin-bottom:0}@media (min-width:768px){.navigation-clean{padding-top:1rem;padding-bottom:1rem}}.navigation-clean .navbar-brand{font-weight:700;color:inherit}.navigation-clean .navbar-brand:hover{color:#222}.navigation-clean .navbar-toggler{border-color:#ddd;color:#888}.navigation-clean .navbar-toggler:focus,.navigation-clean .navbar-toggler:hover{background:0 0}.navigation-clean .form-inline,.navigation-clean .navbar-collapse{border-top-color:#ddd}.navigation-clean.navbar-light .navbar-nav .nav-link.active,.navigation-clean.navbar-light .navbar-nav .nav-link.active:focus,.navigation-clean.navbar-light .navbar-nav .nav-link.active:hover{color:#8f8f8f;box-shadow:none;background:0 0;pointer-events:none}.navigation-clean.navbar .navbar-nav .nav-link{padding-left:18px;padding-right:18px}.navigation-clean.navbar-light .navbar-nav .nav-link{color:#465765}.navigation-clean.navbar-light .navbar-nav .nav-link:focus,.navigation-clean.navbar-light .navbar-nav .nav-link:hover{color:#37434d!important;background-color:transparent}.navigation-clean .navbar-nav>li>.dropdown-menu{margin-top:-5px;box-shadow:none;background-color:#fff;border-radius:2px}.navigation-clean .dropdown-menu .dropdown-item,.navigation-clean .dropdown-menu .dropdown-item:focus{line-height:2;color:#37434d}.navigation-clean .dropdown-menu .dropdown-item:focus,.navigation-clean .dropdown-menu .dropdown-item:hover{background:#eee;color:inherit}.social-icons{color:#313437;background-color:#fff;text-align:center;padding:70px 0}@media (max-width:767px){.social-icons{padding:50px 0}}.social-icons i{font-size:32px;display:inline-block;color:#757980;margin:0 10px;width:60px;height:60px;border:1px solid #c8ced7;text-align:center;border-radius:50%;line-height:60px}

179
server/views/css/404.css Normal file
View File

@ -0,0 +1,179 @@
@import url(https://fonts.googleapis.com/css?family=Lato:100,300,400);
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::-webkit-input-placeholder, textarea:focus::-webkit-input-placeholder {
color: #bbb5af;
}
input::-moz-placeholder, textarea::-moz-placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::-moz-placeholder, textarea:focus::-moz-placeholder {
color: #bbb5af;
}
input::placeholder, textarea::placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::placeholder, textarea::focus:placeholder {
color: #bbb5af;
}
input::-ms-placeholder, textarea::-ms-placeholder {
color: #aca49c;
font-size: 0.875em;
}
input:focus::-ms-placeholder, textarea:focus::-ms-placeholder {
color: #bbb5af;
}
/* on hover placeholder */
input:hover::-webkit-input-placeholder, textarea:hover::-webkit-input-placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::-webkit-input-placeholder, textarea:hover:focus::-webkit-input-placeholder {
color: #cbc6c1;
}
input:hover::-moz-placeholder, textarea:hover::-moz-placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::-moz-placeholder, textarea:hover:focus::-moz-placeholder {
color: #cbc6c1;
}
input:hover::placeholder, textarea:hover::placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::placeholder, textarea:hover:focus::placeholder {
color: #cbc6c1;
}
input:hover::placeholder, textarea:hover::placeholder {
color: #e2dedb;
font-size: 0.875em;
}
input:hover:focus::-ms-placeholder, textarea:hover::focus:-ms-placeholder {
color: #cbc6c1;
}
body {
font-family: 'Lato', sans-serif;
background: #e2dedb;
color: #b3aca7;
}
header {
position: relative;
margin: 100px 0 25px 0;
font-size: 2.3em;
text-align: center;
letter-spacing: 7px;
}
return {
position: relative;
margin: 100px 0 25px 0;
font-size: 1.0em;
text-align: center;
letter-spacing: 3px;
}
#form {
position: relative;
width: 500px;
margin: 50px auto 100px auto;
}
input {
font-family: 'Lato', sans-serif;
font-size: 0.875em;
width: 470px;
height: 50px;
padding: 0px 15px 0px 15px;
background: transparent;
outline: none;
color: #726659;
border: solid 1px #b3aca7;
border-bottom: none;
transition: all 0.3s ease-in-out;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
}
input:hover {
background: #b3aca7;
color: #e2dedb;
}
textarea {
width: 470px;
max-width: 470px;
height: 110px;
max-height: 110px;
padding: 15px;
background: transparent;
outline: none;
color: #726659;
font-family: 'Lato', sans-serif;
font-size: 0.875em;
border: solid 1px #b3aca7;
transition: all 0.3s ease-in-out;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
}
textarea:hover {
background: #b3aca7;
color: #e2dedb;
}
#submit {
width: 470px;
padding: 0;
margin: -5px 0px 0px 0px;
font-family: 'Lato', sans-serif;
font-size: 0.875em;
color: #b3aca7;
outline:none;
cursor: pointer;
border: solid 1px #b3aca7;
}
#submit:hover {
color: #e2dedb;
}
a {
color: #726659;
}

49
server/views/gallery.ejs Normal file
View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Gallery</title>
<meta property="og:site_name" content="ShareX Upload Server">
<meta property="og:title" content="Media Gallery">
<meta property="og:description" content="View Uploaded Media">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<div class="container">
<div class="row fbox3">
<% pictures.forEach(pic => { %>
<div class="col-sm-4 d-flex justify-content-center align-items-center"><a href="<%= pic; %>" data-fancybox="gallery" data-caption="<%= pic; %>"><img class="img-fluid" src="<%= pic; %>" alt="<%= pic; %>"></a></div>
<% })%>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Gallery</title>
<meta property="og:site_name" content="ShareX Upload Server">
<meta property="og:title" content="Media Gallery">
<meta property="og:description" content="View Uploaded Media">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<div class="login-clean" style="background-color: rgb(59,59,59);">
<form action="/gallery" method="post" style="background-color: rgb(51,51,51);">
<h2 class="sr-only">Login Form</h2>
<div class="illustration"><i class="fa fa-photo" style="color: rgb(230,94,94);"></i></div>
<div class="form-group"><input class="form-control" type="password" name="password" placeholder="Password" id="password" style="background-color: rgb(51,51,51);"></div>
<div class="form-group"><button class="btn btn-primary btn-block" type="submit" style="background-color: rgb(230,94,94);">Log In</button></div>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.js"></script>
</body>
</html>

23
server/views/md.ejs Normal file
View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta name="theme-color" content="#DC603A">
<meta property="og:title" content="HPaste">
<meta property="og:description" content="<%= ogDesc; %>...">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="highlight.pack.js"></script>
</head>
<style>
body {
margin-top: 30px;
margin-bottom: 30px;
margin-right: 30px;
margin-left: 30px;
}
</style>
<body>
<%- mdRender; %>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>

1
server/views/mp3.ejs Normal file
View File

@ -0,0 +1 @@
<body><video controls="" autoplay="" name="media"><source src="data:audio/mp3;base64,<%= data; %>" type="audio/mpeg"></video></body>

17
server/views/paste.ejs Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta name="theme-color" content="#DC603A">
<meta property="og:title" content="HPaste">
<meta property="og:description" content="<%= ogDesc; %>...">
<link rel="stylesheet" href="atom-one-dark.css">
<link rel="stylesheet" href="paste.css">
<script src="highlight.pack.js"></script>
<script src="highlightjs-line-numbers.min.js"></script>
</head>
<body>
<pre><code id="code"><%= pData; %></code></pre>
<script>hljs.initHighlightingOnLoad()</script>
<script>hljs.initLineNumbersOnLoad();</script>
</body>
</html>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Image Showcase</title>
<meta name="theme-color" content="#DC603A">
<meta property="og:title" content="Image Showcase">
<meta property="og:description" content="Camera: <%= camera; %>
F-Stop: <%= fstop; %>
Shutter Speed: <%= shutter; %>
ISO: <%= iso; %>
Focal Length: <%= focal; %>
Lens: <%= lens; %>">
<meta property="og:image" content="<%= filename; %>">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<style>
.showcaseImage {
filter: drop-shadow(0px 0px 1px rgba(0,0,0,.3))
drop-shadow(0px 0px 10px rgba(0,0,0,.3));
height: <%= height; %>px !important;
width: <%= width; %>px !important;
object-fit: scale-down !important;
}
body {
background-color: white;
height: 100%;
}
.is-horizontal-center {
justify-content: center;
display: inline;
}
</style>
</head>
<body>
<section class="section has-text-centered ">
<div class="has-text-centered">
<h4><%= dims; %></h4>
<br />
<a class="column is-one-quarter is-horizontal-center has-text-centered "data-fancybox="gallery" data-caption="<b>Camera:</b> <%= camera; %><br />
<b>F-Stop:</b> <%= fstop; %><br />
<b>Shutter Speed:</b> <%= shutter; %><br />
<b>ISO:</b> <%= iso; %><br />
<b>Lens:</b> <%= lens; %><br />
<b>Focal Length:</b> <%= focal; %>" href="<%= filename; %>"><img height="500px" class="is-horizontal-center showcaseImage" src="<%= filename; %>"></a>
</div>
</section>
</body>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Authorization</title>
<meta property="og:site_name" content="ShareX Upload Server">
<meta property="og:title" content="Password Protected Media">
<meta property="og:description" content="Provide password to view contents">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div class="login-clean" style="background-color: rgb(59,59,59);">
<form action="/pupload" method="post" style="background-color: rgb(51,51,51);">
<h2 class="sr-only">Login Form</h2>
<div class="illustration"><i class="fa fa-photo" style="color: rgb(230,94,94);"></i></div>
<div class="form-group"><input class="form-control" type="password" name="password" placeholder="Password" id="password" style="background-color: rgb(51,51,51);"></div>
<div class="form-group"><input class="form-control" type="email" name="file" value="<%= fileName; %>" id="file" style="background-color: rgb(51,51,51);" readonly></div>
<div class="form-group"><button class="btn btn-primary btn-block" type="submit" style="background-color: rgb(230,94,94);">Authorize</button></div>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.js"></script>
</body>
</html>

77
server/views/short.ejs Normal file
View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>URL Shortener</title>
<meta property="og:site_name" content="ShareX Upload Server">
<meta property="og:title" content="URL Shortener">
<meta property="og:description" content="Shorten a URL">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<style>
.err::-webkit-input-placeholder {
color: red;
}
.success::-webkit-input-placeholder {
color: green;
}
</style>
</head>
<body style="background-color: rgb(59,59,59);">
<div id="afterBox">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
if(window.location.search){
if(window.location.search.toString().includes("error")){
var error = window.location.search.toString().replace(/(\?error=)+/g, '').replace(/[\_]/g, ' ');
document.getElementById("afterBox").innerHTML = '<div class="alert alert-info" role="alert" id="save-sucess" style="height: 50px;padding-bottom: 6px;margin-bottom: 0px;"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button><i class="icon ion-checkmark-round mr-1"></i><span style="color: #0C6D38 !important;">'+ error + '<br></span></div>';
}else{
var result = window.location.search.toString().replace(/(\?success=)+/g, '').replace(/[\_]/g, ' ');
document.getElementById("afterBox").innerHTML = '<div class="alert alert-info" role="alert" id="save-sucess" style="background-color: #B4F7D2!important;border: 1px solid #0C6D38;height: 50px;padding-bottom: 6px;margin-bottom: 0px;"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button><i class="icon ion-checkmark-round mr-1"></i><span style="color: #0C6D38 !important;">'+ result + '<br></span></div>';
}
}
});
</script>
</div>
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/gallery" style="color: rgb(230,94,94);">Gallery</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<div class="login-clean" style="background-color: rgb(59,59,59);">
<form action="/short" method="post" id="urlForm" style="background-color: rgb(52,52,52);">
<h2 class="sr-only">Login Form</h2>
<div class="illustration"><i class="fas fa-link" style="color: rgb(230,94,94);"></i></div>
<div class="form-group"><input type="url" id="URL" name="URL" placeholder="URL" autocomplete="off" inputmode="url" class="form-control" style="background-color: rgb(52,52,52);" /></div>
<% if(!public) { %>
<div class="form-group"><input class="form-control" type="password" name="password" placeholder="Password" id="password" style="background-color: rgb(51,51,51);"></div>
<% } %>
<div class="form-group"><button class="btn btn-primary btn-block" type="submit" style="background-color: rgb(230,94,94);">Shorten URL</button></div>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>UNAUTHORIZED</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/gallery" style="color: rgb(230,94,94);">Gallery</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/upload" style="color: rgb(230,94,94);">Upload</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<h1 class="text-center shadow-none justify-content-center align-items-center align-content-center align-self-center" style="color: rgb(230,94,94);margin: 8px;width: 99%;height: 99%;padding-top: 140px;"><br>UNAUTHORIZED<br></h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>

71
server/views/upload.ejs Normal file
View File

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Upload</title>
<meta property="og:site_name" content="ShareX Upload Server">
<meta property="og:title" content="File Upload">
<meta property="og:description" content="Upload files to the server">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=ABeeZee">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="background-color: rgb(59,59,59);">
<div id="afterBox">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
if(window.location.search){
if(window.location.search.toString().includes("error")){
var error = window.location.search.toString().replace(/(\?error=)+/g, '').replace(/[\_]/g, ' ');
document.getElementById("afterBox").innerHTML = '<div class="alert alert-info" role="alert" id="save-sucess" style="height: 50px;padding-bottom: 6px;margin-bottom: 0px;"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button><i class="icon ion-checkmark-round mr-1"></i><span style="color: #0C6D38 !important;">'+ error + '<br></span></div>';
}else{
var result = window.location.search.toString().replace(/(\?success=)+/g, '').replace(/[\_]/g, ' ');
document.getElementById("afterBox").innerHTML = '<div class="alert alert-info" role="alert" id="save-sucess" style="background-color: #B4F7D2!important;border: 1px solid #0C6D38;height: 50px;padding-bottom: 6px;margin-bottom: 0px;"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button><i class="icon ion-checkmark-round mr-1"></i><span style="color: #0C6D38 !important;">'+ result + '<br></span></div>';
}
}
});
</script>
</div>
<div>
<nav class="navbar navbar-light navbar-expand-md navigation-clean" style="background-color: rgb(52,52,52);">
<div class="container"><a class="navbar-brand text-left d-flex d-xl-flex justify-content-xl-start" href="#" style="color: rgb(255,255,255);font-family: Roboto, sans-serif;">ShareX Webserver</a><button class="navbar-toggler" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div
class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item" role="presentation"><a class="nav-link" href="/" style="color: rgb(230,94,94);">Home</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/short" style="color: rgb(230,94,94);">URL Shortener</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="/gallery" style="color: rgb(230,94,94);">Gallery</a></li>
<li class="nav-item" role="presentation"><a class="nav-link" href="https://github.com/TannerReynolds/node-sharex-server" style="color: rgb(230,94,94);">Github</a></li>
</ul>
</div>
</div>
</nav>
</div>
<div class="login-clean" style="background-color: rgb(59,59,59);">
<form action="/api/files" method="post" style="background-color: rgb(51,51,51);" enctype="multipart/form-data" name="fdataForm">
<h2 class="sr-only">Upload Form</h2>
<div class="illustration"><i class="fa fa-photo" style="color: rgb(230,94,94);"></i></div>
<% if(!public) { %>
<div class="form-group"><input class="form-control" type="password" name="password" placeholder="Password" id="password" style="background-color: rgb(51,51,51);"></div>
<% } %>
<div class="form-group"><input class="form-control" type="password" name="pupload" placeholder="Pupload" id="pupload" style="background-color: rgb(51,51,51);"></div>
<div class = "form-group"><input type="file" id="fdataUploader" name="fdataUploader" required/></div>
<div class="form-group"><button class="btn btn-primary btn-block" type="submit" style="background-color: rgb(230,94,94);">Upload</button></div>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.2/dist/jquery.fancybox.min.js"></script>
</body>
</html>