完善discord登录流程
This commit is contained in:
parent
3621d8cc44
commit
a2313ff701
@ -1,74 +1,89 @@
|
|||||||
import fastify, { FastifyError, FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
|
import fastify, {
|
||||||
import helmet from '@fastify/helmet'
|
FastifyError,
|
||||||
import { IncomingMessage, Server, ServerResponse } from 'http'
|
FastifyInstance,
|
||||||
import { RouterMap } from 'decorators/router'
|
FastifyReply,
|
||||||
import { mongoose } from '@typegoose/typegoose'
|
FastifyRequest,
|
||||||
import logger from 'logger/logger'
|
} from "fastify";
|
||||||
import config from 'config/config'
|
import helmet from "@fastify/helmet";
|
||||||
import { ConnectOptions } from 'mongoose'
|
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 fs = require("fs");
|
||||||
const join = require('path').join
|
const join = require("path").join;
|
||||||
|
|
||||||
require('./common/Extend')
|
require("./common/Extend");
|
||||||
|
|
||||||
export class ApiServer {
|
export class ApiServer {
|
||||||
server: FastifyInstance<Server, IncomingMessage, ServerResponse>
|
server: FastifyInstance<Server, IncomingMessage, ServerResponse>;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
this.server = fastify({ logger: true, trustProxy: true })
|
this.server = fastify({ logger: true, trustProxy: true });
|
||||||
this.registerPlugins()
|
this.registerPlugins();
|
||||||
console.log('version::' + process.version)
|
console.log("version::" + process.version);
|
||||||
}
|
}
|
||||||
private registerPlugins() {
|
private registerPlugins() {
|
||||||
this.server.register(require('@fastify/formbody'))
|
this.server.register(require("@fastify/formbody"));
|
||||||
this.server.register(zReqParserPlugin)
|
this.server.register(zReqParserPlugin);
|
||||||
this.server.register(helmet, { hidePoweredBy: false, contentSecurityPolicy: false })
|
this.server.register(helmet, {
|
||||||
this.server.register(zTokenParserPlugin)
|
hidePoweredBy: false,
|
||||||
|
contentSecurityPolicy: false,
|
||||||
|
});
|
||||||
|
this.server.register(zTokenParserPlugin);
|
||||||
|
|
||||||
this.server.register(apiAuthPlugin, {
|
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,
|
expiresIn: config.api.token_expiresIn,
|
||||||
})
|
});
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
this.server.register(require('@fastify/cors'), {})
|
this.server.register(require("@fastify/cors"), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.server.register(require('@fastify/view'), {
|
this.server.register(require("@fastify/view"), {
|
||||||
engine: {
|
engine: {
|
||||||
ejs: require('ejs'),
|
ejs: require("ejs"),
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerRouter() {
|
private registerRouter() {
|
||||||
logger.log('register api routers')
|
logger.log("register api routers");
|
||||||
let self = this
|
let self = this;
|
||||||
for (let [controller, config] of RouterMap.decoratedRouters) {
|
for (let [controller, config] of RouterMap.decoratedRouters) {
|
||||||
for (let data of config.data) {
|
for (let data of config.data) {
|
||||||
logger.info(
|
logger.info(
|
||||||
'add router',
|
"add router",
|
||||||
data.method || 'all',
|
data.method || "all",
|
||||||
data.path,
|
data.path,
|
||||||
`${data.target.constructor.name}.${controller.name}()`,
|
`${data.target.constructor.name}.${controller.name}()`
|
||||||
)
|
);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
self.server[data.method || 'all'](
|
self.server[data.method || "all"](
|
||||||
data.path,
|
data.path,
|
||||||
{
|
{
|
||||||
preValidation: async function (request: FastifyRequest, reply: FastifyReply) {
|
preValidation: async function (
|
||||||
request.roles = config.roles
|
request: FastifyRequest,
|
||||||
await this.apiAuth(request, reply)
|
reply: FastifyReply
|
||||||
|
) {
|
||||||
|
request.roles = config.roles;
|
||||||
|
await this.apiAuth(request, reply);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
controller,
|
controller
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,56 +91,64 @@ export class ApiServer {
|
|||||||
* 加载所有的controller
|
* 加载所有的controller
|
||||||
*/
|
*/
|
||||||
initControllers() {
|
initControllers() {
|
||||||
logger.info('Bootstrap controllers...')
|
logger.info("Bootstrap controllers...");
|
||||||
const controllers = join(__dirname, './controllers')
|
const controllers = join(__dirname, "./controllers");
|
||||||
fs.readdirSync(controllers)
|
fs.readdirSync(controllers)
|
||||||
.filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/))
|
.filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/))
|
||||||
.forEach((file: any) => {
|
.forEach((file: any) => {
|
||||||
// logger.log(file);
|
// logger.log(file);
|
||||||
return require(join(controllers, file))
|
return require(join(controllers, file));
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initSchedules() {}
|
initSchedules() {}
|
||||||
|
|
||||||
|
initServcers() {
|
||||||
|
new DiscordSvr().init();
|
||||||
|
}
|
||||||
|
|
||||||
async connectDB() {
|
async connectDB() {
|
||||||
const options: ConnectOptions = {
|
const options: ConnectOptions = {
|
||||||
minPoolSize: 5,
|
minPoolSize: 5,
|
||||||
maxPoolSize: 10,
|
maxPoolSize: 10,
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
keepAliveInitialDelay: 300000,
|
keepAliveInitialDelay: 300000,
|
||||||
}
|
};
|
||||||
const uri = config.db_main
|
const uri = config.db_main;
|
||||||
logger.info(`connect to ${uri} ...`)
|
logger.info(`connect to ${uri} ...`);
|
||||||
try {
|
try {
|
||||||
// await mongoose.createConnection(uri, options)
|
// await mongoose.createConnection(uri, options)
|
||||||
await mongoose.connect(uri, options)
|
await mongoose.connect(uri, options);
|
||||||
logger.log('DB Connected')
|
logger.log("DB Connected");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.log(`DB Connection Error: ${err.message}`)
|
logger.log(`DB Connection Error: ${err.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private setErrHandler() {
|
private setErrHandler() {
|
||||||
this.server.setNotFoundHandler(function (
|
this.server.setNotFoundHandler(function (
|
||||||
request: any,
|
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' })
|
reply.send({ errcode: 404, errmsg: "page not found" });
|
||||||
})
|
});
|
||||||
this.server.setErrorHandler(function (error: FastifyError, request: FastifyRequest, reply: FastifyReply) {
|
this.server.setErrorHandler(function (
|
||||||
let statusCode = (error && error.statusCode) || 100
|
error: FastifyError,
|
||||||
|
request: FastifyRequest,
|
||||||
|
reply: FastifyReply
|
||||||
|
) {
|
||||||
|
let statusCode = (error && error.statusCode) || 100;
|
||||||
if (statusCode >= 500) {
|
if (statusCode >= 500) {
|
||||||
logger.error(error)
|
logger.error(error);
|
||||||
} else if (statusCode >= 400) {
|
} else if (statusCode >= 400) {
|
||||||
logger.info(error)
|
logger.info(error);
|
||||||
} else {
|
} else {
|
||||||
logger.error(error)
|
logger.error(error);
|
||||||
}
|
}
|
||||||
reply.code(200).send({
|
reply.code(200).send({
|
||||||
errcode: statusCode,
|
errcode: statusCode,
|
||||||
errmsg: error ? error.message : 'unknown error',
|
errmsg: error ? error.message : "unknown error",
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 格式化接口返回数据, 统一封装成如下格式
|
* 格式化接口返回数据, 统一封装成如下格式
|
||||||
@ -137,40 +160,47 @@ export class ApiServer {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private setFormatSend() {
|
private setFormatSend() {
|
||||||
this.server.addHook('preSerialization', async (request: FastifyRequest, reply: FastifyReply, payload) => {
|
this.server.addHook(
|
||||||
reply.header('X-Powered-By', 'PHP/5.4.16')
|
"preSerialization",
|
||||||
// @ts-ignore
|
async (request: FastifyRequest, reply: FastifyReply, payload) => {
|
||||||
if (!payload.errcode) {
|
reply.header("X-Powered-By", "PHP/5.4.16");
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (payload.direct) {
|
if (!payload.errcode) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
delete payload.direct
|
if (payload.direct) {
|
||||||
return payload
|
// @ts-ignore
|
||||||
}
|
delete payload.direct;
|
||||||
payload = {
|
return payload;
|
||||||
errcode: 0,
|
}
|
||||||
data: payload,
|
payload = {
|
||||||
|
errcode: 0,
|
||||||
|
data: payload,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return payload;
|
||||||
}
|
}
|
||||||
return payload
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
public async start() {
|
public async start() {
|
||||||
let self = this
|
let self = this;
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
await self.connectDB()
|
await self.connectDB();
|
||||||
self.initControllers()
|
self.initControllers();
|
||||||
self.registerRouter()
|
self.registerRouter();
|
||||||
self.setErrHandler()
|
self.setErrHandler();
|
||||||
self.setFormatSend()
|
self.setFormatSend();
|
||||||
self.initSchedules()
|
self.initSchedules();
|
||||||
this.server.listen({ port: config.api.port, host: config.api.host }, (err: any, address: any) => {
|
self.initServcers();
|
||||||
if (err) {
|
this.server.listen(
|
||||||
logger.log(err)
|
{ port: config.api.port, host: config.api.host },
|
||||||
process.exit(0)
|
(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 { ZError } from "common/ZError";
|
||||||
import { role, router } from "decorators/router";
|
import { role, router } from "decorators/router";
|
||||||
import logger from "logger/logger";
|
import logger from "logger/logger";
|
||||||
import { exchangeDiscrodCodeForToken, userInfo } from "services/discord.svr";
|
import {
|
||||||
|
DiscordSvr,
|
||||||
|
exchangeDiscrodCodeForToken,
|
||||||
|
userInfo,
|
||||||
|
} from "services/discord.svr";
|
||||||
|
|
||||||
class DiscordController extends BaseController {
|
class DiscordController extends BaseController {
|
||||||
@role(ROLE_ANON)
|
@role(ROLE_ANON)
|
||||||
@ -14,9 +18,19 @@ class DiscordController extends BaseController {
|
|||||||
if (code) {
|
if (code) {
|
||||||
access_token = await exchangeDiscrodCodeForToken(code);
|
access_token = await exchangeDiscrodCodeForToken(code);
|
||||||
let uinfo = await userInfo(access_token);
|
let uinfo = await userInfo(access_token);
|
||||||
|
console.log(uinfo);
|
||||||
return res.view("/templates/discord_redirect.ejs");
|
return res.view("/templates/discord_redirect.ejs");
|
||||||
} else {
|
} else {
|
||||||
return res.view("/templates/discord_redirect.ejs");
|
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) {
|
export async function exchangeDiscrodCodeForToken(code: string) {
|
||||||
const clientId = process.env.DISCORD_CLIENT_ID;
|
const clientId = process.env.DISCORD_CLIENT_ID;
|
||||||
const clientSecret = process.env.DISCORD_CLIENT_SECRET;
|
const clientSecret = process.env.DISCORD_CLIENT_SECRET;
|
||||||
@ -34,3 +38,29 @@ export async function userInfo(token: string) {
|
|||||||
console.log(data);
|
console.log(data);
|
||||||
return 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