61 lines
1.9 KiB
TypeScript
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')
|