完善discord登录流程
This commit is contained in:
parent
3621d8cc44
commit
a2313ff701
@ -1,74 +1,89 @@
|
||||
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 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, IncomingMessage, ServerResponse>
|
||||
server: FastifyInstance<Server, IncomingMessage, ServerResponse>;
|
||||
|
||||
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(helmet, { hidePoweredBy: false, contentSecurityPolicy: false })
|
||||
this.server.register(zTokenParserPlugin)
|
||||
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(apiAuthPlugin, {
|
||||
secret: { private: config.api.token_secret_private, public: config.api.token_secret_public },
|
||||
secret: {
|
||||
private: config.api.token_secret_private,
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,56 +91,64 @@ 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();
|
||||
}
|
||||
|
||||
async connectDB() {
|
||||
const options: ConnectOptions = {
|
||||
minPoolSize: 5,
|
||||
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",
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 格式化接口返回数据, 统一封装成如下格式
|
||||
@ -137,40 +160,47 @@ 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')
|
||||
// @ts-ignore
|
||||
if (!payload.errcode) {
|
||||
this.server.addHook(
|
||||
"preSerialization",
|
||||
async (request: FastifyRequest, reply: FastifyReply, payload) => {
|
||||
reply.header("X-Powered-By", "PHP/5.4.16");
|
||||
// @ts-ignore
|
||||
if (payload.direct) {
|
||||
if (!payload.errcode) {
|
||||
// @ts-ignore
|
||||
delete payload.direct
|
||||
return payload
|
||||
}
|
||||
payload = {
|
||||
errcode: 0,
|
||||
data: payload,
|
||||
if (payload.direct) {
|
||||
// @ts-ignore
|
||||
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()
|
||||
this.server.listen({ port: config.api.port, host: config.api.host }, (err: any, address: any) => {
|
||||
if (err) {
|
||||
logger.log(err)
|
||||
process.exit(0)
|
||||
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);
|
||||
}
|
||||
resolve && resolve(address)
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,11 @@ import BaseController, { ROLE_ANON } from "common/base.controller";
|
||||
import { ZError } from "common/ZError";
|
||||
import { role, router } from "decorators/router";
|
||||
import logger from "logger/logger";
|
||||
import { exchangeDiscrodCodeForToken, userInfo } from "services/discord.svr";
|
||||
import {
|
||||
DiscordSvr,
|
||||
exchangeDiscrodCodeForToken,
|
||||
userInfo,
|
||||
} from "services/discord.svr";
|
||||
|
||||
class DiscordController extends BaseController {
|
||||
@role(ROLE_ANON)
|
||||
@ -14,9 +18,19 @@ class DiscordController extends BaseController {
|
||||
if (code) {
|
||||
access_token = await exchangeDiscrodCodeForToken(code);
|
||||
let uinfo = await userInfo(access_token);
|
||||
console.log(uinfo);
|
||||
return res.view("/templates/discord_redirect.ejs");
|
||||
} else {
|
||||
return res.view("/templates/discord_redirect.ejs");
|
||||
}
|
||||
}
|
||||
|
||||
@role(ROLE_ANON)
|
||||
@router("get /discord/check_user_role")
|
||||
async checkUserRole(req, res) {
|
||||
// let { uid } = req.params;
|
||||
let uid = "1034482894690861116";
|
||||
let role = await new DiscordSvr().checkUserRole(uid);
|
||||
return { role };
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
import { ZError } from "common/ZError";
|
||||
import { singleton } from "decorators/singleton";
|
||||
const { Client, Events, GatewayIntentBits } = require("discord.js");
|
||||
|
||||
export async function exchangeDiscrodCodeForToken(code: string) {
|
||||
const clientId = process.env.DISCORD_CLIENT_ID;
|
||||
const clientSecret = process.env.DISCORD_CLIENT_SECRET;
|
||||
@ -34,3 +38,29 @@ export async function userInfo(token: string) {
|
||||
console.log(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@singleton
|
||||
export class DiscordSvr {
|
||||
private client: any;
|
||||
private guild: any;
|
||||
public async init() {
|
||||
console.log("DiscordSvr init");
|
||||
this.client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||
this.client.once(Events.ClientReady, async (c) => {
|
||||
console.log(`Ready! Logged in as ${c.user.tag}`);
|
||||
this.guild = await this.client.guilds.fetch(process.env.DISCROD_GUILD_ID);
|
||||
});
|
||||
this.client.login(process.env.DISCORD_BOT_TOKEN);
|
||||
}
|
||||
|
||||
public async checkUserRole(uid: string) {
|
||||
if (!this.guild) {
|
||||
throw new ZError(10, "DiscordSvr not init");
|
||||
}
|
||||
const member = await this.guild.members.fetch(uid);
|
||||
if (!member) {
|
||||
return false;
|
||||
}
|
||||
return member.roles.cache.has(process.env.DISCORD_ROLE_ID);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user