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};