parent
5c7f517895
commit
cb9bd6a004
8 changed files with 121 additions and 0 deletions
|
@ -137,10 +137,13 @@ renoteMute: "Mute Renotes"
|
||||||
renoteUnmute: "Unmute Renotes"
|
renoteUnmute: "Unmute Renotes"
|
||||||
block: "Block"
|
block: "Block"
|
||||||
unblock: "Unblock"
|
unblock: "Unblock"
|
||||||
|
markAsNSFW: "Mark all media from user as NSFW"
|
||||||
suspend: "Suspend"
|
suspend: "Suspend"
|
||||||
unsuspend: "Unsuspend"
|
unsuspend: "Unsuspend"
|
||||||
blockConfirm: "Are you sure that you want to block this account?"
|
blockConfirm: "Are you sure that you want to block this account?"
|
||||||
unblockConfirm: "Are you sure that you want to unblock this account?"
|
unblockConfirm: "Are you sure that you want to unblock this account?"
|
||||||
|
nsfwConfirm: "Are you sure that you want to mark all media from this account as NSFW?"
|
||||||
|
unNsfwConfirm: "Are you sure that you want to unmark all media from this account as NSFW?"
|
||||||
suspendConfirm: "Are you sure that you want to suspend this account?"
|
suspendConfirm: "Are you sure that you want to suspend this account?"
|
||||||
unsuspendConfirm: "Are you sure that you want to unsuspend this account?"
|
unsuspendConfirm: "Are you sure that you want to unsuspend this account?"
|
||||||
selectList: "Select a list"
|
selectList: "Select a list"
|
||||||
|
|
3
locales/index.d.ts
vendored
3
locales/index.d.ts
vendored
|
@ -140,10 +140,13 @@ export interface Locale {
|
||||||
"renoteUnmute": string;
|
"renoteUnmute": string;
|
||||||
"block": string;
|
"block": string;
|
||||||
"unblock": string;
|
"unblock": string;
|
||||||
|
"markAsNSFW": string;
|
||||||
"suspend": string;
|
"suspend": string;
|
||||||
"unsuspend": string;
|
"unsuspend": string;
|
||||||
"blockConfirm": string;
|
"blockConfirm": string;
|
||||||
"unblockConfirm": string;
|
"unblockConfirm": string;
|
||||||
|
"nsfwConfirm": string;
|
||||||
|
"unNsfwConfirm": string;
|
||||||
"suspendConfirm": string;
|
"suspendConfirm": string;
|
||||||
"unsuspendConfirm": string;
|
"unsuspendConfirm": string;
|
||||||
"selectList": string;
|
"selectList": string;
|
||||||
|
|
|
@ -137,10 +137,13 @@ renoteMute: "リノートをミュート"
|
||||||
renoteUnmute: "リノートのミュートを解除"
|
renoteUnmute: "リノートのミュートを解除"
|
||||||
block: "ブロック"
|
block: "ブロック"
|
||||||
unblock: "ブロック解除"
|
unblock: "ブロック解除"
|
||||||
|
markAsNSFW: "ユーザーのすべてのメディアをNSFWとしてマークする"
|
||||||
suspend: "凍結"
|
suspend: "凍結"
|
||||||
unsuspend: "解凍"
|
unsuspend: "解凍"
|
||||||
blockConfirm: "ブロックしますか?"
|
blockConfirm: "ブロックしますか?"
|
||||||
unblockConfirm: "ブロック解除しますか?"
|
unblockConfirm: "ブロック解除しますか?"
|
||||||
|
nsfwConfirm: "このアカウントからのすべてのメディアをNSFWとしてマークしてもよろしいですか?"
|
||||||
|
unNsfwConfirm: "このアカウントのすべてのメディアをNSFWとしてマーク解除してもよろしいですか?"
|
||||||
suspendConfirm: "凍結しますか?"
|
suspendConfirm: "凍結しますか?"
|
||||||
unsuspendConfirm: "解凍しますか?"
|
unsuspendConfirm: "解凍しますか?"
|
||||||
selectList: "リストを選択"
|
selectList: "リストを選択"
|
||||||
|
|
|
@ -61,6 +61,8 @@ import * as ep___admin_serverInfo from './endpoints/admin/server-info.js';
|
||||||
import * as ep___admin_showModerationLogs from './endpoints/admin/show-moderation-logs.js';
|
import * as ep___admin_showModerationLogs from './endpoints/admin/show-moderation-logs.js';
|
||||||
import * as ep___admin_showUser from './endpoints/admin/show-user.js';
|
import * as ep___admin_showUser from './endpoints/admin/show-user.js';
|
||||||
import * as ep___admin_showUsers from './endpoints/admin/show-users.js';
|
import * as ep___admin_showUsers from './endpoints/admin/show-users.js';
|
||||||
|
import * as ep___admin_nsfwUser from './endpoints/admin/nsfw-user.js';
|
||||||
|
import * as ep___admin_unnsfwUser from './endpoints/admin/unnsfw-user.js';
|
||||||
import * as ep___admin_suspendUser from './endpoints/admin/suspend-user.js';
|
import * as ep___admin_suspendUser from './endpoints/admin/suspend-user.js';
|
||||||
import * as ep___admin_unsuspendUser from './endpoints/admin/unsuspend-user.js';
|
import * as ep___admin_unsuspendUser from './endpoints/admin/unsuspend-user.js';
|
||||||
import * as ep___admin_updateMeta from './endpoints/admin/update-meta.js';
|
import * as ep___admin_updateMeta from './endpoints/admin/update-meta.js';
|
||||||
|
@ -414,6 +416,8 @@ const $admin_serverInfo: Provider = { provide: 'ep:admin/server-info', useClass:
|
||||||
const $admin_showModerationLogs: Provider = { provide: 'ep:admin/show-moderation-logs', useClass: ep___admin_showModerationLogs.default };
|
const $admin_showModerationLogs: Provider = { provide: 'ep:admin/show-moderation-logs', useClass: ep___admin_showModerationLogs.default };
|
||||||
const $admin_showUser: Provider = { provide: 'ep:admin/show-user', useClass: ep___admin_showUser.default };
|
const $admin_showUser: Provider = { provide: 'ep:admin/show-user', useClass: ep___admin_showUser.default };
|
||||||
const $admin_showUsers: Provider = { provide: 'ep:admin/show-users', useClass: ep___admin_showUsers.default };
|
const $admin_showUsers: Provider = { provide: 'ep:admin/show-users', useClass: ep___admin_showUsers.default };
|
||||||
|
const $admin_nsfwUser: Provider = { provide: 'ep:admin/nsfw-user', useClass: ep___admin_nsfwUser.default };
|
||||||
|
const $admin_unnsfwUser: Provider = { provide: 'ep:admin/unnsfw-user', useClass: ep___admin_unnsfwUser.default };
|
||||||
const $admin_suspendUser: Provider = { provide: 'ep:admin/suspend-user', useClass: ep___admin_suspendUser.default };
|
const $admin_suspendUser: Provider = { provide: 'ep:admin/suspend-user', useClass: ep___admin_suspendUser.default };
|
||||||
const $admin_unsuspendUser: Provider = { provide: 'ep:admin/unsuspend-user', useClass: ep___admin_unsuspendUser.default };
|
const $admin_unsuspendUser: Provider = { provide: 'ep:admin/unsuspend-user', useClass: ep___admin_unsuspendUser.default };
|
||||||
const $admin_updateMeta: Provider = { provide: 'ep:admin/update-meta', useClass: ep___admin_updateMeta.default };
|
const $admin_updateMeta: Provider = { provide: 'ep:admin/update-meta', useClass: ep___admin_updateMeta.default };
|
||||||
|
@ -771,6 +775,8 @@ const $sponsors: Provider = { provide: 'ep:sponsors', useClass: ep___sponsors.de
|
||||||
$admin_showModerationLogs,
|
$admin_showModerationLogs,
|
||||||
$admin_showUser,
|
$admin_showUser,
|
||||||
$admin_showUsers,
|
$admin_showUsers,
|
||||||
|
$admin_nsfwUser,
|
||||||
|
$admin_unnsfwUser,
|
||||||
$admin_suspendUser,
|
$admin_suspendUser,
|
||||||
$admin_unsuspendUser,
|
$admin_unsuspendUser,
|
||||||
$admin_updateMeta,
|
$admin_updateMeta,
|
||||||
|
@ -1122,6 +1128,8 @@ const $sponsors: Provider = { provide: 'ep:sponsors', useClass: ep___sponsors.de
|
||||||
$admin_showModerationLogs,
|
$admin_showModerationLogs,
|
||||||
$admin_showUser,
|
$admin_showUser,
|
||||||
$admin_showUsers,
|
$admin_showUsers,
|
||||||
|
$admin_nsfwUser,
|
||||||
|
$admin_unnsfwUser,
|
||||||
$admin_suspendUser,
|
$admin_suspendUser,
|
||||||
$admin_unsuspendUser,
|
$admin_unsuspendUser,
|
||||||
$admin_updateMeta,
|
$admin_updateMeta,
|
||||||
|
|
|
@ -61,6 +61,8 @@ import * as ep___admin_serverInfo from './endpoints/admin/server-info.js';
|
||||||
import * as ep___admin_showModerationLogs from './endpoints/admin/show-moderation-logs.js';
|
import * as ep___admin_showModerationLogs from './endpoints/admin/show-moderation-logs.js';
|
||||||
import * as ep___admin_showUser from './endpoints/admin/show-user.js';
|
import * as ep___admin_showUser from './endpoints/admin/show-user.js';
|
||||||
import * as ep___admin_showUsers from './endpoints/admin/show-users.js';
|
import * as ep___admin_showUsers from './endpoints/admin/show-users.js';
|
||||||
|
import * as ep___admin_nsfwUser from './endpoints/admin/nsfw-user.js';
|
||||||
|
import * as ep___admin_unnsfwUser from './endpoints/admin/unnsfw-user.js';
|
||||||
import * as ep___admin_suspendUser from './endpoints/admin/suspend-user.js';
|
import * as ep___admin_suspendUser from './endpoints/admin/suspend-user.js';
|
||||||
import * as ep___admin_unsuspendUser from './endpoints/admin/unsuspend-user.js';
|
import * as ep___admin_unsuspendUser from './endpoints/admin/unsuspend-user.js';
|
||||||
import * as ep___admin_updateMeta from './endpoints/admin/update-meta.js';
|
import * as ep___admin_updateMeta from './endpoints/admin/update-meta.js';
|
||||||
|
@ -412,6 +414,8 @@ const eps = [
|
||||||
['admin/show-moderation-logs', ep___admin_showModerationLogs],
|
['admin/show-moderation-logs', ep___admin_showModerationLogs],
|
||||||
['admin/show-user', ep___admin_showUser],
|
['admin/show-user', ep___admin_showUser],
|
||||||
['admin/show-users', ep___admin_showUsers],
|
['admin/show-users', ep___admin_showUsers],
|
||||||
|
['admin/nsfw-user', ep___admin_nsfwUser],
|
||||||
|
['admin/unnsfw-user', ep___admin_unnsfwUser],
|
||||||
['admin/suspend-user', ep___admin_suspendUser],
|
['admin/suspend-user', ep___admin_suspendUser],
|
||||||
['admin/unsuspend-user', ep___admin_unsuspendUser],
|
['admin/unsuspend-user', ep___admin_unsuspendUser],
|
||||||
['admin/update-meta', ep___admin_updateMeta],
|
['admin/update-meta', ep___admin_updateMeta],
|
||||||
|
|
42
packages/backend/src/server/api/endpoints/admin/nsfw-user.ts
Normal file
42
packages/backend/src/server/api/endpoints/admin/nsfw-user.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
|
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
|
||||||
|
import { DI } from '@/di-symbols.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
requireModerator: true,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['userId'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||||
|
constructor(
|
||||||
|
@Inject(DI.usersRepository)
|
||||||
|
private usersRepository: UsersRepository,
|
||||||
|
|
||||||
|
@Inject(DI.userProfilesRepository)
|
||||||
|
private userProfilesRepository: UserProfilesRepository,
|
||||||
|
) {
|
||||||
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
const user = await this.usersRepository.findOneBy({ id: ps.userId });
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
throw new Error('user not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.userProfilesRepository.update(user.id, {
|
||||||
|
alwaysMarkNsfw: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
|
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
|
||||||
|
import { DI } from '@/di-symbols.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
requireModerator: true,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['userId'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||||
|
constructor(
|
||||||
|
@Inject(DI.usersRepository)
|
||||||
|
private usersRepository: UsersRepository,
|
||||||
|
|
||||||
|
@Inject(DI.userProfilesRepository)
|
||||||
|
private userProfilesRepository: UserProfilesRepository,
|
||||||
|
) {
|
||||||
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
const user = await this.usersRepository.findOneBy({ id: ps.userId });
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
throw new Error('user not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.userProfilesRepository.update(user.id, {
|
||||||
|
alwaysMarkNsfw: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,6 +77,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<FormSection>
|
<FormSection>
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<MkSwitch v-model="suspended" @update:modelValue="toggleSuspend">{{ i18n.ts.suspend }}</MkSwitch>
|
<MkSwitch v-model="suspended" @update:modelValue="toggleSuspend">{{ i18n.ts.suspend }}</MkSwitch>
|
||||||
|
<MkSwitch v-model="markedAsNSFW" @update:modelValue="toggleNSFW">{{ i18n.ts.markAsNSFW }}</MkSwitch>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<MkButton v-if="user.host == null" inline style="margin-right: 8px;" @click="resetPassword"><i class="ph-key ph-bold ph-lg"></i> {{ i18n.ts.resetPassword }}</MkButton>
|
<MkButton v-if="user.host == null" inline style="margin-right: 8px;" @click="resetPassword"><i class="ph-key ph-bold ph-lg"></i> {{ i18n.ts.resetPassword }}</MkButton>
|
||||||
|
@ -223,6 +224,7 @@ let ap = $ref(null);
|
||||||
let moderator = $ref(false);
|
let moderator = $ref(false);
|
||||||
let silenced = $ref(false);
|
let silenced = $ref(false);
|
||||||
let suspended = $ref(false);
|
let suspended = $ref(false);
|
||||||
|
let markedAsNSFW = $ref(false);
|
||||||
let moderationNote = $ref('');
|
let moderationNote = $ref('');
|
||||||
const filesPagination = {
|
const filesPagination = {
|
||||||
endpoint: 'admin/drive/files' as const,
|
endpoint: 'admin/drive/files' as const,
|
||||||
|
@ -255,6 +257,7 @@ function createFetcher() {
|
||||||
silenced = info.isSilenced;
|
silenced = info.isSilenced;
|
||||||
suspended = info.isSuspended;
|
suspended = info.isSuspended;
|
||||||
moderationNote = info.moderationNote;
|
moderationNote = info.moderationNote;
|
||||||
|
markedAsNSFW = info.alwaysMarkNsfw;
|
||||||
|
|
||||||
watch($$(moderationNote), async () => {
|
watch($$(moderationNote), async () => {
|
||||||
await os.api('admin/update-user-note', { userId: user.id, text: moderationNote });
|
await os.api('admin/update-user-note', { userId: user.id, text: moderationNote });
|
||||||
|
@ -290,6 +293,19 @@ async function resetPassword() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleNSFW(v) {
|
||||||
|
const confirm = await os.confirm({
|
||||||
|
type: 'warning',
|
||||||
|
text: v ? i18n.ts.nsfwConfirm : i18n.ts.unNsfwConfirm,
|
||||||
|
});
|
||||||
|
if (confirm.canceled) {
|
||||||
|
markedAsNSFW = !v;
|
||||||
|
} else {
|
||||||
|
await os.api(v ? 'admin/nsfw-user' : 'admin/unnsfw-user', { userId: user.id });
|
||||||
|
await refreshUser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function toggleSuspend(v) {
|
async function toggleSuspend(v) {
|
||||||
const confirm = await os.confirm({
|
const confirm = await os.confirm({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
|
|
Loading…
Reference in a new issue