summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/endpoints
diff options
context:
space:
mode:
authorMar0xy <marie@kaifa.ch>2023-10-18 13:34:16 +0200
committerMar0xy <marie@kaifa.ch>2023-10-18 13:34:16 +0200
commita4a1b8bb8b9db72e7be45bf44fd19b36fa8e81f4 (patch)
tree8ad917254da2ffa51d9e58c8dd50dbb974a2ce6a /packages/backend/src/server/api/endpoints
parentfix: default for bottrending in model (diff)
downloadsharkey-a4a1b8bb8b9db72e7be45bf44fd19b36fa8e81f4.tar.gz
sharkey-a4a1b8bb8b9db72e7be45bf44fd19b36fa8e81f4.tar.bz2
sharkey-a4a1b8bb8b9db72e7be45bf44fd19b36fa8e81f4.zip
add: isSilenced handling to user and timeline
Diffstat (limited to 'packages/backend/src/server/api/endpoints')
-rw-r--r--packages/backend/src/server/api/endpoints/admin/show-user.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/admin/silence-user.ts46
-rw-r--r--packages/backend/src/server/api/endpoints/admin/unsilence-user.ts39
-rw-r--r--packages/backend/src/server/api/endpoints/notes/global-timeline.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts3
-rw-r--r--packages/backend/src/server/api/endpoints/notes/local-timeline.ts5
-rw-r--r--packages/backend/src/server/api/endpoints/notes/timeline.ts1
7 files changed, 108 insertions, 3 deletions
diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts
index f550c4fd28..7fe70fa026 100644
--- a/packages/backend/src/server/api/endpoints/admin/show-user.ts
+++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts
@@ -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)) {
diff --git a/packages/backend/src/server/api/endpoints/admin/silence-user.ts b/packages/backend/src/server/api/endpoints/admin/silence-user.ts
new file mode 100644
index 0000000000..ed1141da43
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/admin/silence-user.ts
@@ -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,
+ });
+ });
+ }
+}
diff --git a/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts b/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts
new file mode 100644
index 0000000000..7cfedca7de
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts
@@ -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,
+ });
+ });
+ }
+}
diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
index 4a8505fe54..5827577543 100644
--- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
@@ -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) {
diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
index cb3a5ae73b..9417074010 100644
--- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -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;
});
diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
index 0f7a2d31f6..ea24d2643e 100644
--- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
@@ -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;
});
diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts
index 8c068adf94..e8bae286ef 100644
--- a/packages/backend/src/server/api/endpoints/notes/timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts
@@ -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;
});