diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..5f98501 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +dist/*.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..ec6ee13 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,14 @@ +/** @format */ + +module.exports = { + parser: '@typescript-eslint/parser', //定义ESLint的解析器 + extends: [ + 'plugin:prettier/recommended', // 使用prettier中的样式规范,且如果使得ESLint会检测prettier的格式问题,同样将格式问题以error的形式抛出 + ], + parserOptions: {ecmaVersion: 2019, sourceType: 'module'}, + env: { + //指定代码的运行环境 + browser: true, + node: true, + }, +} diff --git a/.gitignore copy b/.gitignore copy new file mode 100644 index 0000000..9dacc57 --- /dev/null +++ b/.gitignore copy @@ -0,0 +1,8 @@ +.idea +node_modules +build +dist +.DS_Store +tmp +target +boundle.log diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..1e80711 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,13 @@ +module.exports = { + "printWidth": 120, + "semi": false, // 在语句末尾添加分号 + "singleQuote": true, // 使用单引号而非双引号 + "trailingComma": "all", // 在任何可能的多行中输入尾逗号 + "bracketSpacing": true, // 在对象字面量声明所使用的的花括号前后({})输出空格 + "jsxBracketSameLine": true, // 在多行JSX元素最后一行的末尾添加 > 而使 > 单独一行(不适用于自闭和元素) + "arrowParens": "avoid", // 为单行箭头函数的参数添加圆括号。 + "requirePragma": false, // Prettier可以严格按照按照文件顶部的一些特殊的注释格式化代码 + "insertPragma": false, // 顶部插入一个 @format + "tabWidth": 2, + "useTabs": false, +}; diff --git a/pm2_dev.sh b/pm2_dev.sh new file mode 100755 index 0000000..9fbcd78 --- /dev/null +++ b/pm2_dev.sh @@ -0,0 +1 @@ +pm2 start npm --name "oauth-svr" --log-date-format "YYYY-MM-DD HH:mm:ss" -- run "dev:api" \ No newline at end of file diff --git a/src/api.server.ts b/src/api.server.ts index 5ceaf52..f3c437e 100644 --- a/src/api.server.ts +++ b/src/api.server.ts @@ -1,45 +1,40 @@ -import fastify, { - FastifyError, - FastifyInstance, - FastifyReply, - FastifyRequest, -} from "fastify"; -import helmet from "@fastify/helmet"; -import { IncomingMessage, Server, ServerResponse } from "http"; -import { RouterMap } from "decorators/router"; -import { mongoose } from "@typegoose/typegoose"; -import logger from "logger/logger"; -import config from "config/config"; -import { ConnectOptions } from "mongoose"; -import { DiscordSvr } from "services/discord.svr"; +import fastify, { FastifyError, FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' +import helmet from '@fastify/helmet' +import { IncomingMessage, Server, ServerResponse } from 'http' +import { RouterMap } from 'decorators/router' +import { mongoose } from '@typegoose/typegoose' +import logger from 'logger/logger' +import config from 'config/config' +import { ConnectOptions } from 'mongoose' +import { DiscordSvr } from 'services/discord.svr' -const zReqParserPlugin = require("plugins/zReqParser"); +const zReqParserPlugin = require('plugins/zReqParser') -const zTokenParserPlugin = require("plugins/zTokenParser"); +const zTokenParserPlugin = require('plugins/zTokenParser') -const apiAuthPlugin = require("plugins/apiauth"); +const apiAuthPlugin = require('plugins/apiauth') -const fs = require("fs"); -const join = require("path").join; +const fs = require('fs') +const join = require('path').join -require("./common/Extend"); +require('./common/Extend') export class ApiServer { - server: FastifyInstance; + server: FastifyInstance public constructor() { - this.server = fastify({ logger: true, trustProxy: true }); - this.registerPlugins(); - console.log("version::" + process.version); + this.server = fastify({ logger: true, trustProxy: true }) + this.registerPlugins() + console.log('version::' + process.version) } private registerPlugins() { - this.server.register(require("@fastify/formbody")); - this.server.register(zReqParserPlugin); + this.server.register(require('@fastify/formbody')) + this.server.register(zReqParserPlugin) this.server.register(helmet, { hidePoweredBy: false, contentSecurityPolicy: false, - }); - this.server.register(zTokenParserPlugin); + }) + this.server.register(zTokenParserPlugin) this.server.register(apiAuthPlugin, { secret: { @@ -47,43 +42,40 @@ export class ApiServer { public: config.api.token_secret_public, }, expiresIn: config.api.token_expiresIn, - }); - if (process.env.NODE_ENV !== "production") { - this.server.register(require("@fastify/cors"), {}); + }) + if (process.env.NODE_ENV !== 'production') { + this.server.register(require('@fastify/cors'), {}) } - this.server.register(require("@fastify/view"), { + this.server.register(require('@fastify/view'), { engine: { - ejs: require("ejs"), + ejs: require('ejs'), }, - }); + }) } private registerRouter() { - logger.log("register api routers"); - let self = this; + logger.log('register api routers') + let self = this for (let [controller, config] of RouterMap.decoratedRouters) { for (let data of config.data) { logger.info( - "add router", - data.method || "all", + 'add router', + data.method || 'all', data.path, - `${data.target.constructor.name}.${controller.name}()` - ); + `${data.target.constructor.name}.${controller.name}()`, + ) // @ts-ignore - self.server[data.method || "all"]( + self.server[data.method || 'all']( data.path, { - preValidation: async function ( - request: FastifyRequest, - reply: FastifyReply - ) { - request.roles = config.roles; - await this.apiAuth(request, reply); + preValidation: async function (request: FastifyRequest, reply: FastifyReply) { + request.roles = config.roles + await this.apiAuth(request, reply) }, }, - controller - ); + controller, + ) } } } @@ -91,20 +83,20 @@ export class ApiServer { * 加载所有的controller */ initControllers() { - logger.info("Bootstrap controllers..."); - const controllers = join(__dirname, "./controllers"); + logger.info('Bootstrap controllers...') + const controllers = join(__dirname, './controllers') fs.readdirSync(controllers) .filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/)) .forEach((file: any) => { // logger.log(file); - return require(join(controllers, file)); - }); + return require(join(controllers, file)) + }) } initSchedules() {} initServcers() { - new DiscordSvr().init(); + new DiscordSvr().init() } async connectDB() { @@ -113,42 +105,38 @@ export class ApiServer { maxPoolSize: 10, keepAlive: true, keepAliveInitialDelay: 300000, - }; - const uri = config.db_main; - logger.info(`connect to ${uri} ...`); + } + const uri = config.db_main + logger.info(`connect to ${uri} ...`) try { // await mongoose.createConnection(uri, options) - await mongoose.connect(uri, options); - logger.log("DB Connected"); + await mongoose.connect(uri, options) + logger.log('DB Connected') } catch (err) { - logger.log(`DB Connection Error: ${err.message}`); + logger.log(`DB Connection Error: ${err.message}`) } } private setErrHandler() { this.server.setNotFoundHandler(function ( request: any, - reply: { send: (arg0: { errcode: number; errmsg: string }) => void } + reply: { send: (arg0: { errcode: number; errmsg: string }) => void }, ) { - reply.send({ errcode: 404, errmsg: "page not found" }); - }); - this.server.setErrorHandler(function ( - error: FastifyError, - request: FastifyRequest, - reply: FastifyReply - ) { - let statusCode = (error && error.statusCode) || 100; + reply.send({ errcode: 404, errmsg: 'page not found' }) + }) + this.server.setErrorHandler(function (error: FastifyError, request: FastifyRequest, reply: FastifyReply) { + let statusCode = (error && error.statusCode) || 100 if (statusCode >= 500) { - logger.error(error); + logger.error(error) } else if (statusCode >= 400) { - logger.info(error); + logger.info(error) } else { - logger.error(error); + logger.error(error) } reply.code(200).send({ errcode: statusCode, - errmsg: error ? error.message : "unknown error", - }); - }); + errmsg: error ? error.message : 'unknown error', + }) + }) } /** * 格式化接口返回数据, 统一封装成如下格式 @@ -160,47 +148,41 @@ export class ApiServer { * @private */ private setFormatSend() { - this.server.addHook( - "preSerialization", - async (request: FastifyRequest, reply: FastifyReply, payload) => { - reply.header("X-Powered-By", "PHP/5.4.16"); + this.server.addHook('preSerialization', async (request: FastifyRequest, reply: FastifyReply, payload) => { + reply.header('X-Powered-By', 'PHP/5.4.16') + // @ts-ignore + if (!payload.errcode) { // @ts-ignore - if (!payload.errcode) { + if (payload.direct) { // @ts-ignore - if (payload.direct) { - // @ts-ignore - delete payload.direct; - return payload; - } - payload = { - errcode: 0, - data: payload, - }; + delete payload.direct + return payload + } + payload = { + errcode: 0, + data: payload, } - return payload; } - ); + return payload + }) } public async start() { - let self = this; + let self = this return new Promise(async (resolve, reject) => { - await self.connectDB(); - self.initControllers(); - self.registerRouter(); - self.setErrHandler(); - self.setFormatSend(); - self.initSchedules(); - self.initServcers(); - this.server.listen( - { port: config.api.port, host: config.api.host }, - (err: any, address: any) => { - if (err) { - logger.log(err); - process.exit(0); - } - resolve && resolve(address); + await self.connectDB() + self.initControllers() + self.registerRouter() + self.setErrHandler() + self.setFormatSend() + self.initSchedules() + self.initServcers() + this.server.listen({ port: config.api.port, host: config.api.host }, (err: any, address: any) => { + if (err) { + logger.log(err) + process.exit(0) } - ); - }); + resolve && resolve(address) + }) + }) } } diff --git a/src/controllers/twitter.controller.ts b/src/controllers/twitter.controller.ts new file mode 100644 index 0000000..8dd75d7 --- /dev/null +++ b/src/controllers/twitter.controller.ts @@ -0,0 +1,13 @@ +import BaseController, { ROLE_ANON } from 'common/base.controller' +import { ZError } from 'common/ZError' +import { role, router } from 'decorators/router' +import logger from 'logger/logger' + +class TwitterController extends BaseController { + @role(ROLE_ANON) + @router('get /twitter/redirect_uri') + async discordCallback(req, res) { + logger.info('twitter redirect: ', req.params) + return res.view('/templates/twitter_redirect.ejs') + } +} diff --git a/templates/twitter_redirect.ejs b/templates/twitter_redirect.ejs new file mode 100644 index 0000000..fdd9afc --- /dev/null +++ b/templates/twitter_redirect.ejs @@ -0,0 +1,22 @@ + + + + Discord Redirect + + + + + + +