summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2025-08-09 14:41:11 +0900
committerGitHub <noreply@github.com>2025-08-09 14:41:11 +0900
commitb5b79140733a7fe46c446616d03060587cf4919c (patch)
tree65d90d7fe945c51c3ebb3ff7e41d1bb8258383fe /packages
parentfix(backend): prevent run repeatable job immediately (diff)
downloadmisskey-b5b79140733a7fe46c446616d03060587cf4919c.tar.gz
misskey-b5b79140733a7fe46c446616d03060587cf4919c.tar.bz2
misskey-b5b79140733a7fe46c446616d03060587cf4919c.zip
enhance: ユーザー検索を制限できるように (#16380)
* enhance: ユーザー検索を制限できるように * Update Changelog
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/src/core/RoleService.ts3
-rw-r--r--packages/backend/src/models/json-schema/role.ts4
-rw-r--r--packages/backend/src/server/api/endpoints/users/search.ts1
-rw-r--r--packages/frontend/src/pages/admin/roles.editor.vue20
-rw-r--r--packages/frontend/src/pages/admin/roles.vue8
-rw-r--r--packages/frontend/src/pages/search.vue10
-rw-r--r--packages/frontend/src/utility/check-permissions.ts8
-rw-r--r--packages/misskey-js/src/autogen/types.ts1
8 files changed, 53 insertions, 2 deletions
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index cddfc0094e..3df7ee69ee 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -43,6 +43,7 @@ export type RolePolicies = {
canManageCustomEmojis: boolean;
canManageAvatarDecorations: boolean;
canSearchNotes: boolean;
+ canSearchUsers: boolean;
canUseTranslator: boolean;
canHideAds: boolean;
driveCapacityMb: number;
@@ -82,6 +83,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
canManageCustomEmojis: false,
canManageAvatarDecorations: false,
canSearchNotes: false,
+ canSearchUsers: true,
canUseTranslator: true,
canHideAds: false,
driveCapacityMb: 100,
@@ -402,6 +404,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
canManageCustomEmojis: calc('canManageCustomEmojis', vs => vs.some(v => v === true)),
canManageAvatarDecorations: calc('canManageAvatarDecorations', vs => vs.some(v => v === true)),
canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)),
+ canSearchUsers: calc('canSearchUsers', vs => vs.some(v => v === true)),
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
diff --git a/packages/backend/src/models/json-schema/role.ts b/packages/backend/src/models/json-schema/role.ts
index c9cdbd5d89..0b9234cb81 100644
--- a/packages/backend/src/models/json-schema/role.ts
+++ b/packages/backend/src/models/json-schema/role.ts
@@ -212,6 +212,10 @@ export const packedRolePoliciesSchema = {
type: 'boolean',
optional: false, nullable: false,
},
+ canSearchUsers: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
canUseTranslator: {
type: 'boolean',
optional: false, nullable: false,
diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts
index 5d36847e03..c422286152 100644
--- a/packages/backend/src/server/api/endpoints/users/search.ts
+++ b/packages/backend/src/server/api/endpoints/users/search.ts
@@ -13,6 +13,7 @@ export const meta = {
tags: ['users'],
requireCredential: false,
+ requiredRolePolicy: 'canSearchUsers',
description: 'Search for users.',
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index c172e22688..bb96a1cde1 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -346,6 +346,26 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>
+ <MkFolder v-if="matchQuery([i18n.ts._role._options.canSearchUsers, 'canSearchUsers'])">
+ <template #label>{{ i18n.ts._role._options.canSearchUsers }}</template>
+ <template #suffix>
+ <span v-if="role.policies.canSearchUsers.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
+ <span v-else>{{ role.policies.canSearchUsers.value ? i18n.ts.yes : i18n.ts.no }}</span>
+ <span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canSearchUsers)"></i></span>
+ </template>
+ <div class="_gaps">
+ <MkSwitch v-model="role.policies.canSearchUsers.useDefault" :readonly="readonly">
+ <template #label>{{ i18n.ts._role.useBaseValue }}</template>
+ </MkSwitch>
+ <MkSwitch v-model="role.policies.canSearchUsers.value" :disabled="role.policies.canSearchUsers.useDefault" :readonly="readonly">
+ <template #label>{{ i18n.ts.enable }}</template>
+ </MkSwitch>
+ <MkRange v-model="role.policies.canSearchUsers.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
+ <template #label>{{ i18n.ts._role.priority }}</template>
+ </MkRange>
+ </div>
+ </MkFolder>
+
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseTranslator, 'canUseTranslator'])">
<template #label>{{ i18n.ts._role._options.canUseTranslator }}</template>
<template #suffix>
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index e78a4bbc11..efdf8620ef 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -122,6 +122,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</MkFolder>
+ <MkFolder v-if="matchQuery([i18n.ts._role._options.canSearchUsers, 'canSearchUsers'])">
+ <template #label>{{ i18n.ts._role._options.canSearchUsers }}</template>
+ <template #suffix>{{ policies.canSearchUsers ? i18n.ts.yes : i18n.ts.no }}</template>
+ <MkSwitch v-model="policies.canSearchUsers">
+ <template #label>{{ i18n.ts.enable }}</template>
+ </MkSwitch>
+ </MkFolder>
+
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseTranslator, 'canUseTranslator'])">
<template #label>{{ i18n.ts._role._options.canUseTranslator }}</template>
<template #suffix>{{ policies.canUseTranslator ? i18n.ts.yes : i18n.ts.no }}</template>
diff --git a/packages/frontend/src/pages/search.vue b/packages/frontend/src/pages/search.vue
index b6d21a4616..8d2bf9eb42 100644
--- a/packages/frontend/src/pages/search.vue
+++ b/packages/frontend/src/pages/search.vue
@@ -15,16 +15,22 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div v-else-if="tab === 'user'" class="_spacer" style="--MI_SPACER-w: 800px;">
- <XUser v-bind="props"/>
+ <div v-if="usersSearchAvailable">
+ <XUser v-bind="props"/>
+ </div>
+ <div v-else>
+ <MkInfo warn>{{ i18n.ts.usersSearchNotAvailable }}</MkInfo>
+ </div>
</div>
</PageWithHeader>
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, toRef } from 'vue';
+import { $i } from '@/i.js';
import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js';
-import { notesSearchAvailable } from '@/utility/check-permissions.js';
+import { notesSearchAvailable, usersSearchAvailable } from '@/utility/check-permissions.js';
import MkInfo from '@/components/MkInfo.vue';
const props = withDefaults(defineProps<{
diff --git a/packages/frontend/src/utility/check-permissions.ts b/packages/frontend/src/utility/check-permissions.ts
index 2de8fd2cd1..4f55556e0a 100644
--- a/packages/frontend/src/utility/check-permissions.ts
+++ b/packages/frontend/src/utility/check-permissions.ts
@@ -17,3 +17,11 @@ export const notesSearchAvailable = (
export const canSearchNonLocalNotes = (
instance.noteSearchableScope === 'global'
);
+
+export const usersSearchAvailable = (
+ // FIXME: instance.policies would be null in Vitest
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ ($i == null && instance.policies != null && instance.policies.canSearchUsers) ||
+ ($i != null && $i.policies.canSearchUsers) ||
+ false
+);
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index f0efd63d3a..13c5dcf5f1 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -5211,6 +5211,7 @@ export type components = {
canManageCustomEmojis: boolean;
canManageAvatarDecorations: boolean;
canSearchNotes: boolean;
+ canSearchUsers: boolean;
canUseTranslator: boolean;
canHideAds: boolean;
driveCapacityMb: number;