fix(backend): add missing kind definition for admin endpoints to improve security

This commit is contained in:
syuilo 2023-12-18 12:32:26 +09:00
parent 776eea736a
commit 5150053275
77 changed files with 153 additions and 2 deletions

View File

@ -93,6 +93,7 @@
- Fix: アカウントをブロックした際に、自身のユーザーのページでノートが相手に表示される問題を修正 - Fix: アカウントをブロックした際に、自身のユーザーのページでノートが相手に表示される問題を修正
- Fix: モデレーションログがモデレーターは閲覧できないように修正 - Fix: モデレーションログがモデレーターは閲覧できないように修正
- Fix: HTTP Digestヘッダのアルゴリズム部分に大文字の"SHA-256"しか使えない - Fix: HTTP Digestヘッダのアルゴリズム部分に大文字の"SHA-256"しか使えない
- Fix: 管理者用APIのアクセス権限が適切に設定されていない問題を修正
## 2023.11.1 ## 2023.11.1

View File

@ -13,6 +13,8 @@ import { AbuseUserReportEntityService } from '@/core/entities/AbuseUserReportEnt
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -15,6 +15,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
res: { res: {
type: 'object', type: 'object',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -14,6 +14,8 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '@/server/api/error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -13,6 +13,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { AnnouncementService } from '@/core/AnnouncementService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -14,6 +14,8 @@ import { IdService } from '@/core/IdService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',
errors: { errors: {

View File

@ -15,6 +15,8 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',

View File

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.j
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -14,6 +14,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -8,7 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueueService } from '@/core/QueueService.js'; import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
secure: true, kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -15,6 +15,8 @@ import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -15,6 +15,8 @@ import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
kind: 'read:admin',
tags: ['admin'], tags: ['admin'],
} as const; } as const;

View File

@ -12,6 +12,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
kind: 'read:admin',
tags: ['admin'], tags: ['admin'],
res: { res: {

View File

@ -12,6 +12,8 @@ import { IdService } from '@/core/IdService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { DEFAULT_POLICIES } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['meta'], tags: ['meta'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -11,6 +11,8 @@ import type { DeliverQueue } from '@/core/QueueModule.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import type { InboxQueue } from '@/core/QueueModule.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -10,6 +10,8 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, Obj
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { RelayService } from '@/core/RelayService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { RelayService } from '@/core/RelayService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -15,6 +15,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -12,6 +12,8 @@ import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { MetaService } from '@/core/MetaService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin', 'role', 'users'], tags: ['admin', 'role', 'users'],
kind: 'read:admin',
requireCredential: false, requireCredential: false,
requireAdmin: true, requireAdmin: true,

View File

@ -10,6 +10,8 @@ import { EmailService } from '@/core/EmailService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -17,6 +17,8 @@ export const meta = {
tags: ['admin', 'meta'], tags: ['admin', 'meta'],
kind: 'read:admin',
res: { res: {
type: 'object', type: 'object',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -16,6 +16,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
kind: 'read:admin',
res: { res: {
type: 'array', type: 'array',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -17,6 +17,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
kind: 'read:admin',
res: { res: {
type: 'object', type: 'object',
nullable: false, optional: false, nullable: false, optional: false,

View File

@ -17,6 +17,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
kind: 'read:admin',
res: { res: {
type: 'array', type: 'array',
nullable: false, optional: false, nullable: false, optional: false,

View File

@ -19,6 +19,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;
@ -39,7 +41,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (user == null) { if (user == null) {
throw new Error('user not found'); throw new Error('user not found');
} }
if (user.avatarId == null) return; if (user.avatarId == null) return;
await this.usersRepository.update(user.id, { await this.usersRepository.update(user.id, {

View File

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { MetaService } from '@/core/MetaService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;