summaryrefslogtreecommitdiff
path: root/src/server/api
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-09-22 22:53:41 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-09-22 22:53:41 +0900
commit338793d891d1657f158cd4dc83f998e124bd7e45 (patch)
treed47080ad4fcff61ad5eafdb8eb1e3ca997739115 /src/server/api
parentMerge branch 'develop' (diff)
parent12.91.0 (diff)
downloadmisskey-338793d891d1657f158cd4dc83f998e124bd7e45.tar.gz
misskey-338793d891d1657f158cd4dc83f998e124bd7e45.tar.bz2
misskey-338793d891d1657f158cd4dc83f998e124bd7e45.zip
Merge branch 'develop'
Diffstat (limited to 'src/server/api')
-rw-r--r--src/server/api/call.ts7
-rw-r--r--src/server/api/endpoints.ts4
-rw-r--r--src/server/api/endpoints/admin/accounts/delete.ts58
-rw-r--r--src/server/api/endpoints/antennas/notes.ts5
-rw-r--r--src/server/api/endpoints/i/delete-account.ts4
-rw-r--r--src/server/api/endpoints/reset-db.ts2
-rw-r--r--src/server/api/openapi/schemas.ts49
-rw-r--r--src/server/api/private/signin.ts37
-rw-r--r--src/server/api/stream/channels/channel.ts4
-rw-r--r--src/server/api/stream/channels/global-timeline.ts6
-rw-r--r--src/server/api/stream/channels/hashtag.ts4
-rw-r--r--src/server/api/stream/channels/home-timeline.ts6
-rw-r--r--src/server/api/stream/channels/hybrid-timeline.ts9
-rw-r--r--src/server/api/stream/channels/local-timeline.ts9
-rw-r--r--src/server/api/stream/channels/user-list.ts4
-rw-r--r--src/server/api/stream/index.ts12
16 files changed, 127 insertions, 93 deletions
diff --git a/src/server/api/call.ts b/src/server/api/call.ts
index 2768bde07e..bd86ffdc35 100644
--- a/src/server/api/call.ts
+++ b/src/server/api/call.ts
@@ -40,7 +40,12 @@ export default async (endpoint: string, user: User | null | undefined, token: Ac
}
if (ep.meta.requireCredential && user!.isSuspended) {
- throw new ApiError(accessDenied, { reason: 'Your account has been suspended.' });
+ throw new ApiError({
+ message: 'Your account has been suspended.',
+ code: 'YOUR_ACCOUNT_SUSPENDED',
+ id: 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370',
+ httpStatusCode: 403
+ });
}
if (ep.meta.requireAdmin && !user!.isAdmin) {
diff --git a/src/server/api/endpoints.ts b/src/server/api/endpoints.ts
index 640b14ed6a..6d9d2b0782 100644
--- a/src/server/api/endpoints.ts
+++ b/src/server/api/endpoints.ts
@@ -3,7 +3,7 @@ import { dirname } from 'path';
import { Context } from 'cafy';
import * as path from 'path';
import * as glob from 'glob';
-import { Schema } from '@/misc/schema';
+import { SimpleSchema } from '@/misc/simple-schema';
//const _filename = fileURLToPath(import.meta.url);
const _filename = __filename;
@@ -34,7 +34,7 @@ export interface IEndpointMeta {
};
};
- res?: Schema;
+ res?: SimpleSchema;
/**
* このエンドポイントにリクエストするのにユーザー情報が必須か否か
diff --git a/src/server/api/endpoints/admin/accounts/delete.ts b/src/server/api/endpoints/admin/accounts/delete.ts
new file mode 100644
index 0000000000..4e8a559805
--- /dev/null
+++ b/src/server/api/endpoints/admin/accounts/delete.ts
@@ -0,0 +1,58 @@
+import $ from 'cafy';
+import define from '../../../define';
+import { Users } from '@/models/index';
+import { doPostSuspend } from '@/services/suspend-user';
+import { publishUserEvent } from '@/services/stream';
+import { createDeleteAccountJob } from '@/queue';
+import { ID } from '@/misc/cafy-id';
+
+export const meta = {
+ tags: ['admin'],
+
+ requireCredential: true as const,
+ requireModerator: true,
+
+ params: {
+ userId: {
+ validator: $.type(ID),
+ },
+ }
+};
+
+export default define(meta, async (ps, me) => {
+ const user = await Users.findOne(ps.userId);
+
+ if (user == null) {
+ throw new Error('user not found');
+ }
+
+ if (user.isAdmin) {
+ throw new Error('cannot suspend admin');
+ }
+
+ if (user.isModerator) {
+ throw new Error('cannot suspend moderator');
+ }
+
+ if (Users.isLocalUser(user)) {
+ // 物理削除する前にDelete activityを送信する
+ await doPostSuspend(user).catch(e => {});
+
+ createDeleteAccountJob(user, {
+ soft: false
+ });
+ } else {
+ createDeleteAccountJob(user, {
+ soft: true // リモートユーザーの削除は、完全にDBから物理削除してしまうと再度連合してきてアカウントが復活する可能性があるため、soft指定する
+ });
+ }
+
+ await Users.update(user.id, {
+ isDeleted: true,
+ });
+
+ if (Users.isLocalUser(user)) {
+ // Terminate streaming
+ publishUserEvent(user.id, 'terminate', {});
+ }
+});
diff --git a/src/server/api/endpoints/antennas/notes.ts b/src/server/api/endpoints/antennas/notes.ts
index 3c8a4fbdae..1759e95b4c 100644
--- a/src/server/api/endpoints/antennas/notes.ts
+++ b/src/server/api/endpoints/antennas/notes.ts
@@ -1,6 +1,7 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
+import readNote from '@/services/note/read';
import { Antennas, Notes, AntennaNotes } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
import { generateVisibilityQuery } from '../../common/generate-visibility-query';
@@ -84,5 +85,9 @@ export default define(meta, async (ps, user) => {
.take(ps.limit!)
.getMany();
+ if (notes.length > 0) {
+ readNote(user.id, notes);
+ }
+
return await Notes.packMany(notes, user);
});
diff --git a/src/server/api/endpoints/i/delete-account.ts b/src/server/api/endpoints/i/delete-account.ts
index 77f11925cd..10e5adf64a 100644
--- a/src/server/api/endpoints/i/delete-account.ts
+++ b/src/server/api/endpoints/i/delete-account.ts
@@ -35,7 +35,9 @@ export default define(meta, async (ps, user) => {
// 物理削除する前にDelete activityを送信する
await doPostSuspend(user).catch(e => {});
- createDeleteAccountJob(user);
+ createDeleteAccountJob(user, {
+ soft: false
+ });
await Users.update(user.id, {
isDeleted: true,
diff --git a/src/server/api/endpoints/reset-db.ts b/src/server/api/endpoints/reset-db.ts
index f430869302..f0a9dae4ff 100644
--- a/src/server/api/endpoints/reset-db.ts
+++ b/src/server/api/endpoints/reset-db.ts
@@ -18,4 +18,6 @@ export default define(meta, async (ps, user) => {
if (process.env.NODE_ENV !== 'test') throw 'NODE_ENV is not a test';
await resetDb();
+
+ await new Promise(resolve => setTimeout(resolve, 1000));
});
diff --git a/src/server/api/openapi/schemas.ts b/src/server/api/openapi/schemas.ts
index 5402dc6f48..12fc207c47 100644
--- a/src/server/api/openapi/schemas.ts
+++ b/src/server/api/openapi/schemas.ts
@@ -1,26 +1,4 @@
-import { packedUserSchema } from '@/models/repositories/user';
-import { Schema } from '@/misc/schema';
-import { packedNoteSchema } from '@/models/repositories/note';
-import { packedUserListSchema } from '@/models/repositories/user-list';
-import { packedAppSchema } from '@/models/repositories/app';
-import { packedMessagingMessageSchema } from '@/models/repositories/messaging-message';
-import { packedNotificationSchema } from '@/models/repositories/notification';
-import { packedDriveFileSchema } from '@/models/repositories/drive-file';
-import { packedDriveFolderSchema } from '@/models/repositories/drive-folder';
-import { packedFollowingSchema } from '@/models/repositories/following';
-import { packedMutingSchema } from '@/models/repositories/muting';
-import { packedBlockingSchema } from '@/models/repositories/blocking';
-import { packedNoteReactionSchema } from '@/models/repositories/note-reaction';
-import { packedHashtagSchema } from '@/models/repositories/hashtag';
-import { packedPageSchema } from '@/models/repositories/page';
-import { packedUserGroupSchema } from '@/models/repositories/user-group';
-import { packedNoteFavoriteSchema } from '@/models/repositories/note-favorite';
-import { packedChannelSchema } from '@/models/repositories/channel';
-import { packedAntennaSchema } from '@/models/repositories/antenna';
-import { packedClipSchema } from '@/models/repositories/clip';
-import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance';
-import { packedQueueCountSchema } from '@/models/repositories/queue';
-import { packedGalleryPostSchema } from '@/models/repositories/gallery-post';
+import { refs, Schema } from '@/misc/schema';
export function convertSchemaToOpenApiSchema(schema: Schema) {
const res: any = schema;
@@ -72,26 +50,7 @@ export const schemas = {
required: ['error']
},
- User: convertSchemaToOpenApiSchema(packedUserSchema),
- UserList: convertSchemaToOpenApiSchema(packedUserListSchema),
- UserGroup: convertSchemaToOpenApiSchema(packedUserGroupSchema),
- App: convertSchemaToOpenApiSchema(packedAppSchema),
- MessagingMessage: convertSchemaToOpenApiSchema(packedMessagingMessageSchema),
- Note: convertSchemaToOpenApiSchema(packedNoteSchema),
- NoteReaction: convertSchemaToOpenApiSchema(packedNoteReactionSchema),
- NoteFavorite: convertSchemaToOpenApiSchema(packedNoteFavoriteSchema),
- Notification: convertSchemaToOpenApiSchema(packedNotificationSchema),
- DriveFile: convertSchemaToOpenApiSchema(packedDriveFileSchema),
- DriveFolder: convertSchemaToOpenApiSchema(packedDriveFolderSchema),
- Following: convertSchemaToOpenApiSchema(packedFollowingSchema),
- Muting: convertSchemaToOpenApiSchema(packedMutingSchema),
- Blocking: convertSchemaToOpenApiSchema(packedBlockingSchema),
- Hashtag: convertSchemaToOpenApiSchema(packedHashtagSchema),
- Page: convertSchemaToOpenApiSchema(packedPageSchema),
- Channel: convertSchemaToOpenApiSchema(packedChannelSchema),
- QueueCount: convertSchemaToOpenApiSchema(packedQueueCountSchema),
- Antenna: convertSchemaToOpenApiSchema(packedAntennaSchema),
- Clip: convertSchemaToOpenApiSchema(packedClipSchema),
- FederationInstance: convertSchemaToOpenApiSchema(packedFederationInstanceSchema),
- GalleryPost: convertSchemaToOpenApiSchema(packedGalleryPostSchema),
+ ...Object.fromEntries(
+ Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema)])
+ ),
};
diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts
index fff1037ff9..83c3dfee94 100644
--- a/src/server/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -18,6 +18,11 @@ export default async (ctx: Koa.Context) => {
const password = body['password'];
const token = body['token'];
+ function error(status: number, error: { id: string }) {
+ ctx.status = status;
+ ctx.body = { error };
+ }
+
if (typeof username != 'string') {
ctx.status = 400;
return;
@@ -40,15 +45,15 @@ export default async (ctx: Koa.Context) => {
}) as ILocalUser;
if (user == null) {
- ctx.throw(404, {
- error: 'user not found'
+ error(404, {
+ id: '6cc579cc-885d-43d8-95c2-b8c7fc963280',
});
return;
}
if (user.isSuspended) {
- ctx.throw(403, {
- error: 'user is suspended'
+ error(403, {
+ id: 'e03a5f46-d309-4865-9b69-56282d94e1eb',
});
return;
}
@@ -58,7 +63,7 @@ export default async (ctx: Koa.Context) => {
// Compare password
const same = await bcrypt.compare(password, profile.password!);
- async function fail(status?: number, failure?: { error: string }) {
+ async function fail(status?: number, failure?: { id: string }) {
// Append signin history
await Signins.insert({
id: genId(),
@@ -69,7 +74,7 @@ export default async (ctx: Koa.Context) => {
success: false
});
- ctx.throw(status || 500, failure || { error: 'someting happened' });
+ error(status || 500, failure || { id: '4e30e80c-e338-45a0-8c8f-44455efa3b76' });
}
if (!profile.twoFactorEnabled) {
@@ -78,7 +83,7 @@ export default async (ctx: Koa.Context) => {
return;
} else {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -87,7 +92,7 @@ export default async (ctx: Koa.Context) => {
if (token) {
if (!same) {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -104,14 +109,14 @@ export default async (ctx: Koa.Context) => {
return;
} else {
await fail(403, {
- error: 'invalid token'
+ id: 'cdf1235b-ac71-46d4-a3a6-84ccce48df6f'
});
return;
}
} else if (body.credentialId) {
if (!same && !profile.usePasswordLessLogin) {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -127,7 +132,7 @@ export default async (ctx: Koa.Context) => {
if (!challenge) {
await fail(403, {
- error: 'non-existent challenge'
+ id: '2715a88a-2125-4013-932f-aa6fe72792da'
});
return;
}
@@ -139,7 +144,7 @@ export default async (ctx: Koa.Context) => {
if (new Date().getTime() - challenge.createdAt.getTime() >= 5 * 60 * 1000) {
await fail(403, {
- error: 'non-existent challenge'
+ id: '2715a88a-2125-4013-932f-aa6fe72792da'
});
return;
}
@@ -155,7 +160,7 @@ export default async (ctx: Koa.Context) => {
if (!securityKey) {
await fail(403, {
- error: 'invalid credentialId'
+ id: '66269679-aeaf-4474-862b-eb761197e046'
});
return;
}
@@ -174,14 +179,14 @@ export default async (ctx: Koa.Context) => {
return;
} else {
await fail(403, {
- error: 'invalid challenge data'
+ id: '93b86c4b-72f9-40eb-9815-798928603d1e'
});
return;
}
} else {
if (!same && !profile.usePasswordLessLogin) {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -192,7 +197,7 @@ export default async (ctx: Koa.Context) => {
if (keys.length === 0) {
await fail(403, {
- error: 'no keys found'
+ id: 'f27fd449-9af4-4841-9249-1f989b9fa4a4'
});
return;
}
diff --git a/src/server/api/stream/channels/channel.ts b/src/server/api/stream/channels/channel.ts
index e6a9a6c696..72ddbf93b4 100644
--- a/src/server/api/stream/channels/channel.ts
+++ b/src/server/api/stream/channels/channel.ts
@@ -3,8 +3,8 @@ import Channel from '../channel';
import { Notes, Users } from '@/models/index';
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
-import { PackedNote } from '@/models/repositories/note';
import { User } from '@/models/entities/user';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'channel';
@@ -25,7 +25,7 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
+ private async onNote(note: Packed<'Note'>) {
if (note.channelId !== this.channelId) return;
// リプライなら再pack
diff --git a/src/server/api/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts
index 2cb138966f..f5983ab472 100644
--- a/src/server/api/stream/channels/global-timeline.ts
+++ b/src/server/api/stream/channels/global-timeline.ts
@@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel';
import { fetchMeta } from '@/misc/fetch-meta';
import { Notes } from '@/models/index';
-import { PackedNote } from '@/models/repositories/note';
import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'globalTimeline';
@@ -24,7 +24,7 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
+ private async onNote(note: Packed<'Note'>) {
if (note.visibility !== 'public') return;
if (note.channelId != null) return;
@@ -43,7 +43,7 @@ export default class extends Channel {
// 関係ない返信は除外
if (note.reply) {
- const reply = note.reply as PackedNote;
+ const reply = note.reply;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
}
diff --git a/src/server/api/stream/channels/hashtag.ts b/src/server/api/stream/channels/hashtag.ts
index 997ab75f6d..281be4f2eb 100644
--- a/src/server/api/stream/channels/hashtag.ts
+++ b/src/server/api/stream/channels/hashtag.ts
@@ -2,9 +2,9 @@ import autobind from 'autobind-decorator';
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel';
import { Notes } from '@/models/index';
-import { PackedNote } from '@/models/repositories/note';
import { normalizeForSearch } from '@/misc/normalize-for-search';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'hashtag';
@@ -23,7 +23,7 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
+ private async onNote(note: Packed<'Note'>) {
const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : [];
const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag))));
if (!matched) return;
diff --git a/src/server/api/stream/channels/home-timeline.ts b/src/server/api/stream/channels/home-timeline.ts
index c7a9728741..52e9aec250 100644
--- a/src/server/api/stream/channels/home-timeline.ts
+++ b/src/server/api/stream/channels/home-timeline.ts
@@ -2,9 +2,9 @@ import autobind from 'autobind-decorator';
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel';
import { Notes } from '@/models/index';
-import { PackedNote } from '@/models/repositories/note';
import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'homeTimeline';
@@ -18,7 +18,7 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
+ private async onNote(note: Packed<'Note'>) {
if (note.channelId) {
if (!this.followingChannels.has(note.channelId)) return;
} else {
@@ -51,7 +51,7 @@ export default class extends Channel {
// 関係ない返信は除外
if (note.reply) {
- const reply = note.reply as PackedNote;
+ const reply = note.reply;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
}
diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts
index 5c454764ec..51f95fc0cd 100644
--- a/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/src/server/api/stream/channels/hybrid-timeline.ts
@@ -3,10 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel';
import { fetchMeta } from '@/misc/fetch-meta';
import { Notes } from '@/models/index';
-import { PackedNote } from '@/models/repositories/note';
-import { PackedUser } from '@/models/repositories/user';
import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'hybridTimeline';
@@ -23,7 +22,7 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
+ private async onNote(note: Packed<'Note'>) {
// チャンネルの投稿ではなく、自分自身の投稿 または
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
@@ -31,7 +30,7 @@ export default class extends Channel {
if (!(
(note.channelId == null && this.user!.id === note.userId) ||
(note.channelId == null && this.following.has(note.userId)) ||
- (note.channelId == null && ((note.user as PackedUser).host == null && note.visibility === 'public')) ||
+ (note.channelId == null && (note.user.host == null && note.visibility === 'public')) ||
(note.channelId != null && this.followingChannels.has(note.channelId))
)) return;
@@ -60,7 +59,7 @@ export default class extends Channel {
// 関係ない返信は除外
if (note.reply) {
- const reply = note.reply as PackedNote;
+ const reply = note.reply;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
}
diff --git a/src/server/api/stream/channels/local-timeline.ts b/src/server/api/stream/channels/local-timeline.ts
index 4bf0d02ed3..a6166c2be2 100644
--- a/src/server/api/stream/channels/local-timeline.ts
+++ b/src/server/api/stream/channels/local-timeline.ts
@@ -3,10 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel';
import { fetchMeta } from '@/misc/fetch-meta';
import { Notes } from '@/models/index';
-import { PackedNote } from '@/models/repositories/note';
-import { PackedUser } from '@/models/repositories/user';
import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'localTimeline';
@@ -25,8 +24,8 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
- if ((note.user as PackedUser).host !== null) return;
+ private async onNote(note: Packed<'Note'>) {
+ if (note.user.host !== null) return;
if (note.visibility !== 'public') return;
if (note.channelId != null && !this.followingChannels.has(note.channelId)) return;
@@ -45,7 +44,7 @@ export default class extends Channel {
// 関係ない返信は除外
if (note.reply) {
- const reply = note.reply as PackedNote;
+ const reply = note.reply;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
}
diff --git a/src/server/api/stream/channels/user-list.ts b/src/server/api/stream/channels/user-list.ts
index 0ca83cd658..63b254605b 100644
--- a/src/server/api/stream/channels/user-list.ts
+++ b/src/server/api/stream/channels/user-list.ts
@@ -3,8 +3,8 @@ import Channel from '../channel';
import { Notes, UserListJoinings, UserLists } from '@/models/index';
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import { User } from '@/models/entities/user';
-import { PackedNote } from '@/models/repositories/note';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
+import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'userList';
@@ -47,7 +47,7 @@ export default class extends Channel {
}
@autobind
- private async onNote(note: PackedNote) {
+ private async onNote(note: Packed<'Note'>) {
if (!this.listUsers.includes(note.userId)) return;
if (['followers', 'specified'].includes(note.visibility)) {
diff --git a/src/server/api/stream/index.ts b/src/server/api/stream/index.ts
index 469f28f11c..ccd555e149 100644
--- a/src/server/api/stream/index.ts
+++ b/src/server/api/stream/index.ts
@@ -14,7 +14,7 @@ import { AccessToken } from '@/models/entities/access-token';
import { UserProfile } from '@/models/entities/user-profile';
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream';
import { UserGroup } from '@/models/entities/user-group';
-import { PackedNote } from '@/models/repositories/note';
+import { Packed } from '@/misc/schema';
/**
* Main stream connection
@@ -31,7 +31,7 @@ export default class Connection {
public subscriber: EventEmitter;
private channels: Channel[] = [];
private subscribingNotes: any = {};
- private cachedNotes: PackedNote[] = [];
+ private cachedNotes: Packed<'Note'>[] = [];
constructor(
wsConnection: websocket.connection,
@@ -150,8 +150,8 @@ export default class Connection {
}
@autobind
- public cacheNote(note: PackedNote) {
- const add = (note: PackedNote) => {
+ public cacheNote(note: Packed<'Note'>) {
+ const add = (note: Packed<'Note'>) => {
const existIndex = this.cachedNotes.findIndex(n => n.id === note.id);
if (existIndex > -1) {
this.cachedNotes[existIndex] = note;
@@ -165,8 +165,8 @@ export default class Connection {
};
add(note);
- if (note.reply) add(note.reply as PackedNote);
- if (note.renote) add(note.renote as PackedNote);
+ if (note.reply) add(note.reply);
+ if (note.renote) add(note.renote);
}
@autobind