Я застрял в интересной ситуации. Мне нужно получить доступ к контексту области запроса от пользовательского декоратора. Вариант использования без авторизации:
@injectable()
export class CreateUserUseCase implements ICreateUserUseCase {
@inject(Types.IdentityDBContext) private _identityDBContext: IIdentityDBContext;
public async execute(inputData: DSCreateUserInputData): Promise<void> {
const {
email: emailValue,
name: nameValue,
profileURL: profileURLValue,
roleID: roleIDValue,
userID: userIDValue
} = inputData;
// Request body to value objects here ....
const userResult = User.createUser(
{
email,
name,
profileURL,
auditDate,
auditUser
},
userID
);
const user: User = userResult.getValue() as User;
await this._identityDBContext.startTransaction();
try {
await this._identityDBContext.userRepository.saveUser(user, role);
} catch (error) {
await this._identityDBContext.rollbackTransaction();
throw error;
}
await this._identityDBContext.commitTransaction();
}
}
Я не могу найти способ найти точки между областью запроса и декоратором. Каким-то образом мне нужно добавить сквозную функциональность, чтобы проверить права пользователей из контекста запроса (пользователь проходит проверку подлинности на уровне инфраструктуры (в контроллере)). Я не хочу передавать этот контекст непосредственно в качестве параметра метода, поскольку я не хочу избегать влияния контракта интерфейса (но это единственный способ, которым я придумал):
@injectable()
export class CreateUserUseCase implements ICreateUserUseCase {
@inject(Types.IdentityDBContext) private _identityDBContext: IIdentityDBContext;
@Permissions([PermissionType.CREATE_USER])
public async execute(inputData: DSCreateUserInputData): Promise<void> {
Есть ли какой-нибудь мягкий способ сделать это?
PS Возможное решение для декоратора:
export function Permissions(roles: PermissionType[]): any {
return function (...args: [Record<string, any>, string, PropertyDescriptor]): any {
if (args.length === 3 && typeof args[2] !== 'number') {
const [, , propertyDescriptor]: [Record<string, any>, string, PropertyDescriptor] = args;
const original = propertyDescriptor.value;
propertyDescriptor.value = function (...args1: any[]): any {
// This one
const systemUserService: SystemUserService = ?
const userHasPermissions = systemUserService.currentSystemUser.systemUserRole.hasPermissions(roles);
if (userHasPermissions) {
const result = original.apply(this, args1);
return result;
}
throw Error('Unauthorized');
};
return propertyDescriptor;
}
throw new Error('Not a valid decorator');
};
};