Context not working in decorator after await action
Nyanng opened this issue · comments
I'm using Typescript, Koa version is 2.13.4, Node js is 16.11.1
First of all, I am using decorator to replace middleware.
So I wrote down below code.
Decorator:
// hasPermission decorator
export function hasPermission(
type: PermissionType,
action: PermissionAction,
): MethodDecorator {
return function (
target: Object,
props: string | symbol,
descriptor: PropertyDescriptor,
) {
let original = descriptor.value;
descriptor.value = async function (...args: [HttpContext, ...any]) {
const ctx = args[0];
const hasPermission = await ctx.state.user?.hasPermission(type, action);
if (hasPermission) return await original.apply(this, args);
else ctx.body = ctx.__('error.needPermission');
};
};
}
// hasRole decorator
export function hasRole(role: UserRole | UserRole[]) {
return function (target: any, props: string, descriptor: PropertyDescriptor) {
let original = descriptor.value;
descriptor.value = function (...args: [HttpContext, ...any]) {
const ctx = args[0];
if (ctx.state.user?.hasRole(role)) return original.apply(this, args);
else ctx.body = ctx.__('error.needRole');
};
};
}
Controller:
@hasRole([UserRole.Administrator, UserRole.Supporter])
@hasPermission(PermissionType.Shop, PermissionAction.Read)
async all(ctx: HttpContext) {
const shops = await Shop.find({
select: ['id', 'name', 'domain', 'endedAt'],
});
ctx.body = shops;
}
hasRole has no problem, but hasPermission does.
I want to check user has permission. and it is saved on database.
To check it, I have to using async/await function to get data.
But, a matter occured in this part.
in (1), context works perfectly, however (2) doesn't.
in (2), I can't manipulate any response - status code, returning body and so on.
due to this reason, if user wasn't permitted, just returning 404 error.
I don't understand why can't change context after await action.
// hasPermission
descriptor.value = async function (...args: [HttpContext, ...any]) {
const ctx = args[0];
// (1) ctx.body = 'in here, ctx works!'
const hasPermission = await ctx.state.user?.hasPermission(type, action);
// (2) ctx.body = 'in here, ctx doesn't work!'
if (hasPermission) return await original.apply(this, args);
else ctx.body = ctx.__('error.needPermission'); // Thus, This code doesn't work. only return default error (404).
};
How can I resolve this problem?
Please understand that my English is short and Thanks for reading.
I resolved. next() in middleware is not set 'await', so context doesn't work.