@@ -7,6 +7,9 @@ import type { CacheableLocalUser, CacheableUser, ILocalUser, User } from '@/mode
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { UserCacheService } from '@/core/UserCacheService.js';
|
||||
import { RoleCondFormulaValue } from '@/models/entities/Role.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
export type RoleOptions = {
|
||||
@@ -44,6 +47,8 @@ export class RoleService implements OnApplicationShutdown {
|
||||
private roleAssignmentsRepository: RoleAssignmentsRepository,
|
||||
|
||||
private metaService: MetaService,
|
||||
private userCacheService: UserCacheService,
|
||||
private userEntityService: UserEntityService,
|
||||
) {
|
||||
//this.onMessage = this.onMessage.bind(this);
|
||||
|
||||
@@ -111,12 +116,49 @@ export class RoleService implements OnApplicationShutdown {
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private evalCond(user: User, value: RoleCondFormulaValue): boolean {
|
||||
try {
|
||||
switch (value.type) {
|
||||
case 'and': {
|
||||
return value.values.every(v => this.evalCond(user, v));
|
||||
}
|
||||
case 'or': {
|
||||
return value.values.some(v => this.evalCond(user, v));
|
||||
}
|
||||
case 'not': {
|
||||
return !this.evalCond(user, value.value);
|
||||
}
|
||||
case 'isLocal': {
|
||||
return this.userEntityService.isLocalUser(user);
|
||||
}
|
||||
case 'isRemote': {
|
||||
return this.userEntityService.isRemoteUser(user);
|
||||
}
|
||||
case 'createdLessThan': {
|
||||
return user.createdAt.getTime() > (Date.now() - (value.sec * 1000));
|
||||
}
|
||||
case 'createdMoreThan': {
|
||||
return user.createdAt.getTime() < (Date.now() - (value.sec * 1000));
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
// TODO: log error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async getUserRoles(userId: User['id']) {
|
||||
const assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId }));
|
||||
const assignedRoleIds = assigns.map(x => x.roleId);
|
||||
const roles = await this.rolesCache.fetch(null, () => this.rolesRepository.findBy({}));
|
||||
return roles.filter(r => assignedRoleIds.includes(r.id));
|
||||
const assignedRoles = roles.filter(r => assignedRoleIds.includes(r.id));
|
||||
const user = roles.some(r => r.target === 'conditional') ? await this.userCacheService.findById(userId) : null;
|
||||
const matchedCondRoles = roles.filter(r => r.target === 'conditional' && this.evalCond(user!, r.condFormula));
|
||||
return [...assignedRoles, ...matchedCondRoles];
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
Reference in New Issue
Block a user