mirror of https://github.com/JoeBiellik/paste
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.5 KiB
JavaScript
139 lines
3.5 KiB
JavaScript
const config = require('config');
|
|
const fs = require('fs').promises;
|
|
const isBinaryFile = require('isbinaryfile').isBinaryFile;
|
|
const detectCharacterEncoding = require('detect-character-encoding');
|
|
const encoding = require('encoding');
|
|
const Paste = require('../models/paste');
|
|
|
|
module.exports = {
|
|
async index(ctx) {
|
|
await ctx.render('index', {
|
|
pretty: config.prettyHtml,
|
|
title: config.name,
|
|
url: ctx.request.origin,
|
|
expires: config.expires,
|
|
highlights: config.highlights
|
|
});
|
|
},
|
|
|
|
async view(ctx) {
|
|
try {
|
|
const paste = await Paste.findById(ctx.params.id).exec();
|
|
const lang = (Object.keys(ctx.query)[0] || '').toLowerCase();
|
|
|
|
ctx.set('Expires', paste.expiresAt.toUTCString());
|
|
ctx.set('Last-Modified', paste.updatedAt.toUTCString());
|
|
|
|
if (lang) {
|
|
await ctx.render('highlight', {
|
|
pretty: config.prettyHtml,
|
|
title: config.name + ' ' + paste.id,
|
|
paste: paste.paste,
|
|
lang: Object.keys(config.highlights).includes(lang) ? lang : 'unknown'
|
|
});
|
|
} else {
|
|
ctx.body = paste.paste;
|
|
}
|
|
} catch {
|
|
ctx.throw(404, 'Paste Not Found');
|
|
}
|
|
},
|
|
|
|
/* eslint-disable-next-line complexity */
|
|
async create(ctx) {
|
|
ctx.set('Cache-Control', 'no-cache');
|
|
|
|
// File body
|
|
if (ctx.request.files && Object.keys(ctx.request.files).length > 0) {
|
|
// Request body, xxx
|
|
let path = Object.values(ctx.request.files)[0].path;
|
|
|
|
try {
|
|
// Request body, paste=xxx
|
|
if (ctx.request.files.paste) {
|
|
path = ctx.request.files.paste.path;
|
|
}
|
|
|
|
if (await isBinaryFile(path)) ctx.throw('Binary file');
|
|
|
|
const data = await fs.readFile(path);
|
|
const detectedEncoding = detectCharacterEncoding(data);
|
|
|
|
ctx.request.body.paste = encoding.convert(data, 'utf8', detectedEncoding.encoding).toString();
|
|
} catch {
|
|
ctx.throw(400, 'Bad Paste Body');
|
|
} finally {
|
|
try {
|
|
await fs.unlink(path);
|
|
} catch {
|
|
// Ignore
|
|
}
|
|
}
|
|
}
|
|
|
|
// Raw body
|
|
if (typeof ctx.request.body === 'string') {
|
|
ctx.request.body = {
|
|
paste: ctx.request.body
|
|
};
|
|
}
|
|
|
|
if (!ctx.request.body.paste) {
|
|
ctx.throw(400, 'No Paste Provided');
|
|
}
|
|
|
|
// Expiry multiplier
|
|
try {
|
|
if (ctx.request.body.expire && ctx.request.body.multiplier) {
|
|
ctx.request.body.expire *= ctx.request.body.multiplier;
|
|
}
|
|
} catch {
|
|
ctx.throw(400, 'Bad Paste Expiry');
|
|
}
|
|
|
|
// /?expire=xxx
|
|
if (!ctx.request.body.expire && ctx.query.expire) {
|
|
ctx.request.body.expire = ctx.query.expire;
|
|
}
|
|
|
|
// No expire provided
|
|
if (!ctx.request.body.expire) {
|
|
ctx.request.body.expire = config.expires.default.value * config.expires.default.multiplier;
|
|
}
|
|
|
|
const paste = new Paste({
|
|
paste: ctx.request.body.paste,
|
|
ip: ctx.request.ip,
|
|
expiresAt: new Date(Date.now() + (ctx.request.body.expire * 1000))
|
|
});
|
|
|
|
try {
|
|
await paste.save();
|
|
} catch (err) {
|
|
ctx.throw(500, err.message);
|
|
}
|
|
|
|
// /?highlight=xxx
|
|
if (!ctx.request.body.highlight && ctx.query.highlight) {
|
|
ctx.request.body.highlight = ctx.query.highlight;
|
|
}
|
|
|
|
// /?xxx
|
|
if (!ctx.request.body.highlight && !ctx.query.highlight && ctx.query) {
|
|
ctx.request.body.highlight = Object.keys(ctx.query).find((k) => k !== 'redirect' && k !== 'expire');
|
|
}
|
|
|
|
let highlight = '';
|
|
|
|
if (ctx.request.body.highlight && Object.keys(config.highlights).includes(ctx.request.body.highlight)) {
|
|
highlight = '?' + ctx.request.body.highlight;
|
|
}
|
|
|
|
if (Object.keys(ctx.query).includes('redirect')) {
|
|
ctx.redirect(ctx.request.origin + '/' + paste.id + highlight);
|
|
} else {
|
|
ctx.body = ctx.request.origin + '/' + paste.id + highlight + '\n';
|
|
}
|
|
}
|
|
};
|