88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import { FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify'
|
|
import fastifyPlugin from 'fastify-plugin'
|
|
import { ActivityInfo, ActivityInfoClass } from 'models/ActivityInfo'
|
|
import { ActivityUser, ActivityUserClass } from 'models/ActivityUser'
|
|
import { ROLE_ANON } from 'zutils'
|
|
import { DocumentType } from '@typegoose/typegoose'
|
|
import { ReadOnlyCache } from 'common/ReadOnlyCache'
|
|
import { ACTIVITY_NAME } from 'common/Constants'
|
|
|
|
declare module 'fastify' {
|
|
interface FastifyRequest {
|
|
roles?: string[]
|
|
user?: DocumentType<ActivityUserClass>
|
|
activity?: DocumentType<ActivityInfoClass>
|
|
token?: string
|
|
}
|
|
interface FastifyInstance {
|
|
apiAuth: (request: FastifyRequest, reply: FastifyReply) => {}
|
|
}
|
|
}
|
|
|
|
export interface ApiAuthOptions {
|
|
secret: string
|
|
expiresIn: string
|
|
}
|
|
const checkEndList = [
|
|
'/api/activity/upload_invite_code',
|
|
'/api/chest/enhance',
|
|
'/api/chest/open',
|
|
'/api/user/checkin',
|
|
'/api/user/checkin/claim',
|
|
'/api/user/checkin/claim_seq',
|
|
'/api/game/pre_step',
|
|
'/api/game/step',
|
|
'/api/ingame/claim',
|
|
'/api/ingame/draw',
|
|
'/api/partner/claim',
|
|
'/api/tasks/begin_task',
|
|
'/api/tasks/check_task',
|
|
'/api/tasks/claim',
|
|
'/api/voucher/claim',
|
|
]
|
|
const checkEndSet = new Set(checkEndList)
|
|
|
|
const apiAuthPlugin: FastifyPluginAsync<ApiAuthOptions> = async function (fastify, opts) {
|
|
fastify.register(require('@fastify/jwt'), {
|
|
secret: opts.secret,
|
|
sign: { expiresIn: opts.expiresIn },
|
|
})
|
|
// 只有路由配置的role为anon才不需要过滤
|
|
fastify.decorate('apiAuth', async function (request: FastifyRequest, reply: FastifyReply) {
|
|
let activity = new ReadOnlyCache().getData(ACTIVITY_NAME)
|
|
if (!activity) {
|
|
activity = await ActivityInfo.findById(ACTIVITY_NAME)
|
|
if (activity) {
|
|
new ReadOnlyCache().setData(ACTIVITY_NAME, activity)
|
|
}
|
|
}
|
|
if (activity) {
|
|
if (checkEndSet.has(request.url) && Date.now() > activity.endTime) {
|
|
return reply.send({ errcode: 90, errmsg: 'activity is end' })
|
|
}
|
|
request.activity = activity
|
|
}
|
|
if (!request.roles || request.roles.indexOf(ROLE_ANON) == -1 || request.token) {
|
|
try {
|
|
if (!request.token) {
|
|
return reply.send({ errcode: 11, errmsg: 'need login' })
|
|
}
|
|
//@ts-ignore
|
|
const data = this.jwt.verify(request.token)
|
|
if (!data || !data.id) {
|
|
return reply.send({ errcode: 10, errmsg: 'need login' })
|
|
}
|
|
let account = await ActivityUser.findById(data.id)
|
|
if (!account) {
|
|
return reply.send({ errcode: 10, errmsg: 'need login' })
|
|
}
|
|
request.user = account
|
|
} catch (err) {
|
|
return reply.send({ errcode: 401, errmsg: 'need auth' })
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
export default fastifyPlugin(apiAuthPlugin, '4.x')
|