before frontend login
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
'use strict'
|
||||
|
||||
import { getLogger } from 'frontblock-generic/Types';
|
||||
import { promises as fs, mkdirSync } from "fs"
|
||||
import { RPCServer } from 'rpclibrary'
|
||||
import { AdminConf, TableDefiniton } from '../Types/Types';
|
||||
import { RPCConfigLoader } from '../Components/RPCConfigLoader';
|
||||
import * as Path from 'path'
|
||||
import * as Knex from 'knex';
|
||||
import * as http from 'http';
|
||||
import * as express from 'express';
|
||||
import { TableDefinitionExporter } from '../Types/Interfaces';
|
||||
import { FrontworkComponent } from '../Types/FrontworkComponent';
|
||||
|
||||
const logger = getLogger("admin", 'debug')
|
||||
|
||||
export class FrontworkAdmin
|
||||
implements TableDefinitionExporter {
|
||||
knex:Knex
|
||||
config: RPCConfigLoader<AdminConf>
|
||||
|
||||
private express
|
||||
private httpServer
|
||||
|
||||
constructor(private components: FrontworkComponent[]){
|
||||
this.config = new RPCConfigLoader<AdminConf>({
|
||||
name: "FrontworkAdminConf",
|
||||
getDefaultConfig: () => {
|
||||
return {
|
||||
httpPort: 8080,
|
||||
eventBusConf: {},
|
||||
dbConf: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: Path.join(__dirname, "data/frontworkAdmin.sqlite")
|
||||
},
|
||||
useNullAsDefault: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}, './config', this.configChangeHandler)
|
||||
|
||||
components.forEach(c => {
|
||||
c.admin = this
|
||||
if(c.onSetAdmin) c.onSetAdmin(this)
|
||||
})
|
||||
}
|
||||
|
||||
async start(){
|
||||
await this.makeKnex()
|
||||
this.startWebsocket()
|
||||
await Promise.all( this.components.map(c => c.initialize?c.initialize():undefined ))
|
||||
this.startWebserver()
|
||||
|
||||
}
|
||||
|
||||
protected configChangeHandler = (conf:AdminConf, key?:string) => {
|
||||
if(key === 'dbConf'){
|
||||
this.makeKnex()
|
||||
}
|
||||
}
|
||||
|
||||
getConfigKey(key:string){
|
||||
return this.config.getConfigKey(key)
|
||||
}
|
||||
|
||||
setConfigKey(key:string, value:any){
|
||||
return this.config.setConfigKey(key, value)
|
||||
}
|
||||
|
||||
getTableDefinitions(): TableDefiniton[]{
|
||||
return [
|
||||
...this.components
|
||||
].flatMap(exporter => exporter.getTableDefinitions())
|
||||
}
|
||||
|
||||
private startWebsocket(){
|
||||
new RPCServer(20000, [
|
||||
...this.components,
|
||||
])
|
||||
}
|
||||
|
||||
private startWebserver(){
|
||||
if(this.httpServer != null || this.express != null){
|
||||
logger.warn("Webserver is already running")
|
||||
return
|
||||
}
|
||||
|
||||
let port:number = this.config.getConfig().httpPort
|
||||
this.express = express()
|
||||
this.express.use('/', express.static('dist/static'))
|
||||
|
||||
/**
|
||||
* get the compiled FrontendPlugins.js
|
||||
*/
|
||||
this.express.get('/plugins/:id'+".js", async (request, response) => {
|
||||
const pth = Path.resolve("plugins/"+request.params.id, "FrontendPlugin.js");
|
||||
const file = await fs.readFile(pth)
|
||||
const frontend = file.toString()
|
||||
|
||||
response.status(200)
|
||||
response.set('Content-Type', 'application/javascript')
|
||||
response.send(frontend)
|
||||
})
|
||||
|
||||
/**
|
||||
* serve the index.html from the static folder
|
||||
*/
|
||||
this.express.get("/", (request, response) => {
|
||||
response.status(200)
|
||||
response.sendFile('index.html');
|
||||
})
|
||||
|
||||
/**
|
||||
* redirect all the other traffic to the single page app
|
||||
*/
|
||||
this.express.get("*", (request, response) => {
|
||||
response.status(301)
|
||||
response.redirect('/')
|
||||
})
|
||||
|
||||
this.httpServer = new http.Server(this.express)
|
||||
this.httpServer.listen(port, () => {
|
||||
logger.info('Admin panel listening for HTTP on *'+port)
|
||||
})
|
||||
}
|
||||
|
||||
private stopWebserver(){
|
||||
if(this.httpServer == null || this.express == null){
|
||||
logger.warn("Webserver is not running")
|
||||
return
|
||||
}
|
||||
this.httpServer.close()
|
||||
this.httpServer = null
|
||||
this.express = null
|
||||
logger.info("Webserver stopped")
|
||||
}
|
||||
|
||||
async makeKnex():Promise<Knex>{
|
||||
const conf:Knex.Config = this.config.getConfigKey("dbConf")
|
||||
|
||||
logger.debug("Making new knex:", conf)
|
||||
if(conf.client === 'sqlite3'){
|
||||
mkdirSync(Path.dirname((<any>conf.connection).filename), {recursive: true})
|
||||
}
|
||||
|
||||
this.knex = Knex(conf)
|
||||
|
||||
await Promise.all(this.getTableDefinitions().map(async (def)=>{
|
||||
const hasTable = await this.knex.schema.hasTable(def.name)
|
||||
if(!hasTable){
|
||||
await this.knex.schema.createTable(def.name, def.tableBuilder)
|
||||
}
|
||||
}))
|
||||
|
||||
return this.knex
|
||||
}
|
||||
}
|
||||
|
||||
process.on( 'SIGINT', function() {
|
||||
logger.info("Shutting down from SIGINT (Ctrl-C)" );
|
||||
// some other closing procedures go here
|
||||
process.exit(0);
|
||||
})
|
||||
Reference in New Issue
Block a user