isSuspendedの周囲にisRemoteSuspendedの考慮を追加

This commit is contained in:
tamaina 2025-07-07 12:35:41 +09:00
parent 4417f0525c
commit 585ff3d262
13 changed files with 30 additions and 7 deletions

View File

@ -151,6 +151,7 @@ export class FanoutTimelineEndpointService {
};
if (!ps.ignoreAuthorFromUserSuspension) {
if (note.user!.isSuspended) return false;
if (note.user!.isRemoteSuspended) return false;
}
if (note.userId !== note.renoteUserId && noteJoined.renoteUser?.isSuspended) return false;
if (note.userId !== note.replyUserId && noteJoined.replyUser?.isSuspended) return false;

View File

@ -254,7 +254,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
}
// サスペンド済みユーザである
case 'isSuspended': {
return user.isSuspended;
return this.userEntityService.isSuspendedEither(user);
}
// 鍵アカウントユーザである
case 'isLocked': {

View File

@ -207,7 +207,7 @@ export class UserSearchService {
}
}
userQuery.andWhere('user.isSuspended = FALSE');
userQuery.andWhere('user.isSuspended = FALSE').andWhere('user.isRemoteSuspended = FALSE');
return userQuery;
}
@ -243,7 +243,8 @@ export class UserSearchService {
.where('user.updatedAt IS NULL')
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
}))
.andWhere('user.isSuspended = FALSE');
.andWhere('user.isSuspended = FALSE')
.andWhere('user.isRemoteSuspended = FALSE');
if (mutingQuery) {
nameQuery.andWhere(`user.id NOT IN (${mutingQuery.getQuery()})`);
@ -286,6 +287,7 @@ export class UserSearchService {
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
}))
.andWhere('user.isSuspended = FALSE')
.andWhere('user.isRemoteSuspended = FALSE')
.setParameters(profQuery.getParameters());
users = users.concat(await userQuery

View File

@ -290,7 +290,7 @@ export class NotificationEntityService implements OnModuleInit {
if (notifier == null) return false;
if (notifier.host && userMutedInstances.has(notifier.host)) return false;
if (notifier.isSuspended) return false;
if (this.userEntityService.isSuspendedEither(notifier)) return false;
return true;
}

View File

@ -69,6 +69,10 @@ function isRemoteUser(user: MiUser | { host: MiUser['host'] }): boolean {
return !isLocalUser(user);
}
function isSuspendedEither(user: MiUser): boolean {
return user.isSuspended || user.isRemoteSuspended;
}
export type UserRelation = {
id: MiUser['id']
following: MiFollowing | null,
@ -163,6 +167,7 @@ export class UserEntityService implements OnModuleInit {
public isLocalUser = isLocalUser;
public isRemoteUser = isRemoteUser;
public isSuspendedEither = isSuspendedEither;
@bindThis
public async getRelation(me: MiUser['id'], target: MiUser['id']): Promise<UserRelation> {
@ -537,7 +542,7 @@ export class UserEntityService implements OnModuleInit {
bannerBlurhash: user.bannerId == null ? null : user.bannerBlurhash,
isLocked: user.isLocked,
isSilenced: this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote),
isSuspended: user.isSuspended,
isSuspended: this.isSuspendedEither(user),
description: profile!.description,
location: profile!.location,
birthday: profile!.birthday,

View File

@ -215,6 +215,7 @@ export class ServerService implements OnApplicationShutdown {
usernameLower: username.toLowerCase(),
host: (host == null) || (host === this.config.host) ? IsNull() : host,
isSuspended: false,
isRemoteSuspended: false,
},
});

View File

@ -124,6 +124,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
isRemoteSuspended: {
type: 'boolean',
optional: false, nullable: false,
},
isHibernated: {
type: 'boolean',
optional: false, nullable: false,
@ -246,6 +250,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
isModerator: isModerator,
isSilenced: isSilenced,
isSuspended: user.isSuspended,
isRemoteSuspended: user.isRemoteSuspended,
isHibernated: user.isHibernated,
lastActiveDate: user.lastActiveDate ? user.lastActiveDate.toISOString() : null,
moderationNote: profile.moderationNote ?? '',

View File

@ -61,7 +61,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const query = this.usersRepository.createQueryBuilder('user');
switch (ps.state) {
case 'available': query.where('user.isSuspended = FALSE'); break;
case 'available': query.where('user.isSuspended = FALSE').andWhere('user.isRemoteSuspended = FALSE'); break;
case 'alive': query.where('user.updatedAt > :date', { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5) }); break;
case 'suspended': query.where('user.isSuspended = TRUE'); break;
case 'admin': {

View File

@ -51,7 +51,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (!safeForSql(normalizeForSearch(ps.tag))) throw new Error('Injection');
const query = this.usersRepository.createQueryBuilder('user')
.where(':tag <@ user.tags', { tag: [normalizeForSearch(ps.tag)] })
.andWhere('user.isSuspended = FALSE');
.andWhere('user.isSuspended = FALSE')
.andWhere('user.isRemoteSuspended = FALSE');
const recent = new Date(Date.now() - (1000 * 60 * 60 * 24 * 5));

View File

@ -138,6 +138,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} : {
id: In(ps.userIds),
isSuspended: false,
isRemoteSuspended: false,
});
// リクエストされた通りに並べ替え

View File

@ -451,6 +451,7 @@ export class ClientServerService {
usernameLower: username.toLowerCase(),
host: host ?? IsNull(),
isSuspended: false,
isRemoteSuspended: false,
requireSigninToViewContents: false,
});
@ -510,6 +511,7 @@ export class ClientServerService {
usernameLower: username.toLowerCase(),
host: host ?? IsNull(),
isSuspended: false,
isRemoteSuspended: false,
});
vary(reply.raw, 'Accept');
@ -559,6 +561,7 @@ export class ClientServerService {
id: request.params.user,
host: IsNull(),
isSuspended: false,
isRemoteSuspended: false,
});
if (user == null) {

View File

@ -15,6 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span class="sub"><span class="acct _monospace">@{{ acct(user) }}</span></span>
<span class="state">
<span v-if="suspended" class="suspended">Suspended</span>
<span v-if="remoteSuspended" class="suspended">Suspended in Remote</span>
<span v-if="silenced" class="silenced">Silenced</span>
<span v-if="moderator" class="moderator">Moderator</span>
</span>
@ -254,6 +255,7 @@ const ap = ref<any>(null);
const moderator = ref(false);
const silenced = ref(false);
const suspended = ref(false);
const remoteSuspended = ref(false);
const isSystem = ref(false);
const moderationNote = ref('');
const filesPaginator = markRaw(new Paginator('admin/drive/files', {
@ -288,6 +290,7 @@ function createFetcher() {
moderator.value = info.value.isModerator;
silenced.value = info.value.isSilenced;
suspended.value = info.value.isSuspended;
remoteSuspended.value = info.value.isRemoteSuspended;
moderationNote.value = info.value.moderationNote;
isSystem.value = user.value.host == null && user.value.username.includes('.');

View File

@ -11586,6 +11586,7 @@ export interface operations {
isModerator: boolean;
isSilenced: boolean;
isSuspended: boolean;
isRemoteSuspended: boolean;
isHibernated: boolean;
lastActiveDate: string | null;
moderationNote: string;