feat: 通報を受けた際にメールまたはWebhookで通知を送出出来るようにする (#13758)
* feat: 通報を受けた際にメールまたはWebhookで通知を送出出来るようにする
* モデログに対応&エンドポイントを単一オブジェクトでのサポートに変更(API経由で大量に作るシチュエーションもないと思うので)
* fix spdx
* fix migration
* fix migration
* fix models
* add e2e webhook
* tweak
* fix modlog
* fix bugs
* add tests and fix bugs
* add tests and fix bugs
* add tests
* fix path
* regenerate locale
* 混入除去
* 混入除去
* add abuseReportResolved
* fix pnpm-lock.yaml
* add abuseReportResolved test
* fix bugs
* fix ui
* add tests
* fix CHANGELOG.md
* add tests
* add RoleService.getModeratorIds tests
* WebhookServiceをUserとSystemに分割
* fix CHANGELOG.md
* fix test
* insertOneを使う用に
* fix
* regenerate locales
* revert version
* separate webhook job queue
* fix
* 🎨
* Update QueueProcessorService.ts
---------
Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
parent
e0cf5b2402
commit
61fae45390
79 changed files with 6527 additions and 369 deletions
|
@ -6,8 +6,13 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { CoreModule } from '@/core/CoreModule.js';
|
||||
import * as ep___admin_meta from './endpoints/admin/meta.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_list from '@/server/api/endpoints/admin/abuse-report/notification-recipient/list.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_show from '@/server/api/endpoints/admin/abuse-report/notification-recipient/show.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_create from '@/server/api/endpoints/admin/abuse-report/notification-recipient/create.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_update from '@/server/api/endpoints/admin/abuse-report/notification-recipient/update.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_delete from '@/server/api/endpoints/admin/abuse-report/notification-recipient/delete.js';
|
||||
import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js';
|
||||
import * as ep___admin_meta from './endpoints/admin/meta.js';
|
||||
import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js';
|
||||
import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js';
|
||||
import * as ep___admin_accounts_findByEmail from './endpoints/admin/accounts/find-by-email.js';
|
||||
|
@ -82,6 +87,11 @@ import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js';
|
|||
import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js';
|
||||
import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js';
|
||||
import * as ep___admin_roles_users from './endpoints/admin/roles/users.js';
|
||||
import * as ep___admin_systemWebhook_create from './endpoints/admin/system-webhook/create.js';
|
||||
import * as ep___admin_systemWebhook_delete from './endpoints/admin/system-webhook/delete.js';
|
||||
import * as ep___admin_systemWebhook_list from './endpoints/admin/system-webhook/list.js';
|
||||
import * as ep___admin_systemWebhook_show from './endpoints/admin/system-webhook/show.js';
|
||||
import * as ep___admin_systemWebhook_update from './endpoints/admin/system-webhook/update.js';
|
||||
import * as ep___announcements from './endpoints/announcements.js';
|
||||
import * as ep___announcements_show from './endpoints/announcements/show.js';
|
||||
import * as ep___antennas_create from './endpoints/antennas/create.js';
|
||||
|
@ -381,6 +391,11 @@ import type { Provider } from '@nestjs/common';
|
|||
|
||||
const $admin_meta: Provider = { provide: 'ep:admin/meta', useClass: ep___admin_meta.default };
|
||||
const $admin_abuseUserReports: Provider = { provide: 'ep:admin/abuse-user-reports', useClass: ep___admin_abuseUserReports.default };
|
||||
const $admin_abuseReport_notificationRecipient_list: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/list', useClass: ep___admin_abuseReport_notificationRecipient_list.default };
|
||||
const $admin_abuseReport_notificationRecipient_show: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/show', useClass: ep___admin_abuseReport_notificationRecipient_show.default };
|
||||
const $admin_abuseReport_notificationRecipient_create: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/create', useClass: ep___admin_abuseReport_notificationRecipient_create.default };
|
||||
const $admin_abuseReport_notificationRecipient_update: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/update', useClass: ep___admin_abuseReport_notificationRecipient_update.default };
|
||||
const $admin_abuseReport_notificationRecipient_delete: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/delete', useClass: ep___admin_abuseReport_notificationRecipient_delete.default };
|
||||
const $admin_accounts_create: Provider = { provide: 'ep:admin/accounts/create', useClass: ep___admin_accounts_create.default };
|
||||
const $admin_accounts_delete: Provider = { provide: 'ep:admin/accounts/delete', useClass: ep___admin_accounts_delete.default };
|
||||
const $admin_accounts_findByEmail: Provider = { provide: 'ep:admin/accounts/find-by-email', useClass: ep___admin_accounts_findByEmail.default };
|
||||
|
@ -455,6 +470,11 @@ const $admin_roles_assign: Provider = { provide: 'ep:admin/roles/assign', useCla
|
|||
const $admin_roles_unassign: Provider = { provide: 'ep:admin/roles/unassign', useClass: ep___admin_roles_unassign.default };
|
||||
const $admin_roles_updateDefaultPolicies: Provider = { provide: 'ep:admin/roles/update-default-policies', useClass: ep___admin_roles_updateDefaultPolicies.default };
|
||||
const $admin_roles_users: Provider = { provide: 'ep:admin/roles/users', useClass: ep___admin_roles_users.default };
|
||||
const $admin_systemWebhook_create: Provider = { provide: 'ep:admin/system-webhook/create', useClass: ep___admin_systemWebhook_create.default };
|
||||
const $admin_systemWebhook_delete: Provider = { provide: 'ep:admin/system-webhook/delete', useClass: ep___admin_systemWebhook_delete.default };
|
||||
const $admin_systemWebhook_list: Provider = { provide: 'ep:admin/system-webhook/list', useClass: ep___admin_systemWebhook_list.default };
|
||||
const $admin_systemWebhook_show: Provider = { provide: 'ep:admin/system-webhook/show', useClass: ep___admin_systemWebhook_show.default };
|
||||
const $admin_systemWebhook_update: Provider = { provide: 'ep:admin/system-webhook/update', useClass: ep___admin_systemWebhook_update.default };
|
||||
const $announcements: Provider = { provide: 'ep:announcements', useClass: ep___announcements.default };
|
||||
const $announcements_show: Provider = { provide: 'ep:announcements/show', useClass: ep___announcements_show.default };
|
||||
const $antennas_create: Provider = { provide: 'ep:antennas/create', useClass: ep___antennas_create.default };
|
||||
|
@ -758,6 +778,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
|
|||
ApiLoggerService,
|
||||
$admin_meta,
|
||||
$admin_abuseUserReports,
|
||||
$admin_abuseReport_notificationRecipient_list,
|
||||
$admin_abuseReport_notificationRecipient_show,
|
||||
$admin_abuseReport_notificationRecipient_create,
|
||||
$admin_abuseReport_notificationRecipient_update,
|
||||
$admin_abuseReport_notificationRecipient_delete,
|
||||
$admin_accounts_create,
|
||||
$admin_accounts_delete,
|
||||
$admin_accounts_findByEmail,
|
||||
|
@ -832,6 +857,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
|
|||
$admin_roles_unassign,
|
||||
$admin_roles_updateDefaultPolicies,
|
||||
$admin_roles_users,
|
||||
$admin_systemWebhook_create,
|
||||
$admin_systemWebhook_delete,
|
||||
$admin_systemWebhook_list,
|
||||
$admin_systemWebhook_show,
|
||||
$admin_systemWebhook_update,
|
||||
$announcements,
|
||||
$announcements_show,
|
||||
$antennas_create,
|
||||
|
@ -1129,6 +1159,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
|
|||
exports: [
|
||||
$admin_meta,
|
||||
$admin_abuseUserReports,
|
||||
$admin_abuseReport_notificationRecipient_list,
|
||||
$admin_abuseReport_notificationRecipient_show,
|
||||
$admin_abuseReport_notificationRecipient_create,
|
||||
$admin_abuseReport_notificationRecipient_update,
|
||||
$admin_abuseReport_notificationRecipient_delete,
|
||||
$admin_accounts_create,
|
||||
$admin_accounts_delete,
|
||||
$admin_accounts_findByEmail,
|
||||
|
@ -1203,6 +1238,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
|
|||
$admin_roles_unassign,
|
||||
$admin_roles_updateDefaultPolicies,
|
||||
$admin_roles_users,
|
||||
$admin_systemWebhook_create,
|
||||
$admin_systemWebhook_delete,
|
||||
$admin_systemWebhook_list,
|
||||
$admin_systemWebhook_show,
|
||||
$admin_systemWebhook_update,
|
||||
$announcements,
|
||||
$announcements_show,
|
||||
$antennas_create,
|
||||
|
|
|
@ -6,8 +6,18 @@
|
|||
import { permissions } from 'misskey-js';
|
||||
import type { KeyOf, Schema } from '@/misc/json-schema.js';
|
||||
|
||||
import * as ep___admin_meta from './endpoints/admin/meta.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_list
|
||||
from '@/server/api/endpoints/admin/abuse-report/notification-recipient/list.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_show
|
||||
from '@/server/api/endpoints/admin/abuse-report/notification-recipient/show.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_create
|
||||
from '@/server/api/endpoints/admin/abuse-report/notification-recipient/create.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_update
|
||||
from '@/server/api/endpoints/admin/abuse-report/notification-recipient/update.js';
|
||||
import * as ep___admin_abuseReport_notificationRecipient_delete
|
||||
from '@/server/api/endpoints/admin/abuse-report/notification-recipient/delete.js';
|
||||
import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js';
|
||||
import * as ep___admin_meta from './endpoints/admin/meta.js';
|
||||
import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js';
|
||||
import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js';
|
||||
import * as ep___admin_accounts_findByEmail from './endpoints/admin/accounts/find-by-email.js';
|
||||
|
@ -44,7 +54,8 @@ import * as ep___admin_emoji_setCategoryBulk from './endpoints/admin/emoji/set-c
|
|||
import * as ep___admin_emoji_setLicenseBulk from './endpoints/admin/emoji/set-license-bulk.js';
|
||||
import * as ep___admin_emoji_update from './endpoints/admin/emoji/update.js';
|
||||
import * as ep___admin_federation_deleteAllFiles from './endpoints/admin/federation/delete-all-files.js';
|
||||
import * as ep___admin_federation_refreshRemoteInstanceMetadata from './endpoints/admin/federation/refresh-remote-instance-metadata.js';
|
||||
import * as ep___admin_federation_refreshRemoteInstanceMetadata
|
||||
from './endpoints/admin/federation/refresh-remote-instance-metadata.js';
|
||||
import * as ep___admin_federation_removeAllFollowing from './endpoints/admin/federation/remove-all-following.js';
|
||||
import * as ep___admin_federation_updateInstance from './endpoints/admin/federation/update-instance.js';
|
||||
import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js';
|
||||
|
@ -82,6 +93,11 @@ import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js';
|
|||
import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js';
|
||||
import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js';
|
||||
import * as ep___admin_roles_users from './endpoints/admin/roles/users.js';
|
||||
import * as ep___admin_systemWebhook_create from './endpoints/admin/system-webhook/create.js';
|
||||
import * as ep___admin_systemWebhook_delete from './endpoints/admin/system-webhook/delete.js';
|
||||
import * as ep___admin_systemWebhook_list from './endpoints/admin/system-webhook/list.js';
|
||||
import * as ep___admin_systemWebhook_show from './endpoints/admin/system-webhook/show.js';
|
||||
import * as ep___admin_systemWebhook_update from './endpoints/admin/system-webhook/update.js';
|
||||
import * as ep___announcements from './endpoints/announcements.js';
|
||||
import * as ep___announcements_show from './endpoints/announcements/show.js';
|
||||
import * as ep___antennas_create from './endpoints/antennas/create.js';
|
||||
|
@ -379,6 +395,11 @@ import * as ep___reversi_verify from './endpoints/reversi/verify.js';
|
|||
const eps = [
|
||||
['admin/meta', ep___admin_meta],
|
||||
['admin/abuse-user-reports', ep___admin_abuseUserReports],
|
||||
['admin/abuse-report/notification-recipient/list', ep___admin_abuseReport_notificationRecipient_list],
|
||||
['admin/abuse-report/notification-recipient/show', ep___admin_abuseReport_notificationRecipient_show],
|
||||
['admin/abuse-report/notification-recipient/create', ep___admin_abuseReport_notificationRecipient_create],
|
||||
['admin/abuse-report/notification-recipient/update', ep___admin_abuseReport_notificationRecipient_update],
|
||||
['admin/abuse-report/notification-recipient/delete', ep___admin_abuseReport_notificationRecipient_delete],
|
||||
['admin/accounts/create', ep___admin_accounts_create],
|
||||
['admin/accounts/delete', ep___admin_accounts_delete],
|
||||
['admin/accounts/find-by-email', ep___admin_accounts_findByEmail],
|
||||
|
@ -453,6 +474,11 @@ const eps = [
|
|||
['admin/roles/unassign', ep___admin_roles_unassign],
|
||||
['admin/roles/update-default-policies', ep___admin_roles_updateDefaultPolicies],
|
||||
['admin/roles/users', ep___admin_roles_users],
|
||||
['admin/system-webhook/create', ep___admin_systemWebhook_create],
|
||||
['admin/system-webhook/delete', ep___admin_systemWebhook_delete],
|
||||
['admin/system-webhook/list', ep___admin_systemWebhook_list],
|
||||
['admin/system-webhook/show', ep___admin_systemWebhook_show],
|
||||
['admin/system-webhook/update', ep___admin_systemWebhook_update],
|
||||
['announcements', ep___announcements],
|
||||
['announcements/show', ep___announcements_show],
|
||||
['antennas/create', ep___antennas_create],
|
||||
|
@ -873,8 +899,12 @@ export interface IEndpoint {
|
|||
const endpoints: IEndpoint[] = (eps as [string, any]).map(([name, ep]) => {
|
||||
return {
|
||||
name: name,
|
||||
get meta() { return ep.meta ?? {}; },
|
||||
get params() { return ep.paramDef; },
|
||||
get meta() {
|
||||
return ep.meta ?? {};
|
||||
},
|
||||
get params() {
|
||||
return ep.paramDef;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import {
|
||||
AbuseReportNotificationRecipientEntityService,
|
||||
} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js';
|
||||
import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { UserProfilesRepository } from '@/models/_.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'abuse-report', 'notification-recipient'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:abuse-report:notification-recipient',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
ref: 'AbuseReportNotificationRecipient',
|
||||
},
|
||||
|
||||
errors: {
|
||||
correlationCheckEmail: {
|
||||
message: 'If "method" is email, "userId" must be set.',
|
||||
code: 'CORRELATION_CHECK_EMAIL',
|
||||
id: '348bb8ae-575a-6fe9-4327-5811999def8f',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
correlationCheckWebhook: {
|
||||
message: 'If "method" is webhook, "systemWebhookId" must be set.',
|
||||
code: 'CORRELATION_CHECK_WEBHOOK',
|
||||
id: 'b0c15051-de2d-29ef-260c-9585cddd701a',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
emailAddressNotSet: {
|
||||
message: 'Email address is not set.',
|
||||
code: 'EMAIL_ADDRESS_NOT_SET',
|
||||
id: '7cc1d85e-2f58-fc31-b644-3de8d0d3421f',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
isActive: {
|
||||
type: 'boolean',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 255,
|
||||
},
|
||||
method: {
|
||||
type: 'string',
|
||||
enum: ['email', 'webhook'],
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
systemWebhookId: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'isActive',
|
||||
'name',
|
||||
'method',
|
||||
],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.userProfilesRepository)
|
||||
private userProfilesRepository: UserProfilesRepository,
|
||||
private abuseReportNotificationService: AbuseReportNotificationService,
|
||||
private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
if (ps.method === 'email') {
|
||||
const userProfile = await this.userProfilesRepository.findOneBy({ userId: ps.userId });
|
||||
if (!ps.userId || !userProfile) {
|
||||
throw new ApiError(meta.errors.correlationCheckEmail);
|
||||
}
|
||||
|
||||
if (!userProfile.email || !userProfile.emailVerified) {
|
||||
throw new ApiError(meta.errors.emailAddressNotSet);
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.method === 'webhook' && !ps.systemWebhookId) {
|
||||
throw new ApiError(meta.errors.correlationCheckWebhook);
|
||||
}
|
||||
|
||||
const userId = ps.method === 'email' ? ps.userId : null;
|
||||
const systemWebhookId = ps.method === 'webhook' ? ps.systemWebhookId : null;
|
||||
const result = await this.abuseReportNotificationService.createRecipient(
|
||||
{
|
||||
isActive: ps.isActive,
|
||||
name: ps.name,
|
||||
method: ps.method,
|
||||
userId: userId ?? null,
|
||||
systemWebhookId: systemWebhookId ?? null,
|
||||
},
|
||||
me,
|
||||
);
|
||||
|
||||
return this.abuseReportNotificationRecipientEntityService.pack(result);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'abuse-report', 'notification-recipient'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:abuse-report:notification-recipient',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private abuseReportNotificationService: AbuseReportNotificationService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.abuseReportNotificationService.deleteRecipient(
|
||||
ps.id,
|
||||
me,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import {
|
||||
AbuseReportNotificationRecipientEntityService,
|
||||
} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js';
|
||||
import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'abuse-report', 'notification-recipient'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'read:admin:abuse-report:notification-recipient',
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
ref: 'AbuseReportNotificationRecipient',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
method: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: ['email', 'webhook'],
|
||||
},
|
||||
},
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private abuseReportNotificationService: AbuseReportNotificationService,
|
||||
private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps) => {
|
||||
const recipients = await this.abuseReportNotificationService.fetchRecipients({ method: ps.method });
|
||||
return this.abuseReportNotificationRecipientEntityService.packMany(recipients);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import {
|
||||
AbuseReportNotificationRecipientEntityService,
|
||||
} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js';
|
||||
import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'abuse-report', 'notification-recipient'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'read:admin:abuse-report:notification-recipient',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
ref: 'AbuseReportNotificationRecipient',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchRecipient: {
|
||||
message: 'No such recipient.',
|
||||
code: 'NO_SUCH_RECIPIENT',
|
||||
id: '013de6a8-f757-04cb-4d73-cc2a7e3368e4',
|
||||
kind: 'server',
|
||||
httpStatusCode: 404,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
},
|
||||
required: ['id'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private abuseReportNotificationService: AbuseReportNotificationService,
|
||||
private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps) => {
|
||||
const recipients = await this.abuseReportNotificationService.fetchRecipients({ ids: [ps.id] });
|
||||
if (recipients.length === 0) {
|
||||
throw new ApiError(meta.errors.noSuchRecipient);
|
||||
}
|
||||
|
||||
return this.abuseReportNotificationRecipientEntityService.pack(recipients[0]);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import {
|
||||
AbuseReportNotificationRecipientEntityService,
|
||||
} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js';
|
||||
import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { UserProfilesRepository } from '@/models/_.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'abuse-report', 'notification-recipient'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:abuse-report:notification-recipient',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
ref: 'AbuseReportNotificationRecipient',
|
||||
},
|
||||
|
||||
errors: {
|
||||
correlationCheckEmail: {
|
||||
message: 'If "method" is email, "userId" must be set.',
|
||||
code: 'CORRELATION_CHECK_EMAIL',
|
||||
id: '348bb8ae-575a-6fe9-4327-5811999def8f',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
correlationCheckWebhook: {
|
||||
message: 'If "method" is webhook, "systemWebhookId" must be set.',
|
||||
code: 'CORRELATION_CHECK_WEBHOOK',
|
||||
id: 'b0c15051-de2d-29ef-260c-9585cddd701a',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
emailAddressNotSet: {
|
||||
message: 'Email address is not set.',
|
||||
code: 'EMAIL_ADDRESS_NOT_SET',
|
||||
id: '7cc1d85e-2f58-fc31-b644-3de8d0d3421f',
|
||||
httpStatusCode: 400,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
isActive: {
|
||||
type: 'boolean',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 255,
|
||||
},
|
||||
method: {
|
||||
type: 'string',
|
||||
enum: ['email', 'webhook'],
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
systemWebhookId: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
'isActive',
|
||||
'name',
|
||||
'method',
|
||||
],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.userProfilesRepository)
|
||||
private userProfilesRepository: UserProfilesRepository,
|
||||
private abuseReportNotificationService: AbuseReportNotificationService,
|
||||
private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
if (ps.method === 'email') {
|
||||
const userProfile = await this.userProfilesRepository.findOneBy({ userId: ps.userId });
|
||||
if (!ps.userId || !userProfile) {
|
||||
throw new ApiError(meta.errors.correlationCheckEmail);
|
||||
}
|
||||
|
||||
if (!userProfile.email || !userProfile.emailVerified) {
|
||||
throw new ApiError(meta.errors.emailAddressNotSet);
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.method === 'webhook' && !ps.systemWebhookId) {
|
||||
throw new ApiError(meta.errors.correlationCheckWebhook);
|
||||
}
|
||||
|
||||
const userId = ps.method === 'email' ? ps.userId : null;
|
||||
const systemWebhookId = ps.method === 'webhook' ? ps.systemWebhookId : null;
|
||||
const result = await this.abuseReportNotificationService.updateRecipient(
|
||||
{
|
||||
id: ps.id,
|
||||
isActive: ps.isActive,
|
||||
name: ps.name,
|
||||
method: ps.method,
|
||||
userId: userId ?? null,
|
||||
systemWebhookId: systemWebhookId ?? null,
|
||||
},
|
||||
me,
|
||||
);
|
||||
|
||||
return this.abuseReportNotificationRecipientEntityService.pack(result);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/QueueModule.js';
|
||||
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, UserWebhookDeliverQueue, SystemWebhookDeliverQueue } from '@/core/QueueModule.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
@ -53,7 +53,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject('queue:inbox') public inboxQueue: InboxQueue,
|
||||
@Inject('queue:db') public dbQueue: DbQueue,
|
||||
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
|
||||
@Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue,
|
||||
@Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue,
|
||||
@Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const deliverJobCounts = await this.deliverQueue.getJobCounts();
|
||||
|
|
|
@ -5,12 +5,10 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository, AbuseUserReportsRepository } from '@/models/_.js';
|
||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||
import { QueueService } from '@/core/QueueService.js';
|
||||
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
|
||||
import type { AbuseUserReportsRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { AbuseReportService } from '@/core/AbuseReportService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
@ -18,6 +16,16 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
kind: 'write:admin:resolve-abuse-user-report',
|
||||
|
||||
errors: {
|
||||
noSuchAbuseReport: {
|
||||
message: 'No such abuse report.',
|
||||
code: 'NO_SUCH_ABUSE_REPORT',
|
||||
id: 'ac3794dd-2ce4-d878-e546-73c60c06b398',
|
||||
kind: 'server',
|
||||
httpStatusCode: 404,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -29,47 +37,20 @@ export const paramDef = {
|
|||
required: ['reportId'],
|
||||
} as const;
|
||||
|
||||
// TODO: ロジックをサービスに切り出す
|
||||
|
||||
@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.abuseUserReportsRepository)
|
||||
private abuseUserReportsRepository: AbuseUserReportsRepository,
|
||||
|
||||
private queueService: QueueService,
|
||||
private instanceActorService: InstanceActorService,
|
||||
private apRendererService: ApRendererService,
|
||||
private moderationLogService: ModerationLogService,
|
||||
private abuseReportService: AbuseReportService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const report = await this.abuseUserReportsRepository.findOneBy({ id: ps.reportId });
|
||||
|
||||
if (report == null) {
|
||||
throw new Error('report not found');
|
||||
if (!report) {
|
||||
throw new ApiError(meta.errors.noSuchAbuseReport);
|
||||
}
|
||||
|
||||
if (ps.forward && report.targetUserHost != null) {
|
||||
const actor = await this.instanceActorService.getInstanceActor();
|
||||
const targetUser = await this.usersRepository.findOneByOrFail({ id: report.targetUserId });
|
||||
|
||||
this.queueService.deliver(actor, this.apRendererService.addContext(this.apRendererService.renderFlag(actor, targetUser.uri!, report.comment)), targetUser.inbox, false);
|
||||
}
|
||||
|
||||
await this.abuseUserReportsRepository.update(report.id, {
|
||||
resolved: true,
|
||||
assigneeId: me.id,
|
||||
forwarded: ps.forward && report.targetUserHost != null,
|
||||
});
|
||||
|
||||
this.moderationLogService.log(me, 'resolveAbuseReport', {
|
||||
reportId: report.id,
|
||||
report: report,
|
||||
forwarded: ps.forward && report.targetUserHost != null,
|
||||
});
|
||||
await this.abuseReportService.resolve([{ reportId: report.id, forward: ps.forward }], me);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js';
|
||||
import { systemWebhookEventTypes } from '@/models/SystemWebhook.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'system-webhook'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:system-webhook',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
ref: 'SystemWebhook',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
isActive: {
|
||||
type: 'boolean',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 255,
|
||||
},
|
||||
on: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: systemWebhookEventTypes,
|
||||
},
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 1024,
|
||||
},
|
||||
secret: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 1024,
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'isActive',
|
||||
'name',
|
||||
'on',
|
||||
'url',
|
||||
'secret',
|
||||
],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private systemWebhookService: SystemWebhookService,
|
||||
private systemWebhookEntityService: SystemWebhookEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const result = await this.systemWebhookService.createSystemWebhook(
|
||||
{
|
||||
isActive: ps.isActive,
|
||||
name: ps.name,
|
||||
on: ps.on,
|
||||
url: ps.url,
|
||||
secret: ps.secret,
|
||||
},
|
||||
me,
|
||||
);
|
||||
|
||||
return this.systemWebhookEntityService.pack(result);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'system-webhook'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:system-webhook',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private systemWebhookService: SystemWebhookService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.systemWebhookService.deleteSystemWebhook(
|
||||
ps.id,
|
||||
me,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js';
|
||||
import { systemWebhookEventTypes } from '@/models/SystemWebhook.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'system-webhook'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:system-webhook',
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
ref: 'SystemWebhook',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
isActive: {
|
||||
type: 'boolean',
|
||||
},
|
||||
on: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: systemWebhookEventTypes,
|
||||
},
|
||||
},
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private systemWebhookService: SystemWebhookService,
|
||||
private systemWebhookEntityService: SystemWebhookEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps) => {
|
||||
const webhooks = await this.systemWebhookService.fetchSystemWebhooks({
|
||||
isActive: ps.isActive,
|
||||
on: ps.on,
|
||||
});
|
||||
return this.systemWebhookEntityService.packMany(webhooks);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'system-webhook'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:system-webhook',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
ref: 'SystemWebhook',
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchSystemWebhook: {
|
||||
message: 'No such SystemWebhook.',
|
||||
code: 'NO_SUCH_SYSTEM_WEBHOOK',
|
||||
id: '38dd1ffe-04b4-6ff5-d8ba-4e6a6ae22c9d',
|
||||
kind: 'server',
|
||||
httpStatusCode: 404,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
},
|
||||
required: ['id'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private systemWebhookService: SystemWebhookService,
|
||||
private systemWebhookEntityService: SystemWebhookEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps) => {
|
||||
const webhooks = await this.systemWebhookService.fetchSystemWebhooks({ ids: [ps.id] });
|
||||
if (webhooks.length === 0) {
|
||||
throw new ApiError(meta.errors.noSuchSystemWebhook);
|
||||
}
|
||||
|
||||
return this.systemWebhookEntityService.pack(webhooks[0]);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js';
|
||||
import { systemWebhookEventTypes } from '@/models/SystemWebhook.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin', 'system-webhook'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
secure: true,
|
||||
kind: 'write:admin:system-webhook',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
ref: 'SystemWebhook',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'misskey:id',
|
||||
},
|
||||
isActive: {
|
||||
type: 'boolean',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 255,
|
||||
},
|
||||
on: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: systemWebhookEventTypes,
|
||||
},
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 1024,
|
||||
},
|
||||
secret: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 1024,
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'id',
|
||||
'isActive',
|
||||
'name',
|
||||
'on',
|
||||
'url',
|
||||
'secret',
|
||||
],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private systemWebhookService: SystemWebhookService,
|
||||
private systemWebhookEntityService: SystemWebhookEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const result = await this.systemWebhookService.updateSystemWebhook(
|
||||
{
|
||||
id: ps.id,
|
||||
isActive: ps.isActive,
|
||||
name: ps.name,
|
||||
on: ps.on,
|
||||
url: ps.url,
|
||||
secret: ps.secret,
|
||||
},
|
||||
me,
|
||||
);
|
||||
|
||||
return this.systemWebhookEntityService.pack(result);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -3,17 +3,11 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { AbuseUserReportsRepository } from '@/models/_.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { EmailService } from '@/core/EmailService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { GetterService } from '@/server/api/GetterService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { AbuseReportService } from '@/core/AbuseReportService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
export const meta = {
|
||||
|
@ -57,60 +51,32 @@ export const paramDef = {
|
|||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.abuseUserReportsRepository)
|
||||
private abuseUserReportsRepository: AbuseUserReportsRepository,
|
||||
|
||||
private idService: IdService,
|
||||
private metaService: MetaService,
|
||||
private emailService: EmailService,
|
||||
private getterService: GetterService,
|
||||
private roleService: RoleService,
|
||||
private globalEventService: GlobalEventService,
|
||||
private abuseReportService: AbuseReportService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
// Lookup user
|
||||
const user = await this.getterService.getUser(ps.userId).catch(err => {
|
||||
const targetUser = await this.getterService.getUser(ps.userId).catch(err => {
|
||||
if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
||||
throw err;
|
||||
});
|
||||
|
||||
if (user.id === me.id) {
|
||||
if (targetUser.id === me.id) {
|
||||
throw new ApiError(meta.errors.cannotReportYourself);
|
||||
}
|
||||
|
||||
if (await this.roleService.isAdministrator(user)) {
|
||||
if (await this.roleService.isAdministrator(targetUser)) {
|
||||
throw new ApiError(meta.errors.cannotReportAdmin);
|
||||
}
|
||||
|
||||
const report = await this.abuseUserReportsRepository.insertOne({
|
||||
id: this.idService.gen(),
|
||||
targetUserId: user.id,
|
||||
targetUserHost: user.host,
|
||||
await this.abuseReportService.report([{
|
||||
targetUserId: targetUser.id,
|
||||
targetUserHost: targetUser.host,
|
||||
reporterId: me.id,
|
||||
reporterHost: null,
|
||||
comment: ps.comment,
|
||||
});
|
||||
|
||||
// Publish event to moderators
|
||||
setImmediate(async () => {
|
||||
const moderators = await this.roleService.getModerators();
|
||||
|
||||
for (const moderator of moderators) {
|
||||
this.globalEventService.publishAdminStream(moderator.id, 'newAbuseUserReport', {
|
||||
id: report.id,
|
||||
targetUserId: report.targetUserId,
|
||||
reporterId: report.reporterId,
|
||||
comment: report.comment,
|
||||
});
|
||||
}
|
||||
|
||||
const meta = await this.metaService.fetch();
|
||||
if (meta.email) {
|
||||
this.emailService.sendEmail(meta.email, 'New abuse report',
|
||||
sanitizeHtml(ps.comment),
|
||||
sanitizeHtml(ps.comment));
|
||||
}
|
||||
});
|
||||
}]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,16 @@ import { getNoteSummary } from '@/misc/get-note-summary.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/QueueModule.js';
|
||||
import type {
|
||||
DbQueue,
|
||||
DeliverQueue,
|
||||
EndedPollNotificationQueue,
|
||||
InboxQueue,
|
||||
ObjectStorageQueue,
|
||||
SystemQueue,
|
||||
UserWebhookDeliverQueue,
|
||||
SystemWebhookDeliverQueue,
|
||||
} from '@/core/QueueModule.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { PageEntityService } from '@/core/entities/PageEntityService.js';
|
||||
|
@ -111,7 +120,8 @@ export class ClientServerService {
|
|||
@Inject('queue:inbox') public inboxQueue: InboxQueue,
|
||||
@Inject('queue:db') public dbQueue: DbQueue,
|
||||
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
|
||||
@Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue,
|
||||
@Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue,
|
||||
@Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue,
|
||||
) {
|
||||
//this.createServer = this.createServer.bind(this);
|
||||
}
|
||||
|
@ -239,7 +249,8 @@ export class ClientServerService {
|
|||
this.inboxQueue,
|
||||
this.dbQueue,
|
||||
this.objectStorageQueue,
|
||||
this.webhookDeliverQueue,
|
||||
this.userWebhookDeliverQueue,
|
||||
this.systemWebhookDeliverQueue,
|
||||
].map(q => new BullMQAdapter(q)),
|
||||
serverAdapter,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue