You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

185 lines
6.2 KiB

"use strict"
import plugins from "@/plugins"
import path from "path"
import { baseDir, isDev, publicDir, sourceDir, templateDir } from "@/util"
import { validateJwt, validateSession } from "./auth"
import Hapi, { Server } from "@hapi/hapi"
import { Sequelize } from "sequelize"
import { Req, Res } from "#/global"
import { sequelize } from "./plugins/sequelize"
import fs from "fs-extra"
import { Boom } from "@hapi/boom"
// const Hapi = require("@hapi/hapi");
// const HapiSwagger = require("hapi-swagger");
// const HapiSwagger = require("hapi-swaggered-ui"); // swagger v2版本
const pugPluginAlias = require("pug-alias")
const run = async (): Promise<Server> => {
const server = Hapi.server({
port: 3388,
host: "0.0.0.0",
debug: isDev ? {
request: ['error']
} : false
})
server.events.on('request', (request, event, tags) => {
if (tags.error) {
loggerSite.error(request.path, "\n", event);
} else {
loggerSite.info(request.path, "\n", event);
}
});
server.events.on('log', (event, tags) => {
if (tags.error) {
loggerSite.error(event);
} else {
loggerSite.info(event);
}
});
await server.register([
{
plugin: require('hapi-sequelizejs'),
options: [
{
name: "data", // identifier
models: isDev ? ["source/models/**/*.ts"] : ["dist/models/**/*.js"], // paths/globs to model files
// ignoredModels: [__dirname + "/server/models/**/*.js"], // OPTIONAL: paths/globs to ignore files
sequelize: sequelize, // sequelize instance
sync: true, // sync models - default false
forceSync: false, // force sync (drops tables) - default false
},
],
},
])
//===== JWT ===== Start
// await server.register(require("hapi-auth-jwt2"));
// server.auth.strategy("jwt", "jwt", {
// key: process.env.KEY, // Never Share your secret key
// validate: validateJwt, // validate function defined above
// verifyOptions: { algorithms: ["HS256"] },
// });
//===== JWT ===== End
//===== session ===== Start
// https://hapi.dev/module/cookie/api?v=11.0.2
await server.register(require("@hapi/cookie"))
server.auth.strategy("session", "cookie", {
cookie: {
ttl: 1000 * 60 * 60 * 24,
path: "/", // 测试退出时set-cookie失效,加上这个好了
name: "sid", //cookie的名字
password: process.env.KEY,
isSecure: false, // false: 允许 Cookie 通过不安全的连接传输,这会使其受到攻击
isHttpOnly: true,
clearInvalid: false,
strictHeader: true
},
redirectTo(request: Req) {
if (request.path.startsWith("/api")) {
return false
}
return "/login"
},
appendNext: true,
validate: validateSession,
})
server.auth.default("session")
//===== session ===== End
await server.register(plugins as any)
/**
* 模板引擎
*/
// https://hapi.dev/module/vision/api/?v=6.1.0
await server.register(require("@hapi/vision"))
const Pug = require("pug")
Pug.filters.public = function (text, options) {
const p = path.resolve(publicDir, text)
if (fs.pathExistsSync(p)) {
return fs.readFileSync(p, "utf-8")
}
return ""
};
server.views({
engines: {
ejs: require("ejs"),
pug: Pug,
},
isCached: process.env.NODE_ENV === "development" ? false : true,
compileMode: "sync", // ejs
relativeTo: baseDir,
layout: false, // ejs
layoutPath: path.resolve(templateDir, "layout"), // ejs
path: "template",
// pug
compileOptions: {
// By default Pug uses relative paths (e.g. ../root.pug), when using absolute paths (e.g. include /root.pug), basedir is prepended.
// https://pugjs.org/language/includes.html
basedir: templateDir,
plugins: [
pugPluginAlias({
// as Function
"@": fn => fn.replace(/^@/, "template"),
"@hxpath": fn => fn.replace(/^@hxpath/, "template/htmx/path"),
"@views": fn => fn.replace(/^@views/, "template/views"),
}),
],
},
})
// http://localhost:3000/documentation
await server.register([
{
plugin: require("hapi-swagger"),
options: {
documentationPath: "/doc",
info: {
title: "Dream 文档",
version: "1.0.0",
},
grouping: "tags",
tags: [
{
name: "sum",
description: "working with maths",
externalDocs: {
description: "Find out more",
url: "http://example.org",
},
},
{
name: "store",
description: "storing data",
externalDocs: {
description: "Find out more",
url: "http://example.org",
},
},
],
},
},
])
server.ext('onPreResponse', (request, h) => {
const { response } = request
// 如果状态码为403,则调用自定义错误处理程序
if (response instanceof Boom && (response.output.statusCode < 200 || response.output.statusCode > 299)) {
return h.view('403.pug', { error: response})
}
return h.continue;
});
await server.start()
logger.trace("Server running on %s", server.info.uri.replace("0.0.0.0", "localhost"))
return server
}
process.on("unhandledRejection", err => {
console.log("unhandledRejection:", err)
process.exit(1)
})
export { run }