From 8f2049bcd261c3fb10afdc8c15cf4edffe1baa71 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 15 Feb 2023 13:06:06 +0900 Subject: drop messaging (#9919) * drop messaging (from backend) * wip --- packages/backend/src/server/ServerModule.ts | 4 - packages/backend/src/server/api/EndpointsModule.ts | 24 --- packages/backend/src/server/api/endpoints.ts | 12 -- .../api/endpoints/i/read-all-messaging-messages.ts | 56 ------- .../src/server/api/endpoints/messaging/history.ts | 110 ------------- .../src/server/api/endpoints/messaging/messages.ts | 165 ------------------- .../api/endpoints/messaging/messages/create.ts | 179 --------------------- .../api/endpoints/messaging/messages/delete.ts | 61 ------- .../api/endpoints/messaging/messages/read.ts | 61 ------- .../src/server/api/stream/ChannelsService.ts | 8 +- .../src/server/api/stream/channels/channel.ts | 43 ----- .../server/api/stream/channels/messaging-index.ts | 35 ---- .../src/server/api/stream/channels/messaging.ts | 159 ------------------ packages/backend/src/server/api/stream/index.ts | 24 --- packages/backend/src/server/api/stream/types.ts | 46 ------ 15 files changed, 1 insertion(+), 986 deletions(-) delete mode 100644 packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts delete mode 100644 packages/backend/src/server/api/endpoints/messaging/history.ts delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages.ts delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages/create.ts delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages/delete.ts delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages/read.ts delete mode 100644 packages/backend/src/server/api/stream/channels/messaging-index.ts delete mode 100644 packages/backend/src/server/api/stream/channels/messaging.ts (limited to 'packages/backend/src/server') diff --git a/packages/backend/src/server/ServerModule.ts b/packages/backend/src/server/ServerModule.ts index b605f3c8ab..a5a5f9e7f9 100644 --- a/packages/backend/src/server/ServerModule.ts +++ b/packages/backend/src/server/ServerModule.ts @@ -30,8 +30,6 @@ import { HashtagChannelService } from './api/stream/channels/hashtag.js'; import { HomeTimelineChannelService } from './api/stream/channels/home-timeline.js'; import { HybridTimelineChannelService } from './api/stream/channels/hybrid-timeline.js'; import { LocalTimelineChannelService } from './api/stream/channels/local-timeline.js'; -import { MessagingIndexChannelService } from './api/stream/channels/messaging-index.js'; -import { MessagingChannelService } from './api/stream/channels/messaging.js'; import { QueueStatsChannelService } from './api/stream/channels/queue-stats.js'; import { ServerStatsChannelService } from './api/stream/channels/server-stats.js'; import { UserListChannelService } from './api/stream/channels/user-list.js'; @@ -71,8 +69,6 @@ import { UserListChannelService } from './api/stream/channels/user-list.js'; HomeTimelineChannelService, HybridTimelineChannelService, LocalTimelineChannelService, - MessagingIndexChannelService, - MessagingChannelService, QueueStatsChannelService, ServerStatsChannelService, UserListChannelService, diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 4a55c6cbe3..933dcbebe6 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -195,7 +195,6 @@ import * as ep___i_notifications from './endpoints/i/notifications.js'; import * as ep___i_pageLikes from './endpoints/i/page-likes.js'; import * as ep___i_pages from './endpoints/i/pages.js'; import * as ep___i_pin from './endpoints/i/pin.js'; -import * as ep___i_readAllMessagingMessages from './endpoints/i/read-all-messaging-messages.js'; import * as ep___i_readAllUnreadNotes from './endpoints/i/read-all-unread-notes.js'; import * as ep___i_readAnnouncement from './endpoints/i/read-announcement.js'; import * as ep___i_regenerateToken from './endpoints/i/regenerate-token.js'; @@ -218,11 +217,6 @@ import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js'; import * as ep___i_webhooks_list from './endpoints/i/webhooks/list.js'; import * as ep___i_webhooks_update from './endpoints/i/webhooks/update.js'; import * as ep___i_webhooks_delete from './endpoints/i/webhooks/delete.js'; -import * as ep___messaging_history from './endpoints/messaging/history.js'; -import * as ep___messaging_messages from './endpoints/messaging/messages.js'; -import * as ep___messaging_messages_create from './endpoints/messaging/messages/create.js'; -import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js'; -import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js'; import * as ep___meta from './endpoints/meta.js'; import * as ep___emojis from './endpoints/emojis.js'; import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js'; @@ -530,7 +524,6 @@ const $i_notifications: Provider = { provide: 'ep:i/notifications', useClass: ep const $i_pageLikes: Provider = { provide: 'ep:i/page-likes', useClass: ep___i_pageLikes.default }; const $i_pages: Provider = { provide: 'ep:i/pages', useClass: ep___i_pages.default }; const $i_pin: Provider = { provide: 'ep:i/pin', useClass: ep___i_pin.default }; -const $i_readAllMessagingMessages: Provider = { provide: 'ep:i/read-all-messaging-messages', useClass: ep___i_readAllMessagingMessages.default }; const $i_readAllUnreadNotes: Provider = { provide: 'ep:i/read-all-unread-notes', useClass: ep___i_readAllUnreadNotes.default }; const $i_readAnnouncement: Provider = { provide: 'ep:i/read-announcement', useClass: ep___i_readAnnouncement.default }; const $i_regenerateToken: Provider = { provide: 'ep:i/regenerate-token', useClass: ep___i_regenerateToken.default }; @@ -553,11 +546,6 @@ const $i_webhooks_list: Provider = { provide: 'ep:i/webhooks/list', useClass: ep const $i_webhooks_show: Provider = { provide: 'ep:i/webhooks/show', useClass: ep___i_webhooks_show.default }; const $i_webhooks_update: Provider = { provide: 'ep:i/webhooks/update', useClass: ep___i_webhooks_update.default }; const $i_webhooks_delete: Provider = { provide: 'ep:i/webhooks/delete', useClass: ep___i_webhooks_delete.default }; -const $messaging_history: Provider = { provide: 'ep:messaging/history', useClass: ep___messaging_history.default }; -const $messaging_messages: Provider = { provide: 'ep:messaging/messages', useClass: ep___messaging_messages.default }; -const $messaging_messages_create: Provider = { provide: 'ep:messaging/messages/create', useClass: ep___messaging_messages_create.default }; -const $messaging_messages_delete: Provider = { provide: 'ep:messaging/messages/delete', useClass: ep___messaging_messages_delete.default }; -const $messaging_messages_read: Provider = { provide: 'ep:messaging/messages/read', useClass: ep___messaging_messages_read.default }; const $meta: Provider = { provide: 'ep:meta', useClass: ep___meta.default }; const $emojis: Provider = { provide: 'ep:emojis', useClass: ep___emojis.default }; const $miauth_genToken: Provider = { provide: 'ep:miauth/gen-token', useClass: ep___miauth_genToken.default }; @@ -869,7 +857,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_pageLikes, $i_pages, $i_pin, - $i_readAllMessagingMessages, $i_readAllUnreadNotes, $i_readAnnouncement, $i_regenerateToken, @@ -892,11 +879,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_webhooks_show, $i_webhooks_update, $i_webhooks_delete, - $messaging_history, - $messaging_messages, - $messaging_messages_create, - $messaging_messages_delete, - $messaging_messages_read, $meta, $emojis, $miauth_genToken, @@ -1202,7 +1184,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_pageLikes, $i_pages, $i_pin, - $i_readAllMessagingMessages, $i_readAllUnreadNotes, $i_readAnnouncement, $i_regenerateToken, @@ -1225,11 +1206,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_webhooks_show, $i_webhooks_update, $i_webhooks_delete, - $messaging_history, - $messaging_messages, - $messaging_messages_create, - $messaging_messages_delete, - $messaging_messages_read, $meta, $emojis, $miauth_genToken, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 55e1900d51..639cf30195 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -194,7 +194,6 @@ import * as ep___i_notifications from './endpoints/i/notifications.js'; import * as ep___i_pageLikes from './endpoints/i/page-likes.js'; import * as ep___i_pages from './endpoints/i/pages.js'; import * as ep___i_pin from './endpoints/i/pin.js'; -import * as ep___i_readAllMessagingMessages from './endpoints/i/read-all-messaging-messages.js'; import * as ep___i_readAllUnreadNotes from './endpoints/i/read-all-unread-notes.js'; import * as ep___i_readAnnouncement from './endpoints/i/read-announcement.js'; import * as ep___i_regenerateToken from './endpoints/i/regenerate-token.js'; @@ -217,11 +216,6 @@ import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js'; import * as ep___i_webhooks_list from './endpoints/i/webhooks/list.js'; import * as ep___i_webhooks_update from './endpoints/i/webhooks/update.js'; import * as ep___i_webhooks_delete from './endpoints/i/webhooks/delete.js'; -import * as ep___messaging_history from './endpoints/messaging/history.js'; -import * as ep___messaging_messages from './endpoints/messaging/messages.js'; -import * as ep___messaging_messages_create from './endpoints/messaging/messages/create.js'; -import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js'; -import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js'; import * as ep___meta from './endpoints/meta.js'; import * as ep___emojis from './endpoints/emojis.js'; import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js'; @@ -527,7 +521,6 @@ const eps = [ ['i/page-likes', ep___i_pageLikes], ['i/pages', ep___i_pages], ['i/pin', ep___i_pin], - ['i/read-all-messaging-messages', ep___i_readAllMessagingMessages], ['i/read-all-unread-notes', ep___i_readAllUnreadNotes], ['i/read-announcement', ep___i_readAnnouncement], ['i/regenerate-token', ep___i_regenerateToken], @@ -550,11 +543,6 @@ const eps = [ ['i/webhooks/show', ep___i_webhooks_show], ['i/webhooks/update', ep___i_webhooks_update], ['i/webhooks/delete', ep___i_webhooks_delete], - ['messaging/history', ep___messaging_history], - ['messaging/messages', ep___messaging_messages], - ['messaging/messages/create', ep___messaging_messages_create], - ['messaging/messages/delete', ep___messaging_messages_delete], - ['messaging/messages/read', ep___messaging_messages_read], ['meta', ep___meta], ['emojis', ep___emojis], ['miauth/gen-token', ep___miauth_genToken], diff --git a/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts b/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts deleted file mode 100644 index 109d6d1068..0000000000 --- a/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { MessagingMessagesRepository, UserGroupJoiningsRepository } from '@/models/index.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { DI } from '@/di-symbols.js'; - -export const meta = { - tags: ['account', 'messaging'], - - requireCredential: true, - - kind: 'write:account', -} as const; - -export const paramDef = { - type: 'object', - properties: {}, - required: [], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - @Inject(DI.userGroupJoiningsRepository) - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - - private globalEventService: GlobalEventService, - ) { - super(meta, paramDef, async (ps, me) => { - // Update documents - await this.messagingMessagesRepository.update({ - recipientId: me.id, - isRead: false, - }, { - isRead: true, - }); - - const joinings = await this.userGroupJoiningsRepository.findBy({ userId: me.id }); - - await Promise.all(joinings.map(j => this.messagingMessagesRepository.createQueryBuilder().update() - .set({ - reads: (() => `array_append("reads", '${me.id}')`) as any, - }) - .where('groupId = :groupId', { groupId: j.userGroupId }) - .andWhere('userId != :userId', { userId: me.id }) - .andWhere('NOT (:userId = ANY(reads))', { userId: me.id }) - .execute())); - - this.globalEventService.publishMainStream(me.id, 'readAllMessagingMessages'); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/messaging/history.ts b/packages/backend/src/server/api/endpoints/messaging/history.ts deleted file mode 100644 index 0b6099d4ac..0000000000 --- a/packages/backend/src/server/api/endpoints/messaging/history.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { Brackets } from 'typeorm'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { MessagingMessage } from '@/models/entities/MessagingMessage.js'; -import type { MutingsRepository, UserGroupJoiningsRepository, MessagingMessagesRepository } from '@/models/index.js'; -import { MessagingMessageEntityService } from '@/core/entities/MessagingMessageEntityService.js'; -import { DI } from '@/di-symbols.js'; - -export const meta = { - tags: ['messaging'], - - requireCredential: true, - - kind: 'read:messaging', - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'MessagingMessage', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - group: { type: 'boolean', default: false }, - }, - required: [], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - @Inject(DI.mutingsRepository) - private mutingsRepository: MutingsRepository, - - @Inject(DI.userGroupJoiningsRepository) - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - - private messagingMessageEntityService: MessagingMessageEntityService, - ) { - super(meta, paramDef, async (ps, me) => { - const mute = await this.mutingsRepository.findBy({ - muterId: me.id, - }); - - const groups = ps.group ? await this.userGroupJoiningsRepository.findBy({ - userId: me.id, - }).then(xs => xs.map(x => x.userGroupId)) : []; - - if (ps.group && groups.length === 0) { - return []; - } - - const history: MessagingMessage[] = []; - - for (let i = 0; i < ps.limit; i++) { - const found = ps.group - ? history.map(m => m.groupId!) - : history.map(m => (m.userId === me.id) ? m.recipientId! : m.userId!); - - const query = this.messagingMessagesRepository.createQueryBuilder('message') - .orderBy('message.createdAt', 'DESC'); - - if (ps.group) { - query.where('message.groupId IN (:...groups)', { groups: groups }); - - if (found.length > 0) { - query.andWhere('message.groupId NOT IN (:...found)', { found: found }); - } - } else { - query.where(new Brackets(qb => { qb - .where('message.userId = :userId', { userId: me.id }) - .orWhere('message.recipientId = :userId', { userId: me.id }); - })); - query.andWhere('message.groupId IS NULL'); - - if (found.length > 0) { - query.andWhere('message.userId NOT IN (:...found)', { found: found }); - query.andWhere('message.recipientId NOT IN (:...found)', { found: found }); - } - - if (mute.length > 0) { - query.andWhere('message.userId NOT IN (:...mute)', { mute: mute.map(m => m.muteeId) }); - query.andWhere('message.recipientId NOT IN (:...mute)', { mute: mute.map(m => m.muteeId) }); - } - } - - const message = await query.getOne(); - - if (message) { - history.push(message); - } else { - break; - } - } - - return await Promise.all(history.map(h => this.messagingMessageEntityService.pack(h.id, me))); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/messaging/messages.ts b/packages/backend/src/server/api/endpoints/messaging/messages.ts deleted file mode 100644 index 3673e252ae..0000000000 --- a/packages/backend/src/server/api/endpoints/messaging/messages.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { Brackets } from 'typeorm'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, UserGroupsRepository, MessagingMessagesRepository, UserGroupJoiningsRepository } from '@/models/index.js'; -import { QueryService } from '@/core/QueryService.js'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { MessagingMessageEntityService } from '@/core/entities/MessagingMessageEntityService.js'; -import { MessagingService } from '@/core/MessagingService.js'; -import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; -import { GetterService } from '@/server/api/GetterService.js'; - -export const meta = { - tags: ['messaging'], - - requireCredential: true, - - kind: 'read:messaging', - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'MessagingMessage', - }, - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '11795c64-40ea-4198-b06e-3c873ed9039d', - }, - - noSuchGroup: { - message: 'No such group.', - code: 'NO_SUCH_GROUP', - id: 'c4d9f88c-9270-4632-b032-6ed8cee36f7f', - }, - - groupAccessDenied: { - message: 'You can not read messages of groups that you have not joined.', - code: 'GROUP_ACCESS_DENIED', - id: 'a053a8dd-a491-4718-8f87-50775aad9284', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - markAsRead: { type: 'boolean', default: true }, - }, - anyOf: [ - { - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], - }, - { - properties: { - groupId: { type: 'string', format: 'misskey:id' }, - }, - required: ['groupId'], - }, - ], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - @Inject(DI.userGroupsRepository) - private userGroupRepository: UserGroupsRepository, - - @Inject(DI.userGroupJoiningsRepository) - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - - private messagingMessageEntityService: MessagingMessageEntityService, - private messagingService: MessagingService, - private userEntityService: UserEntityService, - private queryService: QueryService, - private getterService: GetterService, - ) { - super(meta, paramDef, async (ps, me) => { - if (ps.userId != null) { - // Fetch recipient (user) - const recipient = await this.getterService.getUser(ps.userId).catch(err => { - if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw err; - }); - - const query = this.queryService.makePaginationQuery(this.messagingMessagesRepository.createQueryBuilder('message'), ps.sinceId, ps.untilId) - .andWhere(new Brackets(qb => { qb - .where(new Brackets(qb => { qb - .where('message.userId = :meId') - .andWhere('message.recipientId = :recipientId'); - })) - .orWhere(new Brackets(qb => { qb - .where('message.userId = :recipientId') - .andWhere('message.recipientId = :meId'); - })); - })) - .setParameter('meId', me.id) - .setParameter('recipientId', recipient.id); - - const messages = await query.take(ps.limit).getMany(); - - // Mark all as read - if (ps.markAsRead) { - this.messagingService.readUserMessagingMessage(me.id, recipient.id, messages.filter(m => m.recipientId === me.id).map(x => x.id)); - - // リモートユーザーとのメッセージだったら既読配信 - if (this.userEntityService.isLocalUser(me) && this.userEntityService.isRemoteUser(recipient)) { - this.messagingService.deliverReadActivity(me, recipient, messages); - } - } - - return await Promise.all(messages.map(message => this.messagingMessageEntityService.pack(message, me, { - populateRecipient: false, - }))); - } else if (ps.groupId != null) { - // Fetch recipient (group) - const recipientGroup = await this.userGroupRepository.findOneBy({ id: ps.groupId }); - - if (recipientGroup == null) { - throw new ApiError(meta.errors.noSuchGroup); - } - - // check joined - const joining = await this.userGroupJoiningsRepository.findOneBy({ - userId: me.id, - userGroupId: recipientGroup.id, - }); - - if (joining == null) { - throw new ApiError(meta.errors.groupAccessDenied); - } - - const query = this.queryService.makePaginationQuery(this.messagingMessagesRepository.createQueryBuilder('message'), ps.sinceId, ps.untilId) - .andWhere('message.groupId = :groupId', { groupId: recipientGroup.id }); - - const messages = await query.take(ps.limit).getMany(); - - // Mark all as read - if (ps.markAsRead) { - this.messagingService.readGroupMessagingMessage(me.id, recipientGroup.id, messages.map(x => x.id)); - } - - return await Promise.all(messages.map(message => this.messagingMessageEntityService.pack(message, me, { - populateGroup: false, - }))); - } - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/create.ts b/packages/backend/src/server/api/endpoints/messaging/messages/create.ts deleted file mode 100644 index e9ffc7a9eb..0000000000 --- a/packages/backend/src/server/api/endpoints/messaging/messages/create.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import ms from 'ms'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { BlockingsRepository, UserGroupJoiningsRepository, DriveFilesRepository, UserGroupsRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; -import type { UserGroup } from '@/models/entities/UserGroup.js'; -import { GetterService } from '@/server/api/GetterService.js'; -import { MessagingService } from '@/core/MessagingService.js'; -import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../../error.js'; - -export const meta = { - tags: ['messaging'], - - requireCredential: true, - - kind: 'write:messaging', - - limit: { - duration: ms('1hour'), - max: 120, - }, - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'MessagingMessage', - }, - - errors: { - recipientIsYourself: { - message: 'You can not send a message to yourself.', - code: 'RECIPIENT_IS_YOURSELF', - id: '17e2ba79-e22a-4cbc-bf91-d327643f4a7e', - }, - - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '11795c64-40ea-4198-b06e-3c873ed9039d', - }, - - noSuchGroup: { - message: 'No such group.', - code: 'NO_SUCH_GROUP', - id: 'c94e2a5d-06aa-4914-8fa6-6a42e73d6537', - }, - - groupAccessDenied: { - message: 'You can not send messages to groups that you have not joined.', - code: 'GROUP_ACCESS_DENIED', - id: 'd96b3cca-5ad1-438b-ad8b-02f931308fbd', - }, - - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: '4372b8e2-185d-4146-8749-2f68864a3e5f', - }, - - contentRequired: { - message: 'Content required. You need to set text or fileId.', - code: 'CONTENT_REQUIRED', - id: '25587321-b0e6-449c-9239-f8925092942c', - }, - - youHaveBeenBlocked: { - message: 'You cannot send a message because you have been blocked by this user.', - code: 'YOU_HAVE_BEEN_BLOCKED', - id: 'c15a5199-7422-4968-941a-2a462c478f7d', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - text: { type: 'string', nullable: true, maxLength: 3000 }, - fileId: { type: 'string', format: 'misskey:id' }, - }, - anyOf: [ - { - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], - }, - { - properties: { - groupId: { type: 'string', format: 'misskey:id' }, - }, - required: ['groupId'], - }, - ], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.userGroupsRepository) - private userGroupsRepository: UserGroupsRepository, - - @Inject(DI.userGroupJoiningsRepository) - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - - @Inject(DI.blockingsRepository) - private blockingsRepository: BlockingsRepository, - - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - - private getterService: GetterService, - private messagingService: MessagingService, - ) { - super(meta, paramDef, async (ps, me) => { - let recipientUser: User | null; - let recipientGroup: UserGroup | null; - - if (ps.userId != null) { - // Myself - if (ps.userId === me.id) { - throw new ApiError(meta.errors.recipientIsYourself); - } - - // Fetch recipient (user) - recipientUser = await this.getterService.getUser(ps.userId).catch(err => { - if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw err; - }); - - // Check blocking - const block = await this.blockingsRepository.findOneBy({ - blockerId: recipientUser.id, - blockeeId: me.id, - }); - if (block) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } else if (ps.groupId != null) { - // Fetch recipient (group) - recipientGroup = await this.userGroupsRepository.findOneBy({ id: ps.groupId! }); - - if (recipientGroup == null) { - throw new ApiError(meta.errors.noSuchGroup); - } - - // check joined - const joining = await this.userGroupJoiningsRepository.findOneBy({ - userId: me.id, - userGroupId: recipientGroup.id, - }); - - if (joining == null) { - throw new ApiError(meta.errors.groupAccessDenied); - } - } - - let file = null; - if (ps.fileId != null) { - file = await this.driveFilesRepository.findOneBy({ - id: ps.fileId, - userId: me.id, - }); - - if (file == null) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - // テキストが無いかつ添付ファイルも無かったらエラー - if (ps.text == null && file == null) { - throw new ApiError(meta.errors.contentRequired); - } - - return await this.messagingService.createMessage(me, recipientUser, recipientGroup, ps.text, file); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts b/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts deleted file mode 100644 index cd74f5f197..0000000000 --- a/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import ms from 'ms'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { MessagingMessagesRepository } from '@/models/index.js'; -import { MessagingService } from '@/core/MessagingService.js'; -import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../../error.js'; - -export const meta = { - tags: ['messaging'], - - requireCredential: true, - - kind: 'write:messaging', - - limit: { - duration: ms('1hour'), - max: 300, - minInterval: ms('1sec'), - }, - - errors: { - noSuchMessage: { - message: 'No such message.', - code: 'NO_SUCH_MESSAGE', - id: '54b5b326-7925-42cf-8019-130fda8b56af', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - messageId: { type: 'string', format: 'misskey:id' }, - }, - required: ['messageId'], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - private messagingService: MessagingService, - ) { - super(meta, paramDef, async (ps, me) => { - const message = await this.messagingMessagesRepository.findOneBy({ - id: ps.messageId, - userId: me.id, - }); - - if (message == null) { - throw new ApiError(meta.errors.noSuchMessage); - } - - await this.messagingService.deleteMessage(message); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/read.ts b/packages/backend/src/server/api/endpoints/messaging/messages/read.ts deleted file mode 100644 index bddb6d932d..0000000000 --- a/packages/backend/src/server/api/endpoints/messaging/messages/read.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { MessagingMessagesRepository } from '@/models/index.js'; -import { MessagingService } from '@/core/MessagingService.js'; -import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../../error.js'; - -export const meta = { - tags: ['messaging'], - - requireCredential: true, - - kind: 'write:messaging', - - errors: { - noSuchMessage: { - message: 'No such message.', - code: 'NO_SUCH_MESSAGE', - id: '86d56a2f-a9c3-4afb-b13c-3e9bfef9aa14', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - messageId: { type: 'string', format: 'misskey:id' }, - }, - required: ['messageId'], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - private messagingService: MessagingService, - ) { - super(meta, paramDef, async (ps, me) => { - const message = await this.messagingMessagesRepository.findOneBy({ id: ps.messageId }); - - if (message == null) { - throw new ApiError(meta.errors.noSuchMessage); - } - - if (message.recipientId) { - await this.messagingService.readUserMessagingMessage(me.id, message.userId, [message.id]).catch(err => { - if (err.id === 'e140a4bf-49ce-4fb6-b67c-b78dadf6b52f') throw new ApiError(meta.errors.noSuchMessage); - throw err; - }); - } else if (message.groupId) { - await this.messagingService.readGroupMessagingMessage(me.id, message.groupId, [message.id]).catch(err => { - if (err.id === '930a270c-714a-46b2-b776-ad27276dc569') throw new ApiError(meta.errors.noSuchMessage); - throw err; - }); - } - }); - } -} diff --git a/packages/backend/src/server/api/stream/ChannelsService.ts b/packages/backend/src/server/api/stream/ChannelsService.ts index 198fc190d4..6ca7bdf623 100644 --- a/packages/backend/src/server/api/stream/ChannelsService.ts +++ b/packages/backend/src/server/api/stream/ChannelsService.ts @@ -1,5 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; +import { bindThis } from '@/decorators.js'; import { HybridTimelineChannelService } from './channels/hybrid-timeline.js'; import { LocalTimelineChannelService } from './channels/local-timeline.js'; import { HomeTimelineChannelService } from './channels/home-timeline.js'; @@ -11,11 +12,8 @@ import { ServerStatsChannelService } from './channels/server-stats.js'; import { QueueStatsChannelService } from './channels/queue-stats.js'; import { UserListChannelService } from './channels/user-list.js'; import { AntennaChannelService } from './channels/antenna.js'; -import { MessagingChannelService } from './channels/messaging.js'; -import { MessagingIndexChannelService } from './channels/messaging-index.js'; import { DriveChannelService } from './channels/drive.js'; import { HashtagChannelService } from './channels/hashtag.js'; -import { bindThis } from '@/decorators.js'; @Injectable() export class ChannelsService { @@ -29,8 +27,6 @@ export class ChannelsService { private hashtagChannelService: HashtagChannelService, private antennaChannelService: AntennaChannelService, private channelChannelService: ChannelChannelService, - private messagingChannelService: MessagingChannelService, - private messagingIndexChannelService: MessagingIndexChannelService, private driveChannelService: DriveChannelService, private serverStatsChannelService: ServerStatsChannelService, private queueStatsChannelService: QueueStatsChannelService, @@ -50,8 +46,6 @@ export class ChannelsService { case 'hashtag': return this.hashtagChannelService; case 'antenna': return this.antennaChannelService; case 'channel': return this.channelChannelService; - case 'messaging': return this.messagingChannelService; - case 'messagingIndex': return this.messagingIndexChannelService; case 'drive': return this.driveChannelService; case 'serverStats': return this.serverStatsChannelService; case 'queueStats': return this.queueStatsChannelService; diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts index 5ba84e43c4..589c294372 100644 --- a/packages/backend/src/server/api/stream/channels/channel.ts +++ b/packages/backend/src/server/api/stream/channels/channel.ts @@ -1,32 +1,25 @@ import { Inject, Injectable } from '@nestjs/common'; -import type { NotesRepository, UsersRepository } from '@/models/index.js'; import { isUserRelated } from '@/misc/is-user-related.js'; -import type { User } from '@/models/entities/User.js'; import type { Packed } from '@/misc/schema.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; import Channel from '../channel.js'; -import type { StreamMessages } from '../types.js'; class ChannelChannel extends Channel { public readonly chName = 'channel'; public static shouldShare = false; public static requireCredential = false; private channelId: string; - private typers: Record = {}; - private emitTypersIntervalId: ReturnType; constructor( private noteEntityService: NoteEntityService, - private userEntityService: UserEntityService, id: string, connection: Channel['connection'], ) { super(id, connection); //this.onNote = this.onNote.bind(this); - //this.emitTypers = this.emitTypers.bind(this); } @bindThis @@ -35,8 +28,6 @@ class ChannelChannel extends Channel { // Subscribe stream this.subscriber.on('notesStream', this.onNote); - this.subscriber.on(`channelStream:${this.channelId}`, this.onEvent); - this.emitTypersIntervalId = setInterval(this.emitTypers, 5000); } @bindThis @@ -66,42 +57,10 @@ class ChannelChannel extends Channel { this.send('note', note); } - @bindThis - private onEvent(data: StreamMessages['channel']['payload']) { - if (data.type === 'typing') { - const id = data.body; - const begin = this.typers[id] == null; - this.typers[id] = new Date(); - if (begin) { - this.emitTypers(); - } - } - } - - @bindThis - private async emitTypers() { - const now = new Date(); - - // Remove not typing users - for (const [userId, date] of Object.entries(this.typers)) { - if (now.getTime() - date.getTime() > 5000) delete this.typers[userId]; - } - - const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { detail: false }); - - this.send({ - type: 'typers', - body: users, - }); - } - @bindThis public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); - this.subscriber.off(`channelStream:${this.channelId}`, this.onEvent); - - clearInterval(this.emitTypersIntervalId); } } @@ -112,7 +71,6 @@ export class ChannelChannelService { constructor( private noteEntityService: NoteEntityService, - private userEntityService: UserEntityService, ) { } @@ -120,7 +78,6 @@ export class ChannelChannelService { public create(id: string, connection: Channel['connection']): ChannelChannel { return new ChannelChannel( this.noteEntityService, - this.userEntityService, id, connection, ); diff --git a/packages/backend/src/server/api/stream/channels/messaging-index.ts b/packages/backend/src/server/api/stream/channels/messaging-index.ts deleted file mode 100644 index 66cb79f7a7..0000000000 --- a/packages/backend/src/server/api/stream/channels/messaging-index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { bindThis } from '@/decorators.js'; -import Channel from '../channel.js'; - -class MessagingIndexChannel extends Channel { - public readonly chName = 'messagingIndex'; - public static shouldShare = true; - public static requireCredential = true; - - @bindThis - public async init(params: any) { - // Subscribe messaging index stream - this.subscriber.on(`messagingIndexStream:${this.user!.id}`, data => { - this.send(data); - }); - } -} - -@Injectable() -export class MessagingIndexChannelService { - public readonly shouldShare = MessagingIndexChannel.shouldShare; - public readonly requireCredential = MessagingIndexChannel.requireCredential; - - constructor( - ) { - } - - @bindThis - public create(id: string, connection: Channel['connection']): MessagingIndexChannel { - return new MessagingIndexChannel( - id, - connection, - ); - } -} diff --git a/packages/backend/src/server/api/stream/channels/messaging.ts b/packages/backend/src/server/api/stream/channels/messaging.ts deleted file mode 100644 index b544e297c5..0000000000 --- a/packages/backend/src/server/api/stream/channels/messaging.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import type { UserGroupJoiningsRepository, UsersRepository, MessagingMessagesRepository } from '@/models/index.js'; -import type { User, LocalUser, RemoteUser } from '@/models/entities/User.js'; -import type { UserGroup } from '@/models/entities/UserGroup.js'; -import { MessagingService } from '@/core/MessagingService.js'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { DI } from '@/di-symbols.js'; -import { bindThis } from '@/decorators.js'; -import Channel from '../channel.js'; -import type { StreamMessages } from '../types.js'; - -class MessagingChannel extends Channel { - public readonly chName = 'messaging'; - public static shouldShare = false; - public static requireCredential = true; - - private otherpartyId: string | null; - private otherparty: User | null; - private groupId: string | null; - private subCh: `messagingStream:${User['id']}-${User['id']}` | `messagingStream:${UserGroup['id']}`; - private typers: Record = {}; - private emitTypersIntervalId: ReturnType; - - constructor( - private usersRepository: UsersRepository, - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - private messagingMessagesRepository: MessagingMessagesRepository, - private userEntityService: UserEntityService, - private messagingService: MessagingService, - - id: string, - connection: Channel['connection'], - ) { - super(id, connection); - //this.onEvent = this.onEvent.bind(this); - //this.onMessage = this.onMessage.bind(this); - //this.emitTypers = this.emitTypers.bind(this); - } - - @bindThis - public async init(params: any) { - this.otherpartyId = params.otherparty; - this.otherparty = this.otherpartyId ? await this.usersRepository.findOneByOrFail({ id: this.otherpartyId }) : null; - this.groupId = params.group; - - // Check joining - if (this.groupId) { - const joining = await this.userGroupJoiningsRepository.findOneBy({ - userId: this.user!.id, - userGroupId: this.groupId, - }); - - if (joining == null) { - return; - } - } - - this.emitTypersIntervalId = setInterval(this.emitTypers, 5000); - - this.subCh = this.otherpartyId - ? `messagingStream:${this.user!.id}-${this.otherpartyId}` - : `messagingStream:${this.groupId}`; - - // Subscribe messaging stream - this.subscriber.on(this.subCh, this.onEvent); - } - - @bindThis - private onEvent(data: StreamMessages['messaging']['payload'] | StreamMessages['groupMessaging']['payload']) { - if (data.type === 'typing') { - const id = data.body; - const begin = this.typers[id] == null; - this.typers[id] = new Date(); - if (begin) { - this.emitTypers(); - } - } else { - this.send(data); - } - } - - @bindThis - public onMessage(type: string, body: any) { - switch (type) { - case 'read': - if (this.otherpartyId) { - this.messagingService.readUserMessagingMessage(this.user!.id, this.otherpartyId, [body.id]); - - // リモートユーザーからのメッセージだったら既読配信 - if (this.userEntityService.isLocalUser(this.user!) && this.userEntityService.isRemoteUser(this.otherparty!)) { - this.messagingMessagesRepository.findOneBy({ id: body.id }).then(message => { - if (message) this.messagingService.deliverReadActivity(this.user as LocalUser, this.otherparty as RemoteUser, message); - }); - } - } else if (this.groupId) { - this.messagingService.readGroupMessagingMessage(this.user!.id, this.groupId, [body.id]); - } - break; - } - } - - @bindThis - private async emitTypers() { - const now = new Date(); - - // Remove not typing users - for (const [userId, date] of Object.entries(this.typers)) { - if (now.getTime() - date.getTime() > 5000) delete this.typers[userId]; - } - - const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { detail: false }); - - this.send({ - type: 'typers', - body: users, - }); - } - - @bindThis - public dispose() { - this.subscriber.off(this.subCh, this.onEvent); - - clearInterval(this.emitTypersIntervalId); - } -} - -@Injectable() -export class MessagingChannelService { - public readonly shouldShare = MessagingChannel.shouldShare; - public readonly requireCredential = MessagingChannel.requireCredential; - - constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.userGroupJoiningsRepository) - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - private userEntityService: UserEntityService, - private messagingService: MessagingService, - ) { - } - - @bindThis - public create(id: string, connection: Channel['connection']): MessagingChannel { - return new MessagingChannel( - this.usersRepository, - this.userGroupJoiningsRepository, - this.messagingMessagesRepository, - this.userEntityService, - this.messagingService, - id, - connection, - ); - } -} diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts index 6763953f9d..fea06c0315 100644 --- a/packages/backend/src/server/api/stream/index.ts +++ b/packages/backend/src/server/api/stream/index.ts @@ -147,12 +147,6 @@ export default class Connection { case 'disconnect': this.onChannelDisconnectRequested(body); break; case 'channel': this.onChannelMessageRequested(body); break; case 'ch': this.onChannelMessageRequested(body); break; // alias - - // 個々のチャンネルではなくルートレベルでこれらのメッセージを受け取る理由は、 - // クライアントの事情を考慮したとき、入力フォームはノートチャンネルやメッセージのメインコンポーネントとは別 - // なこともあるため、それらのコンポーネントがそれぞれ各チャンネルに接続するようにするのは面倒なため。 - case 'typingOnChannel': this.typingOnChannel(body.channel); break; - case 'typingOnMessaging': this.typingOnMessaging(body); break; } } @@ -325,24 +319,6 @@ export default class Connection { } } - @bindThis - private typingOnChannel(channel: ChannelModel['id']) { - if (this.user) { - this.globalEventService.publishChannelStream(channel, 'typing', this.user.id); - } - } - - @bindThis - private typingOnMessaging(param: { partner?: User['id']; group?: UserGroup['id']; }) { - if (this.user) { - if (param.partner) { - this.globalEventService.publishMessagingStream(param.partner, this.user.id, 'typing', this.user.id); - } else if (param.group) { - this.globalEventService.publishGroupMessagingStream(param.group, 'typing', this.user.id); - } - } - } - @bindThis private async updateFollowing() { const followings = await this.followingsRepository.find({ diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index 8bb4147b43..3d8cfea9d3 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -6,7 +6,6 @@ import type { Antenna } from '@/models/entities/Antenna.js'; import type { DriveFile } from '@/models/entities/DriveFile.js'; import type { DriveFolder } from '@/models/entities/DriveFolder.js'; import type { UserList } from '@/models/entities/UserList.js'; -import type { MessagingMessage } from '@/models/entities/MessagingMessage.js'; import type { UserGroup } from '@/models/entities/UserGroup.js'; import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js'; import type { Signin } from '@/models/entities/Signin.js'; @@ -96,9 +95,6 @@ export interface MainStreamTypes { readAllUnreadMentions: undefined; unreadSpecifiedNote: Note['id']; readAllUnreadSpecifiedNotes: undefined; - readAllMessagingMessages: undefined; - messagingMessage: Packed<'MessagingMessage'>; - unreadMessagingMessage: Packed<'MessagingMessage'>; readAllAntennas: undefined; unreadAntenna: Antenna; readAllAnnouncements: undefined; @@ -153,10 +149,6 @@ type NoteStreamEventTypes = { }; }; -export interface ChannelStreamTypes { - typing: User['id']; -} - export interface UserListStreamTypes { userAdded: Packed<'User'>; userRemoved: Packed<'User'>; @@ -166,28 +158,6 @@ export interface AntennaStreamTypes { note: Note; } -export interface MessagingStreamTypes { - read: MessagingMessage['id'][]; - typing: User['id']; - message: Packed<'MessagingMessage'>; - deleted: MessagingMessage['id']; -} - -export interface GroupMessagingStreamTypes { - read: { - ids: MessagingMessage['id'][]; - userId: User['id']; - }; - typing: User['id']; - message: Packed<'MessagingMessage'>; - deleted: MessagingMessage['id']; -} - -export interface MessagingIndexStreamTypes { - read: MessagingMessage['id'][]; - message: Packed<'MessagingMessage'>; -} - export interface AdminStreamTypes { newAbuseUserReport: { id: AbuseUserReport['id']; @@ -242,10 +212,6 @@ export type StreamMessages = { name: `noteStream:${Note['id']}`; payload: EventUnionFromDictionary>; }; - channel: { - name: `channelStream:${Channel['id']}`; - payload: EventUnionFromDictionary>; - }; userList: { name: `userListStream:${UserList['id']}`; payload: EventUnionFromDictionary>; @@ -254,18 +220,6 @@ export type StreamMessages = { name: `antennaStream:${Antenna['id']}`; payload: EventUnionFromDictionary>; }; - messaging: { - name: `messagingStream:${User['id']}-${User['id']}`; - payload: EventUnionFromDictionary>; - }; - groupMessaging: { - name: `messagingStream:${UserGroup['id']}`; - payload: EventUnionFromDictionary>; - }; - messagingIndex: { - name: `messagingIndexStream:${User['id']}`; - payload: EventUnionFromDictionary>; - }; admin: { name: `adminStream:${User['id']}`; payload: EventUnionFromDictionary>; -- cgit v1.2.3-freya