Skip to content
Snippets Groups Projects
Unverified Commit 57283502 authored by Johann150's avatar Johann150 Committed by GitHub
Browse files

fix: always respect instance mutes (#8854)

* fix: muted user query also checks instances

This way it can be ensured that the instance mute is used everywhere it
is required without checking the whole codebase again. Muted users and
muted instances should be used together anyways.

* fix lint
parent e3461f1b
No related branches found
No related tags found
No related merge requests found
import { User } from '@/models/entities/user.js';
import { id } from '@/models/id.js';
import { UserProfiles } from '@/models/index.js';
import { SelectQueryBuilder, Brackets } from 'typeorm';
function createMutesQuery(id: string) {
return UserProfiles.createQueryBuilder('user_profile')
.select('user_profile.mutedInstances')
.where('user_profile.userId = :muterId', { muterId: id });
}
export function generateMutedInstanceQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const mutingQuery = createMutesQuery(me.id);
q
.andWhere(new Brackets(qb => { qb
.andWhere('note.userHost IS NULL')
.orWhere(`NOT((${ mutingQuery.getQuery() })::jsonb ? note.userHost)`);
}))
.andWhere(new Brackets(qb => { qb
.where(`note.replyUserHost IS NULL`)
.orWhere(`NOT ((${ mutingQuery.getQuery() })::jsonb ? note.replyUserHost)`);
}))
.andWhere(new Brackets(qb => { qb
.where(`note.renoteUserHost IS NULL`)
.orWhere(`NOT ((${ mutingQuery.getQuery() })::jsonb ? note.renoteUserHost)`);
}));
q.setParameters(mutingQuery.getParameters());
}
export function generateMutedInstanceNotificationQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const mutingQuery = createMutesQuery(me.id);
q.andWhere(new Brackets(qb => { qb
.andWhere('notifier.host IS NULL')
.orWhere(`NOT (( ${mutingQuery.getQuery()} )::jsonb ? notifier.host)`);
}));
q.setParameters(mutingQuery.getParameters());
}
import { User } from '@/models/entities/user.js';
import { Mutings } from '@/models/index.js';
import { SelectQueryBuilder, Brackets } from 'typeorm';
import { User } from '@/models/entities/user.js';
import { Mutings, UserProfiles } from '@/models/index.js';
export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }, exclude?: User) {
const mutingQuery = Mutings.createQueryBuilder('muting')
......@@ -11,21 +11,39 @@ export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: { id: Use
mutingQuery.andWhere('muting.muteeId != :excludeId', { excludeId: exclude.id });
}
const mutingInstanceQuery = UserProfiles.createQueryBuilder('user_profile')
.select('user_profile.mutedInstances')
.where('user_profile.userId = :muterId', { muterId: me.id });
// 投稿の作者をミュートしていない かつ
// 投稿の返信先の作者をミュートしていない かつ
// 投稿の引用元の作者をミュートしていない
q
.andWhere(`note.userId NOT IN (${ mutingQuery.getQuery() })`)
.andWhere(new Brackets(qb => { qb
.where(`note.replyUserId IS NULL`)
.where('note.replyUserId IS NULL')
.orWhere(`note.replyUserId NOT IN (${ mutingQuery.getQuery() })`);
}))
.andWhere(new Brackets(qb => { qb
.where(`note.renoteUserId IS NULL`)
.where('note.renoteUserId IS NULL')
.orWhere(`note.renoteUserId NOT IN (${ mutingQuery.getQuery() })`);
}))
// mute instances
.andWhere(new Brackets(qb => { qb
.andWhere('note.userHost IS NULL')
.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.userHost)`);
}))
.andWhere(new Brackets(qb => { qb
.where('note.replyUserHost IS NULL')
.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.replyUserHost)`);
}))
.andWhere(new Brackets(qb => { qb
.where('note.renoteUserHost IS NULL')
.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.renoteUserHost)`);
}));
q.setParameters(mutingQuery.getParameters());
q.setParameters(mutingInstanceQuery.getParameters());
}
export function generateMutedUserQueryForUsers(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
......@@ -33,8 +51,26 @@ export function generateMutedUserQueryForUsers(q: SelectQueryBuilder<any>, me: {
.select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: me.id });
const mutingInstanceQuery = UserProfiles.createQueryBuilder('user_profile')
.select('user_profile.mutedInstances')
.where('user_profile.userId = :muterId', { muterId: me.id });
q
.andWhere(`user.id NOT IN (${ mutingQuery.getQuery() })`);
.andWhere(`user.id NOT IN (${ mutingQuery.getQuery() })`)
// mute instances
.andWhere(new Brackets(qb => { qb
.andWhere('note.userHost IS NULL')
.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.userHost)`);
}))
.andWhere(new Brackets(qb => { qb
.where('note.replyUserHost IS NULL')
.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.replyUserHost)`);
}))
.andWhere(new Brackets(qb => { qb
.where('note.renoteUserHost IS NULL')
.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.renoteUserHost)`);
}));
q.setParameters(mutingQuery.getParameters());
q.setParameters(mutingInstanceQuery.getParameters());
}
import { Brackets } from 'typeorm';
import { Notifications, Followings, Mutings, Users } from '@/models/index.js';
import { Notifications, Followings, Mutings, Users, UserProfiles } from '@/models/index.js';
import { notificationTypes } from '@/types.js';
import read from '@/services/note/read.js';
import { readNotification } from '../../common/read-notification.js';
import define from '../../define.js';
import { makePaginationQuery } from '../../common/make-pagination-query.js';
import { generateMutedInstanceNotificationQuery } from '../../common/generate-muted-instance-query.js';
export const meta = {
tags: ['account', 'notifications'],
......@@ -67,6 +66,10 @@ export default define(meta, paramDef, async (ps, user) => {
.select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: user.id });
const mutingInstanceQuery = UserProfiles.createQueryBuilder('user_profile')
.select('user_profile.mutedInstances')
.where('user_profile.userId = :muterId', { muterId: user.id });
const suspendedQuery = Users.createQueryBuilder('users')
.select('users.id')
.where('users.isSuspended = TRUE');
......@@ -89,14 +92,21 @@ export default define(meta, paramDef, async (ps, user) => {
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
// muted users
query.andWhere(new Brackets(qb => { qb
.where(`notification.notifierId NOT IN (${ mutingQuery.getQuery() })`)
.orWhere('notification.notifierId IS NULL');
}));
query.setParameters(mutingQuery.getParameters());
generateMutedInstanceNotificationQuery(query, user);
// muted instances
query.andWhere(new Brackets(qb => { qb
.andWhere('notifier.host IS NULL')
.orWhere(`NOT (( ${mutingInstanceQuery.getQuery()} )::jsonb ? notifier.host)`);
}));
query.setParameters(mutingInstanceQuery.getParameters());
// suspended users
query.andWhere(new Brackets(qb => { qb
.where(`notification.notifierId NOT IN (${ suspendedQuery.getQuery() })`)
.orWhere('notification.notifierId IS NULL');
......
......@@ -5,7 +5,6 @@ import { makePaginationQuery } from '../../common/make-pagination-query.js';
import { generateVisibilityQuery } from '../../common/generate-visibility-query.js';
import { generateMutedUserQuery } from '../../common/generate-muted-user-query.js';
import { generateBlockedUserQuery } from '../../common/generate-block-query.js';
import { generateMutedInstanceQuery } from '../../common/generate-muted-instance-query.js';
export const meta = {
tags: ['notes'],
......@@ -61,9 +60,10 @@ export default define(meta, paramDef, async (ps, user) => {
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
generateVisibilityQuery(query, user);
if (user) generateMutedUserQuery(query, user);
if (user) generateBlockedUserQuery(query, user);
if (user) generateMutedInstanceQuery(query, user);
if (user) {
generateMutedUserQuery(query, user);
generateBlockedUserQuery(query, user);
}
const notes = await query.take(ps.limit).getMany();
......
import { fetchMeta } from '@/misc/fetch-meta.js';
import { Notes, Users } from '@/models/index.js';
import { Notes } from '@/models/index.js';
import { activeUsersChart } from '@/services/chart/index.js';
import define from '../../define.js';
import { ApiError } from '../../error.js';
import { makePaginationQuery } from '../../common/make-pagination-query.js';
import { generateMutedUserQuery } from '../../common/generate-muted-user-query.js';
import { generateMutedInstanceQuery } from '../../common/generate-muted-instance-query.js';
import { generateRepliesQuery } from '../../common/generate-replies-query.js';
import { generateMutedNoteQuery } from '../../common/generate-muted-note-query.js';
import { generateBlockedUserQuery } from '../../common/generate-block-query.js';
......@@ -76,10 +75,11 @@ export default define(meta, paramDef, async (ps, user) => {
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
generateRepliesQuery(query, user);
if (user) generateMutedUserQuery(query, user);
if (user) generateMutedNoteQuery(query, user);
if (user) generateBlockedUserQuery(query, user);
if (user) generateMutedInstanceQuery(query, user);
if (user) {
generateMutedUserQuery(query, user);
generateMutedNoteQuery(query, user);
generateBlockedUserQuery(query, user);
}
if (ps.withFiles) {
query.andWhere('note.fileIds != \'{}\'');
......
import { Brackets } from 'typeorm';
import { fetchMeta } from '@/misc/fetch-meta.js';
import { Followings, Notes, Users } from '@/models/index.js';
import { Followings, Notes } from '@/models/index.js';
import { activeUsersChart } from '@/services/chart/index.js';
import define from '../../define.js';
import { ApiError } from '../../error.js';
import { makePaginationQuery } from '../../common/make-pagination-query.js';
import { generateVisibilityQuery } from '../../common/generate-visibility-query.js';
import { generateMutedUserQuery } from '../../common/generate-muted-user-query.js';
import { generateMutedInstanceQuery } from '../../common/generate-muted-instance-query.js';
import { generateRepliesQuery } from '../../common/generate-replies-query.js';
import { generateMutedNoteQuery } from '../../common/generate-muted-note-query.js';
import { generateChannelQuery } from '../../common/generate-channel-query.js';
......@@ -92,7 +91,6 @@ export default define(meta, paramDef, async (ps, user) => {
generateRepliesQuery(query, user);
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
generateMutedInstanceQuery(query, user);
generateMutedNoteQuery(query, user);
generateBlockedUserQuery(query, user);
......@@ -134,9 +132,7 @@ export default define(meta, paramDef, async (ps, user) => {
const timeline = await query.take(ps.limit).getMany();
process.nextTick(() => {
if (user) {
activeUsersChart.read(user);
}
activeUsersChart.read(user);
});
return await Notes.packMany(timeline, user);
......
......@@ -5,7 +5,6 @@ import define from '../../define.js';
import { makePaginationQuery } from '../../common/make-pagination-query.js';
import { generateVisibilityQuery } from '../../common/generate-visibility-query.js';
import { generateMutedUserQuery } from '../../common/generate-muted-user-query.js';
import { generateMutedInstanceQuery } from '../../common/generate-muted-instance-query.js';
import { generateRepliesQuery } from '../../common/generate-replies-query.js';
import { generateMutedNoteQuery } from '../../common/generate-muted-note-query.js';
import { generateChannelQuery } from '../../common/generate-channel-query.js';
......@@ -84,7 +83,6 @@ export default define(meta, paramDef, async (ps, user) => {
generateRepliesQuery(query, user);
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
generateMutedInstanceQuery(query, user);
generateMutedNoteQuery(query, user);
generateBlockedUserQuery(query, user);
......@@ -126,9 +124,7 @@ export default define(meta, paramDef, async (ps, user) => {
const timeline = await query.take(ps.limit).getMany();
process.nextTick(() => {
if (user) {
activeUsersChart.read(user);
}
activeUsersChart.read(user);
});
return await Notes.packMany(timeline, user);
......
......@@ -7,7 +7,6 @@ import { makePaginationQuery } from '../../common/make-pagination-query.js';
import { generateVisibilityQuery } from '../../common/generate-visibility-query.js';
import { generateMutedUserQuery } from '../../common/generate-muted-user-query.js';
import { generateBlockedUserQuery } from '../../common/generate-block-query.js';
import { generateMutedInstanceQuery } from '../../common/generate-muted-instance-query.js';
export const meta = {
tags: ['users', 'notes'],
......@@ -77,9 +76,10 @@ export default define(meta, paramDef, async (ps, me) => {
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
generateVisibilityQuery(query, me);
if (me) generateMutedUserQuery(query, me, user);
if (me) generateBlockedUserQuery(query, me);
if (me) generateMutedInstanceQuery(query, me);
if (me) {
generateMutedUserQuery(query, me, user);
generateBlockedUserQuery(query, me);
}
if (ps.withFiles) {
query.andWhere('note.fileIds != \'{}\'');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment