refactor(resourcer): combine middleware class (#825)
* refactor(resourcer): combine middleware class * refactor(resourcer): move new middleware to plugin instance
This commit is contained in:
parent
b92f3b3b95
commit
1a9cd78eb8
@ -12,6 +12,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@nocobase/utils": "0.7.4-alpha.7",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"koa-compose": "^4.1.0",
|
"koa-compose": "^4.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
|
import { requireModule } from '@nocobase/utils';
|
||||||
import Resource from './resource';
|
import Resource from './resource';
|
||||||
import { requireModule } from './utils';
|
|
||||||
import { HandlerType } from './resourcer';
|
import { HandlerType } from './resourcer';
|
||||||
import Middleware, { MiddlewareType } from './middleware';
|
import Middleware, { MiddlewareType } from './middleware';
|
||||||
import { assign, MergeStrategies } from './assign';
|
import { assign, MergeStrategies } from './assign';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
|
import { requireModule } from '@nocobase/utils';
|
||||||
import { ActionName } from './action';
|
import { ActionName } from './action';
|
||||||
import { HandlerType } from './resourcer';
|
import { HandlerType } from './resourcer';
|
||||||
import { requireModule } from './utils';
|
|
||||||
|
|
||||||
export type MiddlewareType = string | string[] | HandlerType | HandlerType[] | MiddlewareOptions | MiddlewareOptions[];
|
export type MiddlewareType = string | string[] | HandlerType | HandlerType[] | MiddlewareOptions | MiddlewareOptions[];
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ export interface MiddlewareOptions {
|
|||||||
|
|
||||||
export class Middleware {
|
export class Middleware {
|
||||||
protected options: MiddlewareOptions;
|
protected options: MiddlewareOptions;
|
||||||
|
private middlewares: HandlerType[] = [];
|
||||||
|
|
||||||
constructor(options: MiddlewareOptions | Function) {
|
constructor(options: MiddlewareOptions | Function) {
|
||||||
options = requireModule(options);
|
options = requireModule(options);
|
||||||
@ -38,7 +39,15 @@ export class Middleware {
|
|||||||
if (typeof handler !== 'function') {
|
if (typeof handler !== 'function') {
|
||||||
throw new Error('Handler must be a 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) {
|
canAccess(name: ActionName) {
|
||||||
@ -75,22 +84,6 @@ export class Middleware {
|
|||||||
|
|
||||||
export default 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(
|
export function branch(
|
||||||
map: {
|
map: {
|
||||||
[key: string]: HandlerType;
|
[key: string]: HandlerType;
|
||||||
|
@ -2,9 +2,10 @@ import glob from 'glob';
|
|||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { pathToRegexp } from 'path-to-regexp';
|
import { pathToRegexp } from 'path-to-regexp';
|
||||||
|
import { requireModule } from '@nocobase/utils';
|
||||||
import Action, { ActionName } from './action';
|
import Action, { ActionName } from './action';
|
||||||
import Resource, { ResourceOptions } from './resource';
|
import Resource, { ResourceOptions } from './resource';
|
||||||
import { getNameByParams, ParsedParams, parseQuery, parseRequest, requireModule } from './utils';
|
import { getNameByParams, ParsedParams, parseQuery, parseRequest } from './utils';
|
||||||
|
|
||||||
export interface ResourcerContext {
|
export interface ResourcerContext {
|
||||||
resourcer?: Resourcer;
|
resourcer?: Resourcer;
|
||||||
|
@ -183,16 +183,6 @@ export function parseRequest(request: ParseRequest, options: ParseOptions = {}):
|
|||||||
return params;
|
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 {
|
export function parseQuery(input: string): any {
|
||||||
// 自带 query 处理的不太给力,需要用 qs 转一下
|
// 自带 query 处理的不太给力,需要用 qs 转一下
|
||||||
const query = qs.parse(input, {
|
const query = qs.parse(input, {
|
||||||
|
@ -1,26 +1,21 @@
|
|||||||
import { Context, Next } from '@nocobase/actions';
|
import { Context, Next } from '@nocobase/actions';
|
||||||
import { MiddlewareManager } from '@nocobase/resourcer';
|
|
||||||
import UsersPlugin from '../server';
|
|
||||||
|
|
||||||
export function parseToken(options?: { plugin: UsersPlugin }) {
|
export async function parseToken(ctx: Context, next: Next) {
|
||||||
const middleware = new MiddlewareManager();
|
const user = await findUserByToken(ctx);
|
||||||
middleware.use(async function (ctx: Context, next: Next) {
|
if (user) {
|
||||||
const user = await findUserByToken(ctx, options.plugin);
|
ctx.state.currentUser = user;
|
||||||
if (user) {
|
}
|
||||||
ctx.state.currentUser = user;
|
return next();
|
||||||
}
|
};
|
||||||
return next();
|
|
||||||
});
|
|
||||||
return middleware;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function findUserByToken(ctx: Context, plugin: UsersPlugin) {
|
async function findUserByToken(ctx: Context) {
|
||||||
const token = ctx.getBearerToken();
|
const token = ctx.getBearerToken();
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
const { jwtService } = ctx.app.getPlugin('@nocobase/plugin-users');
|
||||||
try {
|
try {
|
||||||
const { userId } = await plugin.jwtService.decode(token);
|
const { userId } = await jwtService.decode(token);
|
||||||
const collection = ctx.db.getCollection('users');
|
const collection = ctx.db.getCollection('users');
|
||||||
ctx.state.currentUserAppends = ctx.state.currentUserAppends || [];
|
ctx.state.currentUserAppends = ctx.state.currentUserAppends || [];
|
||||||
for (const [, field] of collection.fields) {
|
for (const [, field] of collection.fields) {
|
||||||
|
@ -4,13 +4,13 @@ import parse from 'json-templates';
|
|||||||
import { Collection, Op } from '@nocobase/database';
|
import { Collection, Op } from '@nocobase/database';
|
||||||
import { Plugin } from '@nocobase/server';
|
import { Plugin } from '@nocobase/server';
|
||||||
import { Registry } from '@nocobase/utils';
|
import { Registry } from '@nocobase/utils';
|
||||||
import { HandlerType, MiddlewareManager } from '@nocobase/resourcer';
|
import { HandlerType, Middleware } from '@nocobase/resourcer';
|
||||||
|
|
||||||
import { namespace } from './';
|
import { namespace } from './';
|
||||||
import * as actions from './actions/users';
|
import * as actions from './actions/users';
|
||||||
import { JwtOptions, JwtService } from './jwt-service';
|
import { JwtOptions, JwtService } from './jwt-service';
|
||||||
import { enUS, zhCN } from './locale';
|
import { enUS, zhCN } from './locale';
|
||||||
import * as middlewares from './middlewares';
|
import { parseToken } from './middlewares';
|
||||||
import initAuthenticators from './authenticators';
|
import initAuthenticators from './authenticators';
|
||||||
|
|
||||||
export interface UserPluginConfig {
|
export interface UserPluginConfig {
|
||||||
@ -20,14 +20,14 @@ export interface UserPluginConfig {
|
|||||||
export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||||
public jwtService: JwtService;
|
public jwtService: JwtService;
|
||||||
|
|
||||||
public tokenMiddleware: MiddlewareManager;
|
public tokenMiddleware: Middleware;
|
||||||
|
|
||||||
public authenticators: Registry<HandlerType> = new Registry();
|
public authenticators: Registry<HandlerType> = new Registry();
|
||||||
|
|
||||||
constructor(app, options) {
|
constructor(app, options) {
|
||||||
super(app, options);
|
super(app, options);
|
||||||
this.jwtService = new JwtService(options?.jwt || {});
|
this.jwtService = new JwtService(options?.jwt || {});
|
||||||
this.tokenMiddleware = middlewares.parseToken({ plugin: this });
|
this.tokenMiddleware = new Middleware(parseToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
async beforeLoad() {
|
async beforeLoad() {
|
||||||
@ -92,7 +92,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
|||||||
this.app.resourcer.registerActionHandler(`users:${key}`, action);
|
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 publicActions = ['check', 'signin', 'signup', 'lostpassword', 'resetpassword', 'getUserByResetToken'];
|
||||||
const loggedInActions = ['signout', 'updateProfile', 'changePassword'];
|
const loggedInActions = ['signout', 'updateProfile', 'changePassword'];
|
||||||
|
Loading…
Reference in New Issue
Block a user