ionian/src/server.ts
2021-02-22 23:10:02 +09:00

145 lines
No EOL
5.6 KiB
TypeScript

import Koa from 'koa';
import Router from 'koa-router';
import {get_setting, SettingConfig} from './SettingConfig';
import {connectDB} from './database';
import {DiffManager, createDiffRouter} from './diff/mod';
import { createReadStream, readFileSync } from 'fs';
import getContentRouter from './route/contents';
import { createKnexDocumentAccessor, createKnexUserController } from './db/mod';
import bodyparser from 'koa-bodyparser';
import {error_handler} from './route/error_handler';
import {createUserMiddleWare,createLoginMiddleware, isAdminFirst, getAdmin, LogoutMiddleware, createRefreshTokenMiddleware} from './login';
import {createInterface as createReadlineInterface} from 'readline';
import { DocumentAccessor, UserAccessor } from './model/mod';
import { createMangaWatcher } from './diff/watcher/manga_watcher';
class ServerApplication{
readonly userController: UserAccessor;
readonly documentController: DocumentAccessor;
readonly diffManger;
readonly app: Koa;
private index_html:Buffer;
private constructor(userController: UserAccessor,documentController:DocumentAccessor){
this.userController = userController;
this.documentController = documentController;
this.diffManger = new DiffManager(documentController);
this.app = new Koa();
this.index_html = readFileSync("index.html");
}
private async setup(){
const setting = get_setting();
const app = this.app;
if(setting.cli){
const userAdmin = await getAdmin(this.userController);
if(await isAdminFirst(userAdmin)){
const rl = createReadlineInterface({input:process.stdin,output:process.stdout});
rl.setPrompt("put admin password : ");
rl.prompt();
const pw = await new Promise((res:(data:string)=>void,err)=>{
rl.on('line',(data)=>res(data));
});
userAdmin.reset_password(pw);
}
}
app.use(bodyparser());
app.use(error_handler);
app.use(createUserMiddleWare(this.userController));
let diff_router = createDiffRouter(this.diffManger);
this.diffManger.register("manga",createMangaWatcher());
let router = new Router();
router.use('/api/diff',diff_router.routes());
router.use('/api/diff',diff_router.allowedMethods());
this.serve_index(router);
this.serve_static_file(router);
const content_router = getContentRouter(this.documentController);
router.use('/api/doc',content_router.routes());
router.use('/api/doc',content_router.allowedMethods());
router.post('/user/login',createLoginMiddleware(this.userController));
router.post('/user/logout',LogoutMiddleware);
router.post('/user/refresh',createRefreshTokenMiddleware(this.userController));
if(setting.mode == "development"){
let mm_count = 0;
app.use(async (ctx,next)=>{
console.log(`==========================${mm_count++}`);
const fromClient = ctx.state['user'].username === "" ? ctx.ip : ctx.state['user'].username;
console.log(`${fromClient} : ${ctx.method} ${ctx.url}`);
await next();
//console.log(`404`);
});}
app.use(router.routes());
app.use(router.allowedMethods());
}
private serve_index(router:Router){
const serveindex = (url:string)=>{
router.get(url, (ctx)=>{
ctx.type = 'html'; ctx.body = this.index_html;
const setting = get_setting();
ctx.set('x-content-type-options','no-sniff');
if(setting.mode === "development"){
ctx.set('cache-control','no-cache');
}
else{
ctx.set('cache-control','public, max-age=3600');
}
})
}
serveindex('/');
serveindex('/doc/:rest(.*)');
serveindex('/search');
serveindex('/login');
serveindex('/profile');
serveindex('/difference');
serveindex('/setting');
}
private serve_static_file(router: Router){
const static_file_server = (path:string,type:string) => {
router.get('/'+path,async (ctx,next)=>{
const setting = get_setting();
ctx.type = type; ctx.body = createReadStream(path);
ctx.set('x-content-type-options','no-sniff');
if(setting.mode === "development"){
ctx.set('cache-control','no-cache');
}
else{
ctx.set('cache-control','public, max-age=3600');
}
})};
const setting = get_setting();
static_file_server('dist/css/style.css','css');
static_file_server('dist/js/bundle.js','js');
if(setting.mode === "development")
static_file_server('dist/js/bundle.js.map','text');
}
start_server(){
let setting = get_setting();
console.log("start server");
//todo : support https
return this.app.listen(setting.port,setting.localmode ? "127.0.0.1" : "0.0.0.0");
}
static async createServer(){
const setting = get_setting();
let db = await connectDB();
const app = new ServerApplication(createKnexUserController(db)
,createKnexDocumentAccessor(db));
await app.setup();
return app;
}
}
//let Koa = require("koa");
export async function create_server(){
return await ServerApplication.createServer();
}
export default {create_server};