More development

This commit is contained in:
Jonatan Nilsson 2022-04-05 16:47:24 +00:00
parent f35c195680
commit a2b1fc9bc8
13 changed files with 114 additions and 208 deletions

1
.gitignore vendored
View file

@ -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

View file

@ -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()

View file

@ -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') }
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
}
// 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)
},
"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

View file

@ -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)
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
},

View file

@ -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()
}

View file

@ -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 */

View file

@ -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()
}
}

View file

@ -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()
@ -34,6 +57,16 @@ export function run(http, port, core) {
}, `<-- ${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 })

View file

@ -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:

11
db.json
View file

@ -1,11 +0,0 @@
{
"core": {
"version": 1,
"nfp_moe": {
"active": "static",
"latestInstalled": "",
"updater": "",
"versions": []
}
}
}

20
dev.mjs
View file

@ -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()
})

View file

@ -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)
})
}
/*

View file

@ -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",