enhance: make configurable to whether notes search available by role
Resolve #10318
This commit is contained in:
parent
7f16b50e73
commit
5d1ccb9bdc
7 changed files with 48 additions and 19 deletions
|
@ -15,6 +15,7 @@ You should also include the user name that made the change.
|
||||||
### Improvements
|
### Improvements
|
||||||
- ユーザーごとにRenoteをミュートできるように
|
- ユーザーごとにRenoteをミュートできるように
|
||||||
- ノートごとに絵文字リアクションを受け取るか設定できるように
|
- ノートごとに絵文字リアクションを受け取るか設定できるように
|
||||||
|
- ノート検索の利用可否をロールで制御可能に(デフォルトでオフ)
|
||||||
- ロールの並び順を設定可能に
|
- ロールの並び順を設定可能に
|
||||||
- 指定した文字列を含む投稿の公開範囲をホームにできるように
|
- 指定した文字列を含む投稿の公開範囲をホームにできるように
|
||||||
- enhance(client): 設定から自分のロールを確認できるように
|
- enhance(client): 設定から自分のロールを確認できるように
|
||||||
|
|
|
@ -1261,6 +1261,7 @@ _role:
|
||||||
rateLimitFactor: "レートリミット"
|
rateLimitFactor: "レートリミット"
|
||||||
descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。"
|
descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。"
|
||||||
canHideAds: "広告の非表示"
|
canHideAds: "広告の非表示"
|
||||||
|
canSearchNotes: "ノート検索の利用可否"
|
||||||
_condition:
|
_condition:
|
||||||
isLocal: "ローカルユーザー"
|
isLocal: "ローカルユーザー"
|
||||||
isRemote: "リモートユーザー"
|
isRemote: "リモートユーザー"
|
||||||
|
|
|
@ -21,6 +21,7 @@ export type RolePolicies = {
|
||||||
canPublicNote: boolean;
|
canPublicNote: boolean;
|
||||||
canInvite: boolean;
|
canInvite: boolean;
|
||||||
canManageCustomEmojis: boolean;
|
canManageCustomEmojis: boolean;
|
||||||
|
canSearchNotes: boolean;
|
||||||
canHideAds: boolean;
|
canHideAds: boolean;
|
||||||
driveCapacityMb: number;
|
driveCapacityMb: number;
|
||||||
pinLimit: number;
|
pinLimit: number;
|
||||||
|
@ -40,6 +41,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
||||||
canPublicNote: true,
|
canPublicNote: true,
|
||||||
canInvite: false,
|
canInvite: false,
|
||||||
canManageCustomEmojis: false,
|
canManageCustomEmojis: false,
|
||||||
|
canSearchNotes: false,
|
||||||
canHideAds: false,
|
canHideAds: false,
|
||||||
driveCapacityMb: 100,
|
driveCapacityMb: 100,
|
||||||
pinLimit: 5,
|
pinLimit: 5,
|
||||||
|
@ -264,6 +266,7 @@ export class RoleService implements OnApplicationShutdown {
|
||||||
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
|
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
|
||||||
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
|
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
|
||||||
canManageCustomEmojis: calc('canManageCustomEmojis', vs => vs.some(v => v === true)),
|
canManageCustomEmojis: calc('canManageCustomEmojis', vs => vs.some(v => v === true)),
|
||||||
|
canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)),
|
||||||
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
|
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
|
||||||
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
|
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
|
||||||
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
|
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
|
||||||
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['notes'],
|
tags: ['notes'],
|
||||||
|
@ -23,6 +25,11 @@ export const meta = {
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
|
unavailable: {
|
||||||
|
message: 'Search of notes unavailable.',
|
||||||
|
code: 'UNAVAILABLE',
|
||||||
|
id: '0b44998d-77aa-4427-80d0-d2c9b8523011',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@ -59,8 +66,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
|
|
||||||
private noteEntityService: NoteEntityService,
|
private noteEntityService: NoteEntityService,
|
||||||
private queryService: QueryService,
|
private queryService: QueryService,
|
||||||
|
private roleService: RoleService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
const policies = await this.roleService.getUserPolicies(me ? me.id : null);
|
||||||
|
if (!policies.canSearchNotes) {
|
||||||
|
throw new ApiError(meta.errors.unavailable);
|
||||||
|
}
|
||||||
|
|
||||||
const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId);
|
const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId);
|
||||||
|
|
||||||
if (ps.userId) {
|
if (ps.userId) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ export const ROLE_POLICIES = [
|
||||||
'canPublicNote',
|
'canPublicNote',
|
||||||
'canInvite',
|
'canInvite',
|
||||||
'canManageCustomEmojis',
|
'canManageCustomEmojis',
|
||||||
|
'canSearchNotes',
|
||||||
'canHideAds',
|
'canHideAds',
|
||||||
'driveCapacityMb',
|
'driveCapacityMb',
|
||||||
'pinLimit',
|
'pinLimit',
|
||||||
|
|
|
@ -187,6 +187,26 @@
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.canSearchNotes, 'canSearchNotes'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.canSearchNotes }}</template>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="role.policies.canSearchNotes.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||||
|
<span v-else>{{ role.policies.canSearchNotes.value ? i18n.ts.yes : i18n.ts.no }}</span>
|
||||||
|
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canSearchNotes)"></i></span>
|
||||||
|
</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="role.policies.canSearchNotes.useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="role.policies.canSearchNotes.value" :disabled="role.policies.canSearchNotes.useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkRange v-model="role.policies.canSearchNotes.priority" :min="0" :max="2" :step="1" easing :text-converter="(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.driveCapacity, 'driveCapacityMb'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacity, 'driveCapacityMb'])">
|
||||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
|
|
|
@ -55,6 +55,14 @@
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.canSearchNotes }}</template>
|
||||||
|
<template #suffix>{{ policies.canSearchNotes ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||||
|
<MkSwitch v-model="policies.canSearchNotes">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||||
<template #suffix>{{ policies.driveCapacityMb }}MB</template>
|
<template #suffix>{{ policies.driveCapacityMb }}MB</template>
|
||||||
|
@ -167,25 +175,7 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
import { instance } from '@/instance';
|
import { instance } from '@/instance';
|
||||||
import { useRouter } from '@/router';
|
import { useRouter } from '@/router';
|
||||||
import MkFoldableSection from '@/components/MkFoldableSection.vue';
|
import MkFoldableSection from '@/components/MkFoldableSection.vue';
|
||||||
|
import { ROLE_POLICIES } from '@/const';
|
||||||
const ROLE_POLICIES = [
|
|
||||||
'gtlAvailable',
|
|
||||||
'ltlAvailable',
|
|
||||||
'canPublicNote',
|
|
||||||
'canInvite',
|
|
||||||
'canManageCustomEmojis',
|
|
||||||
'canHideAds',
|
|
||||||
'driveCapacityMb',
|
|
||||||
'pinLimit',
|
|
||||||
'antennaLimit',
|
|
||||||
'wordMuteLimit',
|
|
||||||
'webhookLimit',
|
|
||||||
'clipLimit',
|
|
||||||
'noteEachClipsLimit',
|
|
||||||
'userListLimit',
|
|
||||||
'userEachUserListsLimit',
|
|
||||||
'rateLimitFactor',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue