diff --git a/packages/core/resourcer/package.json b/packages/core/resourcer/package.json index daf5099c16..7fd3627c09 100644 --- a/packages/core/resourcer/package.json +++ b/packages/core/resourcer/package.json @@ -12,6 +12,7 @@ } ], "dependencies": { + "@nocobase/utils": "0.7.4-alpha.7", "deepmerge": "^4.2.2", "koa-compose": "^4.1.0", "lodash": "^4.17.21", diff --git a/packages/core/resourcer/src/action.ts b/packages/core/resourcer/src/action.ts index 398fe3f244..569df6ac95 100644 --- a/packages/core/resourcer/src/action.ts +++ b/packages/core/resourcer/src/action.ts @@ -1,7 +1,7 @@ import _ from 'lodash'; import compose from 'koa-compose'; +import { requireModule } from '@nocobase/utils'; import Resource from './resource'; -import { requireModule } from './utils'; import { HandlerType } from './resourcer'; import Middleware, { MiddlewareType } from './middleware'; import { assign, MergeStrategies } from './assign'; diff --git a/packages/core/resourcer/src/middleware.ts b/packages/core/resourcer/src/middleware.ts index 1fe8d2fa20..a6c3798134 100644 --- a/packages/core/resourcer/src/middleware.ts +++ b/packages/core/resourcer/src/middleware.ts @@ -1,7 +1,7 @@ import compose from 'koa-compose'; +import { requireModule } from '@nocobase/utils'; import { ActionName } from './action'; import { HandlerType } from './resourcer'; -import { requireModule } from './utils'; export type MiddlewareType = string | string[] | HandlerType | HandlerType[] | MiddlewareOptions | MiddlewareOptions[]; @@ -23,6 +23,7 @@ export interface MiddlewareOptions { export class Middleware { protected options: MiddlewareOptions; + private middlewares: HandlerType[] = []; constructor(options: MiddlewareOptions | Function) { options = requireModule(options); @@ -38,7 +39,15 @@ export class Middleware { if (typeof handler !== 'function') { throw new Error('Handler must be a function!'); } - return handler; + return (ctx, next) => compose([handler, ...this.middlewares])(ctx, next); + } + + use(middleware: HandlerType) { + this.middlewares.push(middleware); + } + + disuse(middleware: HandlerType) { + this.middlewares.splice(this.middlewares.indexOf(middleware), 1); } canAccess(name: ActionName) { @@ -75,22 +84,6 @@ export class Middleware { export default Middleware; -export class MiddlewareManager { - protected middlewares: HandlerType[] = []; - - compose() { - return (ctx, next) => compose(this.middlewares)(ctx, next); - } - - use(middleware: HandlerType) { - this.middlewares.push(middleware); - } - - unuse(middleware: HandlerType) { - this.middlewares.splice(this.middlewares.indexOf(middleware), 1); - } -} - export function branch( map: { [key: string]: HandlerType; diff --git a/packages/core/resourcer/src/resourcer.ts b/packages/core/resourcer/src/resourcer.ts index 1d174eae09..7e5ac17a17 100644 --- a/packages/core/resourcer/src/resourcer.ts +++ b/packages/core/resourcer/src/resourcer.ts @@ -2,9 +2,10 @@ import glob from 'glob'; import compose from 'koa-compose'; import _ from 'lodash'; import { pathToRegexp } from 'path-to-regexp'; +import { requireModule } from '@nocobase/utils'; import Action, { ActionName } from './action'; import Resource, { ResourceOptions } from './resource'; -import { getNameByParams, ParsedParams, parseQuery, parseRequest, requireModule } from './utils'; +import { getNameByParams, ParsedParams, parseQuery, parseRequest } from './utils'; export interface ResourcerContext { resourcer?: Resourcer; diff --git a/packages/core/resourcer/src/utils.ts b/packages/core/resourcer/src/utils.ts index 45d6aee361..2b6baff7c4 100644 --- a/packages/core/resourcer/src/utils.ts +++ b/packages/core/resourcer/src/utils.ts @@ -183,16 +183,6 @@ export function parseRequest(request: ParseRequest, options: ParseOptions = {}): return params; } -export function requireModule(module: any) { - if (typeof module === 'string') { - module = require(module); - } - if (typeof module !== 'object') { - return module; - } - return module.__esModule ? module.default : module; -} - export function parseQuery(input: string): any { // 自带 query 处理的不太给力,需要用 qs 转一下 const query = qs.parse(input, { diff --git a/packages/plugins/users/src/middlewares/parseToken.ts b/packages/plugins/users/src/middlewares/parseToken.ts index 8c55f64293..3530761e72 100644 --- a/packages/plugins/users/src/middlewares/parseToken.ts +++ b/packages/plugins/users/src/middlewares/parseToken.ts @@ -1,26 +1,21 @@ import { Context, Next } from '@nocobase/actions'; -import { MiddlewareManager } from '@nocobase/resourcer'; -import UsersPlugin from '../server'; -export function parseToken(options?: { plugin: UsersPlugin }) { - const middleware = new MiddlewareManager(); - middleware.use(async function (ctx: Context, next: Next) { - const user = await findUserByToken(ctx, options.plugin); - if (user) { - ctx.state.currentUser = user; - } - return next(); - }); - return middleware; -} +export async function parseToken(ctx: Context, next: Next) { + const user = await findUserByToken(ctx); + if (user) { + ctx.state.currentUser = user; + } + return next(); +}; -async function findUserByToken(ctx: Context, plugin: UsersPlugin) { +async function findUserByToken(ctx: Context) { const token = ctx.getBearerToken(); if (!token) { return null; } + const { jwtService } = ctx.app.getPlugin('@nocobase/plugin-users'); try { - const { userId } = await plugin.jwtService.decode(token); + const { userId } = await jwtService.decode(token); const collection = ctx.db.getCollection('users'); ctx.state.currentUserAppends = ctx.state.currentUserAppends || []; for (const [, field] of collection.fields) { diff --git a/packages/plugins/users/src/server.ts b/packages/plugins/users/src/server.ts index d556992423..217e308cef 100644 --- a/packages/plugins/users/src/server.ts +++ b/packages/plugins/users/src/server.ts @@ -4,13 +4,13 @@ import parse from 'json-templates'; import { Collection, Op } from '@nocobase/database'; import { Plugin } from '@nocobase/server'; import { Registry } from '@nocobase/utils'; -import { HandlerType, MiddlewareManager } from '@nocobase/resourcer'; +import { HandlerType, Middleware } from '@nocobase/resourcer'; import { namespace } from './'; import * as actions from './actions/users'; import { JwtOptions, JwtService } from './jwt-service'; import { enUS, zhCN } from './locale'; -import * as middlewares from './middlewares'; +import { parseToken } from './middlewares'; import initAuthenticators from './authenticators'; export interface UserPluginConfig { @@ -20,14 +20,14 @@ export interface UserPluginConfig { export default class UsersPlugin extends Plugin { public jwtService: JwtService; - public tokenMiddleware: MiddlewareManager; + public tokenMiddleware: Middleware; public authenticators: Registry = new Registry(); constructor(app, options) { super(app, options); this.jwtService = new JwtService(options?.jwt || {}); - this.tokenMiddleware = middlewares.parseToken({ plugin: this }); + this.tokenMiddleware = new Middleware(parseToken); } async beforeLoad() { @@ -92,7 +92,7 @@ export default class UsersPlugin extends Plugin { this.app.resourcer.registerActionHandler(`users:${key}`, action); } - this.app.resourcer.use(this.tokenMiddleware.compose()); + this.app.resourcer.use(this.tokenMiddleware.getHandler()); const publicActions = ['check', 'signin', 'signup', 'lostpassword', 'resetpassword', 'getUserByResetToken']; const loggedInActions = ['signout', 'updateProfile', 'changePassword'];