Merge remote-tracking branch 'misskey/master' into feature/misskey-2024.07
This commit is contained in:
commit
cfa9b852df
585 changed files with 23423 additions and 9623 deletions
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private moderationLogService: ModerationLogService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const ad = await this.adsRepository.insert({
|
||||
const ad = await this.adsRepository.insertOne({
|
||||
id: this.idService.gen(),
|
||||
expiresAt: new Date(ps.expiresAt),
|
||||
startsAt: new Date(ps.startsAt),
|
||||
|
|
@ -61,7 +61,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
ratio: ps.ratio,
|
||||
place: ps.place,
|
||||
memo: ps.memo,
|
||||
}).then(r => this.adsRepository.findOneByOrFail({ id: r.identifiers[0].id }));
|
||||
});
|
||||
|
||||
this.moderationLogService.log(me, 'createAd', {
|
||||
adId: ad.id,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export const paramDef = {
|
|||
startsAt: { type: 'integer' },
|
||||
dayOfWeek: { type: 'integer' },
|
||||
},
|
||||
required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'dayOfWeek'],
|
||||
required: ['id'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -63,8 +63,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
ratio: ps.ratio,
|
||||
memo: ps.memo,
|
||||
imageUrl: ps.imageUrl,
|
||||
expiresAt: new Date(ps.expiresAt),
|
||||
startsAt: new Date(ps.startsAt),
|
||||
expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : undefined,
|
||||
startsAt: ps.startsAt ? new Date(ps.startsAt) : undefined,
|
||||
dayOfWeek: ps.dayOfWeek,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export const paramDef = {
|
|||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
userId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
status: { type: 'string', enum: ['all', 'active', 'archived'], default: 'active' },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
|
@ -87,7 +88,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId);
|
||||
query.andWhere('announcement.isActive = true');
|
||||
|
||||
if (ps.status === 'archived') {
|
||||
query.andWhere('announcement.isActive = false');
|
||||
} else if (ps.status === 'active') {
|
||||
query.andWhere('announcement.isActive = true');
|
||||
}
|
||||
|
||||
if (ps.userId) {
|
||||
query.andWhere('announcement.userId = :userId', { userId: ps.userId });
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export const meta = {
|
|||
name: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
example: 'lenna.jpg',
|
||||
example: '192.jpg',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
|
|
|
|||
|
|
@ -66,11 +66,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
const ticketsPromises = [];
|
||||
|
||||
for (let i = 0; i < ps.count; i++) {
|
||||
ticketsPromises.push(this.registrationTicketsRepository.insert({
|
||||
ticketsPromises.push(this.registrationTicketsRepository.insertOne({
|
||||
id: this.idService.gen(),
|
||||
expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : null,
|
||||
code: generateInviteCode(),
|
||||
}).then(x => this.registrationTicketsRepository.findOneByOrFail(x.identifiers[0])));
|
||||
}));
|
||||
}
|
||||
|
||||
const tickets = await Promise.all(ticketsPromises);
|
||||
|
|
|
|||
|
|
@ -132,6 +132,16 @@ export const meta = {
|
|||
nullable: false,
|
||||
},
|
||||
},
|
||||
mediaSilencedHosts: {
|
||||
type: 'array',
|
||||
optional: false,
|
||||
nullable: false,
|
||||
items: {
|
||||
type: 'string',
|
||||
optional: false,
|
||||
nullable: false,
|
||||
},
|
||||
},
|
||||
pinnedUsers: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
|
|
@ -586,6 +596,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
hiddenTags: instance.hiddenTags,
|
||||
blockedHosts: instance.blockedHosts,
|
||||
silencedHosts: instance.silencedHosts,
|
||||
mediaSilencedHosts: instance.mediaSilencedHosts,
|
||||
sensitiveWords: instance.sensitiveWords,
|
||||
prohibitedWords: instance.prohibitedWords,
|
||||
preservedUsernames: instance.preservedUsernames,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { RolesRepository } from '@/models/_.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
|
|
@ -50,19 +49,6 @@ export const paramDef = {
|
|||
},
|
||||
required: [
|
||||
'roleId',
|
||||
'name',
|
||||
'description',
|
||||
'color',
|
||||
'iconUrl',
|
||||
'target',
|
||||
'condFormula',
|
||||
'isPublic',
|
||||
'isModerator',
|
||||
'isAdministrator',
|
||||
'asBadge',
|
||||
'canEditMembersByModerator',
|
||||
'displayOrder',
|
||||
'policies',
|
||||
],
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -158,6 +158,13 @@ export const paramDef = {
|
|||
type: 'string',
|
||||
},
|
||||
},
|
||||
mediaSilencedHosts: {
|
||||
type: 'array',
|
||||
nullable: true,
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
summalyProxy: {
|
||||
type: 'string', nullable: true,
|
||||
description: '[Deprecated] Use "urlPreviewSummaryProxyUrl" instead.',
|
||||
|
|
@ -211,6 +218,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
return h !== '' && h !== lv && !set.blockedHosts?.includes(h);
|
||||
});
|
||||
}
|
||||
if (Array.isArray(ps.mediaSilencedHosts)) {
|
||||
let lastValue = '';
|
||||
set.mediaSilencedHosts = ps.mediaSilencedHosts.sort().filter((h) => {
|
||||
const lv = lastValue;
|
||||
lastValue = h;
|
||||
return h !== '' && h !== lv && !set.blockedHosts?.includes(h);
|
||||
});
|
||||
}
|
||||
if (ps.themeColor !== undefined) {
|
||||
set.themeColor = ps.themeColor;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue