task-svr/src/plugins/apiauth.ts
2024-01-18 19:13:11 +08:00

61 lines
1.9 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'
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 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) {
if (!request.roles || request.roles.indexOf(ROLE_ANON) == -1) {
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
if (account.activity) {
let activity = await ActivityInfo.findById(account.activity)
if (activity) {
request.activity = activity
}
}
} catch (err) {
return reply.send({ errcode: 401, errmsg: 'need auth' })
}
}
})
}
export default fastifyPlugin(apiAuthPlugin, '4.x')