import path from 'path' import fs from 'fs/promises' import { Flaska, FileResponse, HttpError, QueryHandler } from 'flaska' import config from './config.mjs' import PageRoutes from './page/routes.mjs' // import ArticleRoutes from './article/routes.mjs' import ParserMiddleware from './parser/middleware.mjs' export function run(http, port, core) { let localUtil = new core.sc.Util(import.meta.url) const staticRoot = localUtil.getPathFromRoot('../public') const flaska = new Flaska({ log: core.log, nonce: ['script-src'], nonceCacheLength: 50, defaultHeaders: { 'Server': 'Flaska', 'X-Content-Type-Options': 'nosniff', 'Content-Security-Policy': `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'; script-src 'self'`, 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Resource-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp', }, }, http) if (config.get('NODE_ENV') === 'development') { flaska.devMode() } const parser = new ParserMiddleware() flaska.before(function(ctx) { ctx.state.started = new Date().getTime() }) flaska.before(QueryHandler()) flaska.before(parser.contextParser()) flaska.after(function(ctx) { let ended = new Date().getTime() var requestTime = ended - ctx.state.started let status = '' let level = 'info' if (ctx.status >= 400) { status = ctx.status + ' ' level = 'warn' } if (ctx.status >= 500) { level = 'error' } ctx.log[level]({ duration: requestTime, status: ctx.status, }, `<-- ${status}${ctx.method} ${ctx.url}`) }) const page = new PageRoutes() flaska.get('/api/pagetree', page.getPageTree.bind(page)) // flaska.get('/api/pages', page.getAllPages.bind(page)) // flaska.get('/api/pages/:pageId', page.getSinglePage.bind(page)) // const article = new ArticleRoutes() // flaska.get('/api/articles/public', article.getPublicAllArticles.bind(article)) // flaska.get('/api/articles/public/:id', article.getPublicSingleArticle.bind(article)) // flaska.get('/api/pages/:pageId/articles/public', article.getPublicAllPageArticles.bind(article)) flaska.get('/::file', function(ctx) { if (ctx.params.file.startsWith('api/')) { throw new HttpError(404, 'Not Found: ' + ctx.params.file, { status: 404, message: 'Not Found: ' + ctx.params.file }) } let file = path.resolve(path.join(staticRoot, ctx.params.file ? ctx.params.file : 'index.html')) if (!file.startsWith(staticRoot)) { ctx.status = 404 ctx.body = 'HTTP 404 Error' return } return fs.stat(file).catch(function(err) { if (err.code === 'ENOENT') { file = path.resolve(path.join(staticRoot, 'index.html')) return fs.stat(file) } return Promise.reject(err) }) .then(function(stat) { ctx.body = new FileResponse(file, stat) }) }) return flaska.listenAsync(port).then(function() { core.log.info('Server is listening on port ' + port) }) }