holy shit it's working (migrated `upload.js` to `upload.ts`)

pull/62/head
tycrek 3 years ago
parent b77e0a7c05
commit f5896e0031
No known key found for this signature in database
GPG Key ID: 25D74F3943625263

@ -1,5 +1,10 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
export interface User {
token: string
username: string
}
export interface FileData { export interface FileData {
// Data from Multer file object // Data from Multer file object
path: string path: string
@ -11,7 +16,7 @@ export interface FileData {
// Data from ass // Data from ass
randomId: string randomId: string
deleteId: string deleteId: string
is: IsPossible, is: IsPossible
thumbnail: string thumbnail: string
vibrant: string vibrant: string
sha1: string sha1: string
@ -29,21 +34,26 @@ export interface IsPossible {
} }
export interface OpenGraphData { export interface OpenGraphData {
title?: string title?: string | string[]
description?: string description?: string | string[]
author?: string author?: string | string[]
authorUrl?: string authorUrl?: string | string[]
provider?: string provider?: string | string[]
providerUrl?: string providerUrl?: string | string[]
color?: string color?: string | string[]
} }
export interface AssRequest extends Request { export interface AssRequest extends Request {
resourceId?: string resourceId?: string
ass?: { resourceId: string } ass?: { resourceId: string }
token?: string
file?: FileData
} }
export interface AssResponse extends Response { export interface AssResponse extends Response {
} }
export interface ErrWrap extends Error {
code?: number | string
}

@ -1,3 +1,5 @@
import { FileData, AssRequest, AssResponse, ErrWrap, User } from "../definitions";
const fs = require('fs-extra'); const fs = require('fs-extra');
//const rateLimit = require('express-rate-limit'); //const rateLimit = require('express-rate-limit');
const { DateTime } = require('luxon'); const { DateTime } = require('luxon');
@ -10,7 +12,7 @@ const data = require('../data');
const users = require('../auth'); const users = require('../auth');
const ASS_LOGO = 'https://cdn.discordapp.com/icons/848274994375294986/8d339d4a2f3f54b2295e5e0ff62bd9e6.png?size=1024'; const ASS_LOGO = 'https://cdn.discordapp.com/icons/848274994375294986/8d339d4a2f3f54b2295e5e0ff62bd9e6.png?size=1024';
const express = require('express'); import express from 'express';
const router = express.Router(); const router = express.Router();
// Rate limit middleware // Rate limit middleware
@ -20,7 +22,7 @@ const router = express.Router();
})); */ })); */
// Block unauthorized requests and attempt token sanitization // Block unauthorized requests and attempt token sanitization
router.post('/', (req, res, next) => { router.post('/', (req: AssRequest, res: AssResponse, next: Function) => {
req.headers.authorization = req.headers.authorization || ''; req.headers.authorization = req.headers.authorization || '';
req.token = req.headers.authorization.replace(/[^\da-z]/gi, ''); // Strip anything that isn't a digit or ASCII letter req.token = req.headers.authorization.replace(/[^\da-z]/gi, ''); // Strip anything that isn't a digit or ASCII letter
!verify(req, users) ? log.warn('Upload blocked', 'Unauthorized').callback(() => res.sendStatus(CODE_UNAUTHORIZED)) : next(); // skipcq: JS-0093 !verify(req, users) ? log.warn('Upload blocked', 'Unauthorized').callback(() => res.sendStatus(CODE_UNAUTHORIZED)) : next(); // skipcq: JS-0093
@ -28,30 +30,30 @@ router.post('/', (req, res, next) => {
// Upload file // Upload file
//router.post('/', doUpload, processUploaded, ({ next }) => next()); //router.post('/', doUpload, processUploaded, ({ next }) => next());
router.post('/', (req, res, next) => doUpload(req, res, (err) => { router.post('/', (req: AssRequest, res: AssResponse, next: Function) => doUpload(req, res, (err: Error) => {
log.express().Header(req, 'Content-Type'); log.express().Header(req, 'Content-Type');
(err) ? log.error(`Multer encountered an ${!(err.toString().includes('MulterError')) ? 'unknown ' : ''}error`, err).callback(next, err) : log.debug('Multer', 'File saved in temp dir').callback(next); (err) ? log.error(`Multer encountered an ${!(err.toString().includes('MulterError')) ? 'unknown ' : ''}error`, err).callback(next, err) : log.debug('Multer', 'File saved in temp dir').callback(next);
}), processUploaded, ({ next }) => next()); }), processUploaded, ({ next }: { next: Function }) => next());
router.use('/', (err, _req, res, next) => err.code && err.code === 'LIMIT_FILE_SIZE' ? log.warn('Upload blocked', 'File too large').callback(() => res.status(CODE_PAYLOAD_TOO_LARGE).send(`Max upload size: ${maxUploadSize}MB`)) : next(err)); // skipcq: JS-0229 router.use('/', (err: ErrWrap, _req: AssRequest, res: AssResponse, next: Function) => err.code && err.code === 'LIMIT_FILE_SIZE' ? log.warn('Upload blocked', 'File too large').callback(() => res.status(CODE_PAYLOAD_TOO_LARGE).send(`Max upload size: ${maxUploadSize}MB`)) : next(err)); // skipcq: JS-0229
// Process uploaded file // Process uploaded file
router.post('/', (req, res, next) => { router.post('/', (req: AssRequest, res: AssResponse, next: Function) => {
// Load overrides // Load overrides
const trueDomain = getTrueDomain(req.headers['x-ass-domain']); const trueDomain = getTrueDomain(req.headers['x-ass-domain']);
const generator = req.headers['x-ass-access'] || resourceIdType; const generator = req.headers['x-ass-access'] || resourceIdType;
// Save domain with file // Save domain with file
req.file.domain = `${getTrueHttp()}${trueDomain}`; req.file!.domain = `${getTrueHttp()}${trueDomain}`;
// Get the uploaded time in milliseconds // Get the uploaded time in milliseconds
req.file.timestamp = DateTime.now().toMillis(); req.file!.timestamp = DateTime.now().toMillis();
// Keep track of the token that uploaded the resource // Keep track of the token that uploaded the resource
req.file.token = req.token; req.file!.token = req.token ?? '';
// Attach any embed overrides, if necessary // Attach any embed overrides, if necessary
req.file.opengraph = { req.file!.opengraph = {
title: req.headers['x-ass-og-title'], title: req.headers['x-ass-og-title'],
description: req.headers['x-ass-og-description'], description: req.headers['x-ass-og-description'],
author: req.headers['x-ass-og-author'], author: req.headers['x-ass-og-author'],
@ -62,17 +64,17 @@ router.post('/', (req, res, next) => {
}; };
// Save the file information // Save the file information
const resourceId = generateId(generator, resourceIdSize, req.headers['x-ass-gfycat'] || gfyIdSize, req.file.originalname); const resourceId = generateId(generator, resourceIdSize, req.headers['x-ass-gfycat'] || gfyIdSize, req.file!.originalname);
log.debug('Saving data', data.name); log.debug('Saving data', data.name);
data.put(resourceId.split('.')[0], req.file).then(() => { data.put(resourceId.split('.')[0], req.file).then(() => {
// Log the upload // Log the upload
const logInfo = `${req.file.originalname} (${req.file.mimetype}, ${formatBytes(req.file.size)})`; const logInfo = `${req.file!.originalname} (${req.file!.mimetype}, ${formatBytes(req.file!.size)})`;
log.success('File uploaded', logInfo, `uploaded by ${users[req.token] ? users[req.token].username : '<token-only>'}`); log.success('File uploaded', logInfo, `uploaded by ${users[req.token ?? ''] ? users[req.token ?? ''].username : '<token-only>'}`);
// Build the URLs // Build the URLs
const resourceUrl = `${getTrueHttp()}${trueDomain}/${resourceId}`; const resourceUrl = `${getTrueHttp()}${trueDomain}/${resourceId}`;
const thumbnailUrl = `${getTrueHttp()}${trueDomain}/${resourceId}/thumbnail`; const thumbnailUrl = `${getTrueHttp()}${trueDomain}/${resourceId}/thumbnail`;
const deleteUrl = `${getTrueHttp()}${trueDomain}/${resourceId}/delete/${req.file.deleteId}`; const deleteUrl = `${getTrueHttp()}${trueDomain}/${resourceId}/delete/${req.file!.deleteId}`;
// Send the response // Send the response
res.type('json').send({ resource: resourceUrl, thumbnail: thumbnailUrl, delete: deleteUrl }) res.type('json').send({ resource: resourceUrl, thumbnail: thumbnailUrl, delete: deleteUrl })
@ -88,10 +90,10 @@ router.post('/', (req, res, next) => {
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setTitle(logInfo) .setTitle(logInfo)
.setURL(resourceUrl) .setURL(resourceUrl)
.setDescription(`**Size:** \`${formatBytes(req.file.size)}\`\n**[Delete](${deleteUrl})**`) .setDescription(`**Size:** \`${formatBytes(req.file!.size)}\`\n**[Delete](${deleteUrl})**`)
.setThumbnail(thumbnailUrl) .setThumbnail(thumbnailUrl)
.setColor(req.file.vibrant) .setColor(req.file!.vibrant)
.setTimestamp(req.file.timestamp); .setTimestamp(req.file!.timestamp);
// Send the embed to the webhook, then delete the client after to free resources // Send the embed to the webhook, then delete the client after to free resources
log.debug('Sending webhook to client', client); log.debug('Sending webhook to client', client);
@ -103,14 +105,18 @@ router.post('/', (req, res, next) => {
} }
// Also update the users upload count // Also update the users upload count
if (!users[req.token]) { if (!users[req.token ?? '']) {
const generateUsername = () => generateId('random', 20, null); // skipcq: JS-0074 const generateUsername = () => generateId('random', 20, null); // skipcq: JS-0074
let username = generateUsername(); let username: string = generateUsername();
while (Object.values(users).findIndex((user) => user.username === username) !== -1) // skipcq: JS-0073
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
while (Object.values(users).findIndex((user: User) => user.username === username) !== -1) // skipcq: JS-0073
username = generateUsername(); username = generateUsername();
users[req.token] = { username, count: 0 };
users[req.token ?? ''] = { username, count: 0 };
} }
users[req.token].count += 1; users[req.token ?? ''].count += 1;
fs.writeJsonSync(path('auth.json'), { users }, { spaces: 4 }); fs.writeJsonSync(path('auth.json'), { users }, { spaces: 4 });
log.debug('Upload request flow completed', ''); log.debug('Upload request flow completed', '');
Loading…
Cancel
Save