nfp_sites/discord_embed/api/serve.mjs

117 lines
3.5 KiB
JavaScript

import path from 'path'
import { HttpError } from 'flaska'
import Parent from '../base/serve.mjs'
import fs from 'fs/promises'
import fsSync from 'fs'
import dot from 'dot'
import config from '../base/config.mjs'
import AlphabeticID from './id.mjs'
export default class ServeHandler extends Parent {
loadTemplate(indexFile) {
this.template = dot.template(indexFile.toString(), { argName: [
'imageLink',
'videoLink',
'error',
'siteUrl',
'siteUrlBase',
'version',
'nonce',
'in_debug',
'inputVideo',
'inputImage'
] })
}
register(server) {
super.register(server)
server.flaska.onerror(this.serveError.bind(this))
}
serveError(err, ctx) {
ctx.log.error(err)
if (err instanceof HttpError) {
ctx.status = err.status
ctx.state.error = err.message
} else {
ctx.status = 500
ctx.state.error = 'Unknown error occured'
}
let videoLink = ctx.query.get('v') || ''
let imageLink = ctx.query.get('i') || ''
ctx.body = this.template({
videoLink: videoLink,
imageLink: imageLink,
error: ctx.state.error || '',
inputVideo: ctx.state.video || videoLink || '',
inputImage: ctx.state.image || imageLink || '',
siteUrl: this.frontend + ctx.url,
siteUrlBase: this.frontend + '/',
version: this.version,
nonce: ctx.state.nonce,
in_debug: config.get('NODE_ENV') === 'development' && false,
})
ctx.type = 'text/html; charset=utf-8'
}
async serveIndex(ctx) {
if (config.get('NODE_ENV') === 'development') {
let indexFile = await fs.readFile(path.join(this.root, 'index.html'))
this.loadTemplate(indexFile)
}
let videoLink = ctx.query.get('v') || ''
let imageLink = ctx.query.get('i') || ''
if (!ctx.state.error) {
if (ctx.url.match(/^\/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]+$/) && ctx.url.length < 7) {
try {
let id = AlphabeticID.decode(ctx.url.slice(1))
if (id) {
let res = await ctx.db.safeCallProc('discord_embed.link_get', [id - 3843])
if (res.first.length) {
videoLink = ctx.state.video = res.first[0].video_link
if (!ctx.state.video.startsWith('https://cdn.discordapp.com')
&& !ctx.state.video.includes('catbox.')
&& ctx.state.video.includes('?')) {
videoLink = this.frontend + '/video/' + ctx.url.slice(1) + '.webm'
}
imageLink = res.first[0].image_link
} else {
ctx.status = 404
}
}
} catch (err) {
ctx.log.error(err, 'Unable to fetch resource ' + ctx.url.slice(1))
ctx.state.error = 'Unknown error while fetching link.'
}
} else if (ctx.url !== '/') {
ctx.status = 404
}
}
if (videoLink.startsWith('https://cdn.discordapp.com')) {
videoLink = videoLink.replace('https://cdn.discordapp.com', 'https://discordproxy.nfp.is')
}
let payload = {
videoLink: videoLink,
imageLink: imageLink,
error: ctx.state.error || '',
inputVideo: ctx.state.video || videoLink || '',
inputImage: ctx.state.image || imageLink || '',
siteUrl: this.frontend + ctx.url,
siteUrlBase: this.frontend + '/',
version: this.version,
nonce: ctx.state.nonce,
in_debug: config.get('NODE_ENV') === 'development' && false,
}
ctx.body = this.template(payload)
ctx.type = 'text/html; charset=utf-8'
}
}