From a2b1fc9bc887c1760a3e8008245b69a3c1435a07 Mon Sep 17 00:00:00 2001 From: Jonatan Nilsson Date: Tue, 5 Apr 2022 16:47:24 +0000 Subject: [PATCH] More development --- .gitignore | 1 + api/article/model.mjs | 116 -------------------------------------- api/config.mjs | 75 ++++++++++++------------ api/knex.mjs | 15 ++++- api/log.mjs | 28 --------- api/page/routes.mjs | 2 +- api/parser/middleware.mjs | 4 +- api/server_flaska.mjs | 35 +++++++++++- api/staff/model.mjs | 2 +- db.json | 11 ---- dev.mjs | 20 +++++-- index.mjs | 9 ++- package.json | 4 +- 13 files changed, 114 insertions(+), 208 deletions(-) delete mode 100644 api/log.mjs delete mode 100644 db.json diff --git a/.gitignore b/.gitignore index e07b4b8..09a3fec 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ typings/ # Local development config file config/config.json +config.json package-lock.json public/assets/app.js public/assets/app.css diff --git a/api/article/model.mjs b/api/article/model.mjs index 0de8344..ffaa29f 100644 --- a/api/article/model.mjs +++ b/api/article/model.mjs @@ -149,122 +149,6 @@ Article.prototype = createPrototype({ is_featured: false, }) }, - - /*parent() { - return this.belongsTo(Page, 'parent_id') - }, - - banner() { - return this.belongsTo(Media, 'banner_id') - }, - - media() { - return this.belongsTo(Media, 'media_id') - }, - - staff() { - return this.belongsTo(Staff, 'staff_id') - }, - - files() { - return this.hasManyFiltered(File, 'file', 'article_id') - .query(qb => { - qb.orderBy('id', 'asc') - }) - },*/ - - /*getAll(ctx, where = {}, withRelated = [], orderBy = 'id', limitToday = false) { - return this.query(qb => { - this.baseQueryAll(ctx, qb, where, orderBy) - if (limitToday) { - qb.where('published_at', '<=', (new Date()).toISOString()) - } - }) - .fetchPage({ - pageSize: ctx.state.pagination.perPage, - page: ctx.state.pagination.page, - withRelated, - ctx: ctx, - }) - .then(result => { - ctx.state.pagination.total = result.pagination.rowCount - return result - }) - }, - - getSingle(id, withRelated = [], require = true, ctx = null, limitToday = false) { - return this.query(qb => { - qb.where(subq => { - subq.where({ id: Number(id) || 0 }) - .orWhere({ path: id }) - }) - if (limitToday && (!ctx || !ctx.state.user || ctx.state.user.level < 10)) { - qb.where('published_at', '<=', (new Date()).toISOString()) - } - }) - .fetch({ require, withRelated, ctx }) - }, - - async getFeatured(withRelated = [], ctx = null) { - let data = await this.query(qb => { - qb.where({ is_featured: true }) - .where('published_at', '<=', (new Date()).toISOString()) - }) - .fetch({ require: false, withRelated, ctx }) - if (!data) { - data = await this.query(qb => { - qb.where('published_at', '<=', (new Date()).toISOString()) - .whereNotNull('banner_id') - }) - .fetch({ require: false, withRelated, ctx }) - } - return data - }, - - getAllFromPage(ctx, pageId, withRelated = [], orderBy = 'id', limitToday = false) { - return this.query(qb => { - this.baseQueryAll(ctx, qb, {}, orderBy) - qb.leftOuterJoin('pages', 'articles.parent_id', 'pages.id') - qb.where(subq => { - subq.where('pages.id', pageId) - .orWhere('pages.parent_id', pageId) - }) - if (limitToday) { - qb.where('published_at', '<=', (new Date()).toISOString()) - } - qb.select('articles.*') - }) - .fetchPage({ - pageSize: ctx.state.pagination.perPage, - page: ctx.state.pagination.page, - withRelated, - ctx: ctx, - }) - .then(result => { - ctx.state.pagination.total = result.pagination.rowCount - return result - }) - }, - - setAllUnfeatured() { - return bookshelf.knex('articles') - .where({ is_featured: true }) - .update({ - is_featured: false, - }) - }, - - getFrontpageArticles(page = 1) { - return this.query(qb => { - qb.orderBy('published_at', 'DESC') - .where('published_at', '<=', (new Date()).toISOString()) - }) - .fetchPage({ - pageSize: 10, - page: page, - withRelated: ['files', 'media', 'banner', 'parent', 'staff'], - }) - },*/ }) const articleInstance = new Article() diff --git a/api/config.mjs b/api/config.mjs index 42ea8ed..9789815 100644 --- a/api/config.mjs +++ b/api/config.mjs @@ -46,45 +46,44 @@ nconf.env({ }) -// Load package.json for name and such -let pckg = JSON.parse(readFileSync('./package.json')) +// Load empty overrides that can be overwritten later +nconf.overrides({}) -pckg = _.pick(pckg, ['name', 'version', 'description', 'author', 'license', 'homepage']) - -if (nconf.get('DATABASE_URL')) { - pckg.knex = { connection: nconf.get('DATABASE_URL') } -} - -// Load overrides as second priority -nconf.overrides(pckg) - - -// Load any overrides from the appropriate config file -let configFile = 'config/config.json' - -/* istanbul ignore else */ -if (nconf.get('NODE_ENV') === 'test') { - configFile = 'config/config.test.json' -} - -/* istanbul ignore if */ -if (nconf.get('NODE_ENV') === 'production') { - configFile = 'config/config.production.json' -} - -nconf.file('main', configFile) - -// Load defaults -nconf.file('default', 'config/config.default.json') - - -// Final sanity checks -/* istanbul ignore if */ -if (typeof global.it === 'function' & !nconf.inTest()) { - // eslint-disable-next-line no-console - console.log('Critical: potentially running test on production enviroment. Shutting down.') - process.exit(1) -} +nconf.defaults({ + "NODE_ENV": "development", + "knex": { + "client": "pg", + "connection": { + "host" : "127.0.0.1", + "user" : "postgres", + "password" : "postgres", + "database" : "nfpmoe" + }, + "connectionslave": null, + "migrations": { + }, + "acquireConnectionTimeout": 10000 + }, + "frontend": { + "url": "http://beta01.nfp.moe" + }, + "jwt": { + "secret": "this-is-my-secret", + "options": { + "expiresIn": 604800 + } + }, + "sessionsecret": "this-is-session-secret-lol", + "bcrypt": 5, + "fileSize": 524288000, + "upload": { + "baseurl": "https://cdn.nfp.is", + "port": "2111", + "host": "storage01.nfp.is", + "name": "nfpmoe-dev", + "secret": "nfpmoe-dev" + } +}) export default nconf diff --git a/api/knex.mjs b/api/knex.mjs index c562bb9..b345d1d 100644 --- a/api/knex.mjs +++ b/api/knex.mjs @@ -3,7 +3,6 @@ import knexCore from 'knex-core' import config from './config.mjs' import defaults from './defaults.mjs' -import log from './log.mjs' const knex = knexCore(config.get('knex')) @@ -73,14 +72,24 @@ export function createPrototype(opts) { }, async getAllQuery(query, queryContext = null) { + console.log('1') let context = (queryContext || query).queryContext() if (!context.tables) throw new Error('getAll was called before query') let tables = context.tables let tableMap = new Map(tables) - let data = await query + try { + console.log(query) + console.log(query.toString()) + let data = await query + } catch (err) { + console.log(err) + throw err + } + console.log('3') if (data.length === 0) { + console.log('e1') return data } @@ -176,6 +185,8 @@ export function createPrototype(opts) { } } + console.log('2') + return out }, diff --git a/api/log.mjs b/api/log.mjs deleted file mode 100644 index b15f2dc..0000000 --- a/api/log.mjs +++ /dev/null @@ -1,28 +0,0 @@ -import bunyan from 'bunyan-lite' -import config from './config.mjs' -import * as defaults from './defaults.mjs' - -// Clone the settings as we will be touching -// on them slightly. -let settings = defaults.default(config.get('bunyan')) - -// Replace any instance of 'process.stdout' with the -// actual reference to the process.stdout. -for (let i = 0; i < settings.streams.length; i++) { - /* istanbul ignore else */ - if (settings.streams[i].stream === 'process.stdout') { - settings.streams[i].stream = process.stdout - } -} - -// Create our logger. -const log = bunyan.createLogger(settings) - -export default log - -log.logMiddleware = () => - (ctx, next) => { - ctx.log = log - - return next() - } diff --git a/api/page/routes.mjs b/api/page/routes.mjs index 816a972..13a98d4 100644 --- a/api/page/routes.mjs +++ b/api/page/routes.mjs @@ -25,7 +25,7 @@ export default class PageRoutes { async getSinglePage(ctx) { await this.security.ensureIncludes(ctx) - ctx.body = await this.Page.getSingle(ctx.params.id, ctx.state.filter.includes, true, ctx) + ctx.body = await this.Page.getSingle(ctx.params.pageId, ctx.state.filter.includes, true, ctx) } /** POST: /api/pages */ diff --git a/api/parser/middleware.mjs b/api/parser/middleware.mjs index 5eafc82..61e5aa5 100644 --- a/api/parser/middleware.mjs +++ b/api/parser/middleware.mjs @@ -11,11 +11,9 @@ export default class ParserMiddleware { } contextParser() { - return (ctx, next) => { + return (ctx) => { ctx.state.pagination = this.pagination.parsePagination(ctx) ctx.state.filter = this.pagination.parseFilter(ctx) - - return next() } } diff --git a/api/server_flaska.mjs b/api/server_flaska.mjs index e5f4cc1..f1669d9 100644 --- a/api/server_flaska.mjs +++ b/api/server_flaska.mjs @@ -1,6 +1,11 @@ import path from 'path' import fs from 'fs/promises' -import { Flaska, FileResponse, HttpError } from 'flaska' +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) @@ -8,11 +13,29 @@ export function run(http, port, core) { 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() @@ -33,6 +56,16 @@ export function run(http, port, core) { 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/')) { diff --git a/api/staff/model.mjs b/api/staff/model.mjs index 246f5a6..6227cdd 100644 --- a/api/staff/model.mjs +++ b/api/staff/model.mjs @@ -1,5 +1,5 @@ import { createPrototype, safeColumns } from '../knex.mjs' -import bcrypt from 'bcrypt' +// import bcrypt from 'bcrypt' /*import config from '../config.mjs'*/ /* Staff model: diff --git a/db.json b/db.json deleted file mode 100644 index afbabff..0000000 --- a/db.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "core": { - "version": 1, - "nfp_moe": { - "active": "static", - "latestInstalled": "", - "updater": "", - "versions": [] - } - } -} \ No newline at end of file diff --git a/dev.mjs b/dev.mjs index 61ef74a..141c7d5 100644 --- a/dev.mjs +++ b/dev.mjs @@ -1,10 +1,22 @@ +import fs from 'fs' import { ServiceCore } from 'service-core' import * as index from './index.mjs' -var core = new ServiceCore('nfp_moe', import.meta.url) -core.setConfig({ - port: 4030, -}) +var core = new ServiceCore('nfp_moe', import.meta.url, 4030, '') + +let config = { + frontend: { + url: 'http://localhost:4030' + } +} + +try { + config = JSON.parse(fs.readFileSync('./config.json')) +} catch {} + +config.port = 4030 + +core.setConfig(config) core.init(index).then(function() { return core.run() }) \ No newline at end of file diff --git a/index.mjs b/index.mjs index c942f12..5c4bc37 100644 --- a/index.mjs +++ b/index.mjs @@ -1,7 +1,12 @@ -import { run } from "./api/server_flaska.mjs" +import config from './api/config.mjs' export function start(http, port, ctx) { - return run(http, port, ctx) + config.stores.overrides.store = ctx.config + + return import('./api/server_flaska.mjs') + .then(function(server) { + return server.run(http, port, ctx) + }) } /* diff --git a/package.json b/package.json index 1799ddc..099593c 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "scripts": { "start": "node --experimental-modules index.mjs", "test": "echo \"Error: no test specified\" && exit 1", - "build": "asbundle app/index.js public/assets/app.js && asbundle app/admin.js public/assets/admin.js", + "bla": "sass --help", + "build:prod": "sass -s compressed app/app.scss public/assets/app.css && sass -s compressed app/admin.scss public/assets/admin.css && asbundle app/index.js public/assets/app.js && asbundle app/admin.js public/assets/admin.js", + "build": "sass app/app.scss public/assets/app.css && sass app/admin.scss public/assets/admin.css && asbundle app/index.js public/assets/app.js && asbundle app/admin.js public/assets/admin.js", "build:watch": "npm-watch build", "dev:server": "node dev.mjs | bunyan", "dev:server:watch": "npm-watch dev:server",