const express = require('express') const path = require('path') const fs = require('fs') const crypto = require('crypto') const fsp = fs.promises const router = express.Router() const cfgLoader = require(path.join('..', '..', 'config-loader'))(path.join(__dirname, 'config.json'), { root: path.join(process.cwd(), '..', 'fiche', 'code'), style: 'tomorrow-night', index: 'index.html', }) function calculateHash(file, type){ const testFile = fs.readFileSync(file); const shasum = crypto.createHash('sha384') .update(testFile) .digest('base64'); return `sha384-${shasum}` } function encodeSpecial (string) { let i = string.length const a = [] while (i--) { var iC = string[i].charCodeAt() if (iC < 65 || iC > 127 || (iC > 90 && iC < 97)) { a[i] = '&#' + iC + ';' } else { a[i] = string[i] } } return a.join('') } async function init () { const config = await cfgLoader const root = path.resolve(config.root) const themeFile = path.join(__dirname, `${config.style}.css`) const scriptFile = path.join(__dirname, 'highlight.min.js') const themeFileHash = calculateHash(themeFile) const scriptFileHash = calculateHash(scriptFile) await fsp.mkdir(root, { recursive: true }) await fsp.access(root, fs.constants.F_OK) router.get('/theme.css', (req, res) => { res.header('Cache-Control', 'max-age=' + 7 * 24 * 60 * 60 * 1000) res.sendFile(themeFile) }); router.get('/script.js', (req, res) => { res.header('Cache-Control', 'max-age=' + 7 * 24 * 60 * 60 * 1000) res.sendFile(scriptFile) }); router.get('/:name', async (req, res, next) => { const name = req.params.name if (name.length > 5) { try { const text = await fsp.readFile(path.join(root, 'index.html')) res.send(text) } catch (e) { res.status(403) } return res.end() } const fichePath = path.join(root, name, 'index.txt') const ua = req.get('User-Agent') let reqRaw = req.query.raw != null if (!reqRaw && ua && (ua.match(/curl\//i) != null || ua.match(/wget\//i) != null)) reqRaw = true let text try { text = await fsp.readFile(fichePath, { encoding: 'utf8' }) } catch (e) { return res.status(404).end() } res.header('Cache-Control', 'max-age=' + 7 * 24 * 60 * 60 * 1000) if (reqRaw) { return res.set('Content-Type', 'text/plain').send(text) } const etext = encodeSpecial(text) const payload = `
${etext}
` res.set('Content-Type', 'text/html; charset=UTF-8').send(payload) }) router.get('/', (req, res, next) => { if (!config.index) { return next() } let inp = config.index if (inp.indexOf('/') !== 0) { inp = path.join(__dirname, inp) } else { inp = path.resolve(inp) } res.sendFile(inp) }) return router } module.exports = init