add: isSilenced handling to user and timeline

This commit is contained in:
Mar0xy 2023-10-18 13:34:16 +02:00
parent 95b2689a21
commit a4a1b8bb8b
No known key found for this signature in database
GPG key ID: 56569BBE47D2C828
19 changed files with 171 additions and 11 deletions

View file

@ -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)) {

View file

@ -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,
});
});
}
}

View file

@ -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,
});
});
}
}

View file

@ -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) {

View file

@ -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;
});

View file

@ -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;
});

View file

@ -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;
});