@ -3,8 +3,8 @@ const escape = require('escape-html');
const fetch = require ( 'node-fetch' ) ;
const { deleteS3 } = require ( '../storage' ) ;
const { diskFilePath , s3enabled } = require ( '../config.json' ) ;
const { path , saveData, log, getTrueHttp , getTrueDomain , formatBytes , formatTimestamp , getS3url , getDirectUrl , getSafeExt , getResourceColor , replaceholder } = require ( '../utils' ) ;
const { CODE _ BAD_REQUEST , CODE _ UNAUTHORIZED, CODE _NOT _FOUND , } = require ( '../MagicNumbers.json' ) ;
const { path , log, getTrueHttp , getTrueDomain , formatBytes , formatTimestamp , getS3url , getDirectUrl , getSafeExt , getResourceColor , replaceholder } = require ( '../utils' ) ;
const { CODE _ UNAUTHORIZED, CODE _NOT _FOUND , } = require ( '../MagicNumbers.json' ) ;
const data = require ( '../data' ) ;
const users = require ( '../auth' ) ;
@ -14,16 +14,17 @@ const router = express.Router();
// Middleware for parsing the resource ID and handling 404
router . use ( ( req , res , next ) => {
// Parse the resource ID
req . ass = { resourceId : escape ( req . resourceId ) . split ( '.' ) [ 0 ] } ;
req . ass = { resourceId : escape ( req . resourceId || '' ) . split ( '.' ) [ 0 ] } ;
// If the ID is invalid, return 404. Otherwise, continue normally // skipcq: JS-0093
( ! req . ass . resourceId || ! data [ req . ass . resourceId ] ) ? res . sendStatus ( CODE _NOT _FOUND ) : next ( ) ;
// If the ID is invalid, return 404. Otherwise, continue normally
data . has ( req . ass . resourceId )
. then ( ( has ) => has ? next ( ) : res . sendStatus ( CODE _NOT _FOUND ) )
. catch ( next ) ;
} ) ;
// View file
router . get ( '/' , ( req , res ) => {
router . get ( '/' , ( req , res , next ) => data . get ( req . ass . resourceId ) . then ( ( fileData ) => {
const { resourceId } = req . ass ;
const fileData = data [ resourceId ] ;
const isVideo = fileData . mimetype . includes ( 'video' ) ;
// Build OpenGraph meta tags
@ -47,15 +48,12 @@ router.get('/', (req, res) => {
oembedUrl : ` ${ getTrueHttp ( ) } ${ getTrueDomain ( ) } / ${ resourceId } /oembed ` ,
ogtype : isVideo ? 'video.other' : 'image' ,
urlType : ` og: ${ isVideo ? 'video' : 'image' } ` ,
opengraph : replaceholder ( ogs . join ( '\n' ) , fileData )
opengraph : replaceholder ( ogs . join ( '\n' ) , fileData .size , fileData . timestamp , fileData . originalname )
} ) ;
} ) ;
} ) .catch ( next ) ) ;
// Direct resource
router . get ( '/direct*' , ( req , res ) => {
const { resourceId } = req . ass ;
const fileData = data [ resourceId ] ;
router . get ( '/direct*' , ( req , res , next ) => data . get ( req . ass . resourceId ) . then ( ( fileData ) => {
// Send file as an attachement for downloads
if ( req . query . download )
res . header ( 'Content-Disposition' , ` attachment; filename=" ${ fileData . originalname } " ` ) ;
@ -73,58 +71,52 @@ router.get('/direct*', (req, res) => {
} ;
uploaders [ s3enabled ? 's3' : 'local' ] ( ) ;
} ) ;
} ) .catch ( next ) ) ;
// Thumbnail response
router . get ( '/thumbnail' , ( req , res ) => {
const { resourceId } = req . ass ;
// Read the file and send it to the client
fs . readFile ( path ( diskFilePath , 'thumbnails/' , data [ resourceId ] . thumbnail ) )
router . get ( '/thumbnail' , ( req , res , next ) =>
data . get ( req . ass . resourceId )
. then ( ( { thumbnail } ) => fs . readFile ( path ( diskFilePath , 'thumbnails/' , thumbnail ) ) )
. then ( ( fileData ) => res . type ( 'jpg' ) . send ( fileData ) )
. catch ( console . error ) ;
} ) ;
. catch ( next ) ) ;
// oEmbed response for clickable authors/providers
// https://oembed.com/
// https://old.reddit.com/r/discordapp/comments/82p8i6/a_basic_tutorial_on_how_to_get_the_most_out_of/
router . get ( '/oembed' , ( req , res ) => {
const { resourceId } = req . ass ;
// Build the oEmbed object & send the response
const { opengraph , mimetype } = data [ resourceId ] ;
res . type ( 'json' ) . send ( {
version : '1.0' ,
type : mimetype . includes ( 'video' ) ? 'video' : 'photo' ,
author _url : opengraph . authorUrl ,
provider _url : opengraph . providerUrl ,
author _name : replaceholder ( opengraph . author || '' , data [ resourceId ] ) ,
provider _name : replaceholder ( opengraph . provider || '' , data [ resourceId ] )
} ) ;
} ) ;
router . get ( '/oembed' , ( req , res , next ) =>
data . get ( req . ass . resourceId )
. then ( ( { opengraph , mimetype , size , timestamp , originalname } ) =>
res . type ( 'json' ) . send ( {
version : '1.0' ,
type : mimetype . includes ( 'video' ) ? 'video' : 'photo' ,
author _url : opengraph . authorUrl ,
provider _url : opengraph . providerUrl ,
author _name : replaceholder ( opengraph . author || '' , size , timestamp , originalname ) ,
provider _name : replaceholder ( opengraph . provider || '' , size , timestamp , originalname )
} ) )
. catch ( next ) ) ;
// Delete file
router . get ( '/delete/:deleteId' , ( req , res ) => {
const { resourceId } = req . ass ;
const deleteId = escape ( req . params . deleteId ) ;
const fileData = data [ resourceId ] ;
// If the delete ID doesn't match, don't delete the file
if ( deleteId !== fileData . deleteId ) return res . sendStatus ( CODE _UNAUTHORIZED ) ;
// If the ID is invalid, return 400 because we are unable to process the resource
if ( ! resourceId || ! fileData ) return res . sendStatus ( CODE _BAD _REQUEST ) ;
log ( ` Deleted: ${ fileData . originalname } ( ${ fileData . mimetype } ) ` ) ;
// Save the file information
Promise . all ( [ s3enabled ? deleteS3 ( fileData ) : fs . rmSync ( path ( fileData . path ) ) , fs . rmSync ( path ( diskFilePath , 'thumbnails/' , fileData . thumbnail ) ) ] )
. then ( ( ) => {
delete data [ resourceId ] ;
saveData ( data ) ;
res . type ( 'text' ) . send ( 'File has been deleted!' ) ;
router . get ( '/delete/:deleteId' , ( req , res , next ) => {
let oldName , oldType ;
data . get ( req . ass . resourceId )
. then ( ( fileData ) => {
// Extract info for logs
oldName = fileData . originalname ;
oldType = fileData . mimetype ;
// Clean deleteId
const deleteId = escape ( req . params . deleteId ) ;
// If the delete ID doesn't match, don't delete the file
if ( deleteId !== fileData . deleteId ) return res . sendStatus ( CODE _UNAUTHORIZED ) ;
// Save the file information
return Promise . all ( [ s3enabled ? deleteS3 ( fileData ) : fs . rmSync ( path ( fileData . path ) ) , fs . rmSync ( path ( diskFilePath , 'thumbnails/' , fileData . thumbnail ) ) ] ) ;
} )
. catch ( console . error ) ;
. then ( ( ) => data . del ( req . ass . resourceId ) )
. then ( ( ) => ( log ( ` Deleted: ${ oldName } ( ${ oldType } ) ` ) , res . type ( 'text' ) . send ( 'File has been deleted!' ) ) )
. catch ( next ) ;
} ) ;
module . exports = router ;