add: isSilenced handling to user and timeline
This commit is contained in:
parent
95b2689a21
commit
a4a1b8bb8b
19 changed files with 171 additions and 11 deletions
|
|
@ -58,7 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
|
||||
const isModerator = await this.roleService.isModerator(user);
|
||||
const isSilenced = !(await this.roleService.getUserPolicies(user.id)).canPublicNote;
|
||||
const isSilenced = user.isSilenced || !(await this.roleService.getUserPolicies(user.id)).canPublicNote;
|
||||
|
||||
const _me = await this.usersRepository.findOneByOrFail({ id: me.id });
|
||||
if (!await this.roleService.isAdministrator(_me) && await this.roleService.isAdministrator(user)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const user = await this.usersRepository.findOneBy({ id: ps.userId });
|
||||
|
||||
if (user == null) {
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (await this.roleService.isModerator(user)) {
|
||||
throw new Error('cannot silence moderator account');
|
||||
}
|
||||
|
||||
await this.usersRepository.update(user.id, {
|
||||
isSilenced: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const user = await this.usersRepository.findOneBy({ id: ps.userId });
|
||||
|
||||
if (user == null) {
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await this.usersRepository.update(user.id, {
|
||||
isSilenced: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['notes'],
|
||||
|
|
@ -61,6 +62,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private queryService: QueryService,
|
||||
private roleService: RoleService,
|
||||
private activeUsersChart: ActiveUsersChart,
|
||||
private cacheService: CacheService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const policies = await this.roleService.getUserPolicies(me ? me.id : null);
|
||||
|
|
@ -68,6 +70,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.gtlDisabled);
|
||||
}
|
||||
|
||||
const [
|
||||
followings,
|
||||
] = me ? await Promise.all([
|
||||
this.cacheService.userFollowingsCache.fetch(me.id),
|
||||
]) : [undefined];
|
||||
|
||||
//#region Construct query
|
||||
const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'),
|
||||
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||
|
|
@ -92,7 +100,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (!ps.withBots) query.andWhere('user.isBot = FALSE');
|
||||
//#endregion
|
||||
|
||||
const timeline = await query.limit(ps.limit).getMany();
|
||||
let timeline = await query.limit(ps.limit).getMany();
|
||||
|
||||
timeline = timeline.filter(note => {
|
||||
if (note.user?.isSilenced && me && followings && note.userId !== me.id && !followings[note.userId]) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
process.nextTick(() => {
|
||||
if (me) {
|
||||
|
|
|
|||
|
|
@ -87,10 +87,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
|
||||
const [
|
||||
followings,
|
||||
userIdsWhoMeMuting,
|
||||
userIdsWhoMeMutingRenotes,
|
||||
userIdsWhoBlockingMe,
|
||||
] = await Promise.all([
|
||||
this.cacheService.userFollowingsCache.fetch(me.id),
|
||||
this.cacheService.userMutingsCache.fetch(me.id),
|
||||
this.cacheService.renoteMutingsCache.fetch(me.id),
|
||||
this.cacheService.userBlockedCache.fetch(me.id),
|
||||
|
|
@ -151,6 +153,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (ps.withRenotes === false) return false;
|
||||
}
|
||||
}
|
||||
if (note.user?.isSilenced && note.userId !== me.id && !followings[note.userId]) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -83,14 +83,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
|
||||
const [
|
||||
followings,
|
||||
userIdsWhoMeMuting,
|
||||
userIdsWhoMeMutingRenotes,
|
||||
userIdsWhoBlockingMe,
|
||||
] = me ? await Promise.all([
|
||||
this.cacheService.userFollowingsCache.fetch(me.id),
|
||||
this.cacheService.userMutingsCache.fetch(me.id),
|
||||
this.cacheService.renoteMutingsCache.fetch(me.id),
|
||||
this.cacheService.userBlockedCache.fetch(me.id),
|
||||
]) : [new Set<string>(), new Set<string>(), new Set<string>()];
|
||||
]) : [undefined, new Set<string>(), new Set<string>(), new Set<string>()];
|
||||
|
||||
let noteIds: string[];
|
||||
|
||||
|
|
@ -137,6 +139,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (ps.withRenotes === false) return false;
|
||||
}
|
||||
}
|
||||
if (note.user?.isSilenced && me && followings && note.userId !== me.id && !followings[note.userId]) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (note.reply && note.reply.visibility === 'followers') {
|
||||
if (!Object.hasOwn(followings, note.reply.userId)) return false;
|
||||
}
|
||||
if (note.user?.isSilenced && note.userId !== me.id && !followings[note.userId]) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue