From 08c6efb04449bcc68be142e09724b2eecfae50ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 09:44:57 +0900 Subject: [PATCH 01/10] fix(deps): update dependency sanitize-html to v2.17.4 [security] [ci skip] (#17402) * fix(deps): update dependency sanitize-html to v2.17.4 [security] * fix minimumReleaseAgeExclude --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> --- packages/backend/package.json | 2 +- packages/frontend/package.json | 2 +- pnpm-lock.yaml | 22 +++++++++++++++------- pnpm-workspace.yaml | 2 ++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 625349ad34..1a19f02eab 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -138,7 +138,7 @@ "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.2", - "sanitize-html": "2.17.3", + "sanitize-html": "2.17.4", "secure-json-parse": "4.1.0", "semver": "7.7.4", "sharp": "0.33.5", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 1392160c5a..8f4d5cfd52 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -60,7 +60,7 @@ "punycode.js": "2.3.1", "qr-code-styling": "1.9.2", "qr-scanner": "1.4.2", - "sanitize-html": "2.17.3", + "sanitize-html": "2.17.4", "shiki": "4.0.2", "textarea-caret": "3.1.0", "three": "0.184.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0d4fb2acfd..248da08dd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -346,8 +346,8 @@ importers: specifier: 7.8.2 version: 7.8.2 sanitize-html: - specifier: 2.17.3 - version: 2.17.3 + specifier: 2.17.4 + version: 2.17.4 secure-json-parse: specifier: 4.1.0 version: 4.1.0 @@ -738,8 +738,8 @@ importers: specifier: 1.4.2 version: 1.4.2 sanitize-html: - specifier: 2.17.3 - version: 2.17.3 + specifier: 2.17.4 + version: 2.17.4 shiki: specifier: 4.0.2 version: 4.0.2 @@ -7207,6 +7207,9 @@ packages: resolution: {integrity: sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==} engines: {node: '>=18'} + launder@1.7.1: + resolution: {integrity: sha512-mU6WRz5EusL9ZZuiZ5SO4Y6C0P9PAUR9iwdb6bzj4KDihm28DiHFw+/yk9DBH4f+Pv1wuzQ4e2jV3oQ7mkIqvw==} + lazy-ass@1.6.0: resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} engines: {node: '> 0.8'} @@ -8901,8 +8904,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sanitize-html@2.17.3: - resolution: {integrity: sha512-Kn4srCAo2+wZyvCNKCSyB2g8RQ8IkX/gQs2uqoSRNu5t9I2qvUyAVvRDiFUVAiX3N3PNuwStY0eNr+ooBHVWEg==} + sanitize-html@2.17.4: + resolution: {integrity: sha512-2HW7v2ol/uAM7sX4hbD8Z59OGWmAPrvjL8E71UWlBcj6m+kcF6ilQBLny+cIgY214QJeJT5tQuxKKqX0SQqjGQ==} sass-embedded-all-unknown@1.99.0: resolution: {integrity: sha512-qPIRG8Uhjo6/OKyAKixTnwMliTz+t9K6Duk0mx5z+K7n0Ts38NSJz2sjDnc7cA/8V9Lb3q09H38dZ1CLwD+ssw==} @@ -17116,6 +17119,10 @@ snapshots: ky@1.14.3: {} + launder@1.7.1: + dependencies: + dayjs: 1.11.20 + lazy-ass@1.6.0: {} lazystream@1.0.1: @@ -19060,12 +19067,13 @@ snapshots: safer-buffer@2.1.2: {} - sanitize-html@2.17.3: + sanitize-html@2.17.4: dependencies: deepmerge: 4.3.1 escape-string-regexp: 4.0.0 htmlparser2: 10.1.0 is-plain-object: 5.0.0 + launder: 1.7.1 parse-srcset: 1.0.2 postcss: 8.5.14 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 88f9b251b5..9e4c609d4d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -56,6 +56,8 @@ minimumReleaseAgeExclude: - re2 # そのうち消す - nan # そのうち消す - systeminformation # 脆弱性対応。そのうち消す + - sanitize-html # 脆弱性対応。そのうち消す + - launder # 脆弱性対応。そのうち消す overrides: '@aiscript-dev/aiscript-languageserver': '-' chokidar: 5.0.0 From 1684dc9c055df4e6b848a09470e11d9450171050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Fri, 15 May 2026 09:47:35 +0900 Subject: [PATCH 02/10] fix(deps): broken lockfile (#17404) --- pnpm-lock.yaml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 248da08dd2..25a753da19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -331,8 +331,8 @@ importers: specifier: 3.4.1 version: 3.4.1 re2: - specifier: 1.24.0 - version: 1.24.0 + specifier: 1.24.1 + version: 1.24.1 reflect-metadata: specifier: 0.2.2 version: 0.2.2 @@ -7766,8 +7766,8 @@ packages: resolution: {integrity: sha512-BzQguy9W9NJgoVn2mRWzbFrFWWztGCcng2QI9+41frfk+Athwgx3qhqhvStz7ExeUUu7Kzw427sNzHpEZNINog==} engines: {node: '>=16.0.0'} - nan@2.26.2: - resolution: {integrity: sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==} + nan@2.27.0: + resolution: {integrity: sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==} nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} @@ -8662,8 +8662,9 @@ packages: resolution: {integrity: sha512-g8OUrgMXAR9ys/ZuJVfBr05sPPoMA7nHIVs8VEvg9QwM5W4GR2qSFEEHjsyHF1eWlBaf8Ev40WNjQFQ+nJTO3w==} engines: {node: '>=18'} - re2@1.24.0: - resolution: {integrity: sha512-pBm6cMaOb0Yb0kg0Sfw/k4LwDMkPScb/NVd7GrEllDwfsPZstsZIo93A6Nn0wZuWJw3h57GdzkrOk81EofKY/g==} + re2@1.24.1: + resolution: {integrity: sha512-uRl9cLDKuobJQp+6lVz7E3AyVszubUJ0fqAMWout4ocUWTIFvdHgpqLwwMh/vuNGGGJGh2p2mJZJIQr9am9M/A==} + engines: {node: '>=22'} react-docgen-typescript@2.4.0: resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} @@ -17815,7 +17816,7 @@ snapshots: mylas@2.1.14: {} - nan@2.26.2: {} + nan@2.27.0: {} nanoid@3.3.12: {} @@ -18704,10 +18705,10 @@ snapshots: dependencies: setimmediate: 1.0.5 - re2@1.24.0: + re2@1.24.1: dependencies: install-artifact-from-github: 1.6.0 - nan: 2.26.2 + nan: 2.27.0 node-gyp: 12.3.0 react-docgen-typescript@2.4.0(typescript@5.9.3): From 92c1dc06f27ee90b46103b635d2c6568d35feeee Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 15 May 2026 10:11:42 +0900 Subject: [PATCH 03/10] Update CONTRIBUTING.md --- CONTRIBUTING.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 10ae1275e9..de3f4d3208 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -202,6 +202,14 @@ command. - Vite runs behind the backend (the backend will proxy Vite at /vite and /embed_vite except for websocket used for HMR). - You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml). +#### Cloudflare tunnel +Cloudflare tunnelを使うとローカルのMisskeyサーバーをインターネットに公開できます。 +HTTPSでしか動作しない機能を検証したい時や、スマホなど別のデバイスからローカルのMisskeyサーバーを検証したい時に便利です。 + +##### Cloudflare warpと併用する際のtips + +> cloudflared (Cloudflare Tunnel) は region1.v2.argotunnel.com / region2.v2.argotunnel.com に QUIC/HTTP2 でアウトバウンド接続するのですが、WARP を有効化するとこのトラフィックが WARP 経由になってループ/切断します。これら 2 ホストを WARP のトンネル除外(split tunnel)に追加することで、cloudflared だけは WARP をバイパスして直接 Cloudflare エッジへ接続できるようになります。 + ## Testing You can run non-backend tests by executing following commands: ```sh From e6375fb7562384f02994818d93d7f6438c21c8fa Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 15 May 2026 10:12:17 +0900 Subject: [PATCH 04/10] Update CONTRIBUTING.md --- CONTRIBUTING.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de3f4d3208..bfb83e6de2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -189,6 +189,14 @@ pnpm migrate After finishing the migration, you can proceed. +#### Cloudflare tunnel +Cloudflare tunnelを使うとローカルのMisskeyサーバーをインターネットに公開できます。 +HTTPSでしか動作しない機能を検証したい時や、スマホなど別のデバイスからローカルのMisskeyサーバーを検証したい時に便利です。 + +##### Cloudflare warpと併用する際のtips + +> cloudflared (Cloudflare Tunnel) は region1.v2.argotunnel.com / region2.v2.argotunnel.com に QUIC/HTTP2 でアウトバウンド接続するのですが、WARP を有効化するとこのトラフィックが WARP 経由になってループ/切断します。これら 2 ホストを WARP のトンネル除外(split tunnel)に追加することで、cloudflared だけは WARP をバイパスして直接 Cloudflare エッジへ接続できるようになります。 + ### Start developing During development, it is useful to use the ``` @@ -202,14 +210,6 @@ command. - Vite runs behind the backend (the backend will proxy Vite at /vite and /embed_vite except for websocket used for HMR). - You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml). -#### Cloudflare tunnel -Cloudflare tunnelを使うとローカルのMisskeyサーバーをインターネットに公開できます。 -HTTPSでしか動作しない機能を検証したい時や、スマホなど別のデバイスからローカルのMisskeyサーバーを検証したい時に便利です。 - -##### Cloudflare warpと併用する際のtips - -> cloudflared (Cloudflare Tunnel) は region1.v2.argotunnel.com / region2.v2.argotunnel.com に QUIC/HTTP2 でアウトバウンド接続するのですが、WARP を有効化するとこのトラフィックが WARP 経由になってループ/切断します。これら 2 ホストを WARP のトンネル除外(split tunnel)に追加することで、cloudflared だけは WARP をバイパスして直接 Cloudflare エッジへ接続できるようになります。 - ## Testing You can run non-backend tests by executing following commands: ```sh From baad1c51d8449cb926152fd6edbbf46e8b82734c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 16 May 2026 12:54:19 +0900 Subject: [PATCH 05/10] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 648613809b..f026e3f689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ ### General - Enhance: Unicode 17.0 に収録されている絵文字の処理・表示に対応 - Fluent Emojiや端末ネイティブの絵文字を利用している場合は、最新の絵文字に対応しておらず正しく表示できない可能性があります。絵文字が表示できない場合は、表示に使用する絵文字をTwemojiに切り替えてご利用ください。 -- 投稿通知設定したユーザーをリストで見ることができるように +- Enhance: 投稿通知設定したユーザーをリストで見ることができるように +- 依存関係の更新 ### Client - Enhance: テーマのプレビュー時、リロードせずにもとのテーマに戻せるように From 9410bc51946c9338d7200c3f705b55b2940536dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sun, 17 May 2026 18:51:10 +0900 Subject: [PATCH 06/10] fix: move `users/notify/list` to `following/list` (#17416) * fix: move `users/notify/list` to `following/list` * fix * fix lint * fix test * fix test * fix test title --- .../backend/src/server/api/endpoint-list.ts | 2 +- .../{users/notify => following}/list.ts | 23 +-- packages/backend/test/e2e/note-notify.ts | 58 ++++--- .../src/pages/settings/notifications.vue | 11 +- packages/misskey-js/etc/misskey-js.api.md | 16 +- .../misskey-js/src/autogen/apiClientJSDoc.ts | 22 +-- packages/misskey-js/src/autogen/endpoint.ts | 6 +- packages/misskey-js/src/autogen/entities.ts | 4 +- packages/misskey-js/src/autogen/types.ts | 164 +++++++++--------- 9 files changed, 165 insertions(+), 141 deletions(-) rename packages/backend/src/server/api/endpoints/{users/notify => following}/list.ts (75%) diff --git a/packages/backend/src/server/api/endpoint-list.ts b/packages/backend/src/server/api/endpoint-list.ts index 60a4656214..feb39e98bb 100644 --- a/packages/backend/src/server/api/endpoint-list.ts +++ b/packages/backend/src/server/api/endpoint-list.ts @@ -217,6 +217,7 @@ export * as 'flash/search' from './endpoints/flash/search.js'; export * as 'following/create' from './endpoints/following/create.js'; export * as 'following/delete' from './endpoints/following/delete.js'; export * as 'following/invalidate' from './endpoints/following/invalidate.js'; +export * as 'following/list' from './endpoints/following/list.js'; export * as 'following/requests/accept' from './endpoints/following/requests/accept.js'; export * as 'following/requests/cancel' from './endpoints/following/requests/cancel.js'; export * as 'following/requests/list' from './endpoints/following/requests/list.js'; @@ -391,7 +392,6 @@ export * as 'users/featured-notes' from './endpoints/users/featured-notes.js'; export * as 'users/flashs' from './endpoints/users/flashs.js'; export * as 'users/followers' from './endpoints/users/followers.js'; export * as 'users/following' from './endpoints/users/following.js'; -export * as 'users/notify/list' from './endpoints/users/notify/list.js'; export * as 'users/get-following-users-by-birthday' from './endpoints/users/get-following-users-by-birthday.js'; export * as 'users/gallery/posts' from './endpoints/users/gallery/posts.js'; export * as 'users/get-frequently-replied-users' from './endpoints/users/get-frequently-replied-users.js'; diff --git a/packages/backend/src/server/api/endpoints/users/notify/list.ts b/packages/backend/src/server/api/endpoints/following/list.ts similarity index 75% rename from packages/backend/src/server/api/endpoints/users/notify/list.ts rename to packages/backend/src/server/api/endpoints/following/list.ts index 4c7ca48134..5c48621b7a 100644 --- a/packages/backend/src/server/api/endpoints/users/notify/list.ts +++ b/packages/backend/src/server/api/endpoints/following/list.ts @@ -4,7 +4,7 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js'; import type { FollowingsRepository } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; @@ -15,7 +15,7 @@ export const meta = { requireCredential: true, kind: 'read:following', - description: 'List of following users with notification enabled.', + description: 'List of following users', res: { type: 'array', @@ -23,7 +23,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - ref: 'UserDetailed', + ref: 'Following', }, }, } as const; @@ -31,6 +31,7 @@ export const meta = { export const paramDef = { type: 'object', properties: { + notification: { type: 'boolean', default: false }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, sinceDate: { type: 'integer' }, @@ -45,22 +46,24 @@ export default class extends Endpoint { // eslint- @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, - private userEntityService: UserEntityService, + private followingEntityService: FollowingEntityService, private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) - .innerJoinAndSelect('following.followee', 'followee') - .andWhere('following.followerId = :userId', { userId: me.id }) - .andWhere('following.notify IS NOT NULL'); + .andWhere('following.followerId = :userId', { userId: me.id }); + + if (ps.notification) { + query.andWhere('following.notify IS NOT NULL'); + } + + query.innerJoinAndSelect('following.followee', 'followee'); const followings = await query .limit(ps.limit) .getMany(); - const users = followings.map(f => f.followee!); - - return await this.userEntityService.packMany(users, me, { schema: 'UserDetailed' }); + return await this.followingEntityService.packMany(followings, me, { populateFollowee: true }); }); } } diff --git a/packages/backend/test/e2e/note-notify.ts b/packages/backend/test/e2e/note-notify.ts index 9835223053..b3d5d110b9 100644 --- a/packages/backend/test/e2e/note-notify.ts +++ b/packages/backend/test/e2e/note-notify.ts @@ -9,7 +9,7 @@ import { describe, beforeAll, test } from 'vitest'; import { api, signup } from '../utils.js'; import type * as misskey from 'misskey-js'; -describe('users/notify/list', () => { +describe('following/list', () => { let alice: misskey.entities.SignupResponse; let bob: misskey.entities.SignupResponse; let carol: misskey.entities.SignupResponse; @@ -24,11 +24,19 @@ describe('users/notify/list', () => { // alice が bob を普通にフォロー(通知設定なし) await api('following/create', { userId: bob.id }, alice); - const res = await api('users/notify/list', {}, alice); + const res1 = await api('following/list', { notification: true }, alice); + const res2 = await api('following/list', {}, alice); - assert.strictEqual(res.status, 200); - assert.strictEqual(Array.isArray(res.body), true); - assert.strictEqual(res.body.length, 0); + // notification: true の場合は通知設定なしのフォローは返らない + assert.strictEqual(res1.status, 200); + assert.strictEqual(Array.isArray(res1.body), true); + assert.strictEqual(res1.body.length, 0); + + // notification パラメータなしの場合は通知設定なしのフォローも返る + assert.strictEqual(res2.status, 200); + assert.strictEqual(Array.isArray(res2.body), true); + assert.strictEqual(res2.body.length, 1); + assert.strictEqual(res2.body[0].followeeId, bob.id); }); test('通知設定ありのフォローがある場合、そのユーザーが返る', async () => { @@ -36,34 +44,42 @@ describe('users/notify/list', () => { await api('following/create', { userId: carol.id, withReplies: false }, alice); await api('following/update', { userId: carol.id, notify: 'normal' }, alice); - const res = await api('users/notify/list', {}, alice); + const res = await api('following/list', { notification: true }, alice); assert.strictEqual(res.status, 200); assert.strictEqual(res.body.length, 1); - assert.strictEqual(res.body[0].id, carol.id); + assert.strictEqual(res.body[0].followeeId, carol.id); }); test('複数ユーザーで通知設定ありの場合、全員返る', async () => { // bob にも通知設定をON await api('following/update', { userId: bob.id, notify: 'normal' }, alice); - const res = await api('users/notify/list', {}, alice); + const res = await api('following/list', { notification: true }, alice); assert.strictEqual(res.status, 200); assert.strictEqual(res.body.length, 2); - const ids = res.body.map((u: { id: string }) => u.id).sort(); + const ids = res.body.map((u) => u.followeeId).sort(); assert.deepStrictEqual(ids, [bob.id, carol.id].sort()); }); - test('通知設定をOFF(none)にすると一覧から外れる', async () => { + test('通知設定をOFF(none)にすると notification: true な一覧から外れる', async () => { await api('following/update', { userId: bob.id, notify: 'none' }, alice); - const res = await api('users/notify/list', {}, alice); + const res1 = await api('following/list', { notification: true }, alice); + const res2 = await api('following/list', {}, alice); - assert.strictEqual(res.status, 200); - assert.strictEqual(res.body.length, 1); - assert.strictEqual(res.body[0].id, carol.id); + // notification: true の場合は bob は返らない + assert.strictEqual(res1.status, 200); + assert.strictEqual(res1.body.length, 1); + assert.strictEqual(res1.body[0].followeeId, carol.id); + + // notification パラメータなしの場合は bob も返る + assert.strictEqual(res2.status, 200); + assert.strictEqual(res2.body.length, 2); + const ids = res2.body.map((u) => u.followeeId).sort(); + assert.deepStrictEqual(ids, [bob.id, carol.id].sort()); }); test('他のユーザーの通知対象は見えない', async () => { @@ -72,14 +88,14 @@ describe('users/notify/list', () => { await api('following/update', { userId: carol.id, notify: 'normal' }, bob); // alice の一覧には bob の通知設定は反映されない - const aliceRes = await api('users/notify/list', {}, alice); - const aliceIds = aliceRes.body.map((u: { id: string }) => u.id); + const aliceRes = await api('following/list', { notification: true }, alice); + const aliceIds = aliceRes.body.map((u) => u.followeeId); assert.strictEqual(aliceIds.includes(bob.id), false); // bob の一覧には carol だけが含まれる - const bobRes = await api('users/notify/list', {}, bob); + const bobRes = await api('following/list', { notification: true }, bob); assert.strictEqual(bobRes.body.length, 1); - assert.strictEqual(bobRes.body[0].id, carol.id); + assert.strictEqual(bobRes.body[0].followeeId, carol.id); // 後片付け: bob → carol のフォローを解除 await api('following/delete', { userId: carol.id }, bob); @@ -114,18 +130,18 @@ describe('users/notify/list', () => { await api('following/update', { userId: bob.id, notify: 'normal' }, alice); // limitなしだと2件返ることを確認 - const allRes = await api('users/notify/list', {}, alice); + const allRes = await api('following/list', { notification: true }, alice); assert.strictEqual(allRes.status, 200); assert.strictEqual(allRes.body.length, 2); // limit:1 で1件に絞られることを確認 - const res = await api('users/notify/list', { limit: 1 }, alice); + const res = await api('following/list', { notification: true, limit: 1 }, alice); assert.strictEqual(res.status, 200); assert.strictEqual(res.body.length, 1); }); test('未認証の場合はエラー', async () => { - const res = await api('users/notify/list', {}); + const res = await api('following/list', {}); assert.strictEqual(res.status, 401); }); }); diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue index ffd8493cc3..9ff45fa4c5 100644 --- a/packages/frontend/src/pages/settings/notifications.vue +++ b/packages/frontend/src/pages/settings/notifications.vue @@ -47,10 +47,10 @@ SPDX-License-Identifier: AGPL-3.0-only
- - + + - +
@@ -125,8 +125,11 @@ async function showNotifyMenu(user: Misskey.entities.UserDetailed, ev: PointerEv }], ev.currentTarget ?? ev.target); } -const notifyUserPaginator = markRaw(new Paginator('users/notify/list', { +const notifyUserPaginator = markRaw(new Paginator('following/list', { limit: 10, + params: { + notification: true, + }, })); const nonConfigurableNotificationTypes = ['note', 'roleAssigned', 'followRequestAccepted', 'test', 'exportCompleted'] as const satisfies (typeof notificationTypes[number])[]; diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 852ccbb9b9..7a4d44498f 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -1884,6 +1884,8 @@ declare namespace entities { FollowingDeleteResponse, FollowingInvalidateRequest, FollowingInvalidateResponse, + FollowingListRequest, + FollowingListResponse, FollowingRequestsAcceptRequest, FollowingRequestsCancelRequest, FollowingRequestsCancelResponse, @@ -2162,8 +2164,6 @@ declare namespace entities { UsersListsUpdateMembershipRequest, UsersNotesRequest, UsersNotesResponse, - UsersNotifyListRequest, - UsersNotifyListResponse, UsersPagesRequest, UsersPagesResponse, UsersReactionsRequest, @@ -2403,6 +2403,12 @@ type FollowingInvalidateRequest = operations['following___invalidate']['requestB // @public (undocumented) type FollowingInvalidateResponse = operations['following___invalidate']['responses']['200']['content']['application/json']; +// @public (undocumented) +type FollowingListRequest = operations['following___list']['requestBody']['content']['application/json']; + +// @public (undocumented) +type FollowingListResponse = operations['following___list']['responses']['200']['content']['application/json']; + // @public (undocumented) type FollowingRequestsAcceptRequest = operations['following___requests___accept']['requestBody']['content']['application/json']; @@ -3829,12 +3835,6 @@ type UsersNotesRequest = operations['users___notes']['requestBody']['content'][' // @public (undocumented) type UsersNotesResponse = operations['users___notes']['responses']['200']['content']['application/json']; -// @public (undocumented) -type UsersNotifyListRequest = operations['users___notify___list']['requestBody']['content']['application/json']; - -// @public (undocumented) -type UsersNotifyListResponse = operations['users___notify___list']['responses']['200']['content']['application/json']; - // @public (undocumented) type UsersPagesRequest = operations['users___pages']['requestBody']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 395156ad93..a10471aa77 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -2570,6 +2570,17 @@ declare module '../api.js' { credential?: string | null, ): Promise>; + /** + * List of following users + * + * **Credential required**: *Yes* / **Permission**: *read:following* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + /** * No description provided. * @@ -4697,17 +4708,6 @@ declare module '../api.js' { credential?: string | null, ): Promise>; - /** - * List of following users with notification enabled. - * - * **Credential required**: *Yes* / **Permission**: *read:following* - */ - request( - endpoint: E, - params: P, - credential?: string | null, - ): Promise>; - /** * Show all pages this user created. * diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index dbbc44cb7b..063691da8d 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -360,6 +360,8 @@ import type { FollowingDeleteResponse, FollowingInvalidateRequest, FollowingInvalidateResponse, + FollowingListRequest, + FollowingListResponse, FollowingRequestsAcceptRequest, FollowingRequestsCancelRequest, FollowingRequestsCancelResponse, @@ -640,8 +642,6 @@ import type { UsersListsUpdateMembershipRequest, UsersNotesRequest, UsersNotesResponse, - UsersNotifyListRequest, - UsersNotifyListResponse, UsersPagesRequest, UsersPagesResponse, UsersReactionsRequest, @@ -896,6 +896,7 @@ export type Endpoints = { 'following/create': { req: FollowingCreateRequest; res: FollowingCreateResponse }; 'following/delete': { req: FollowingDeleteRequest; res: FollowingDeleteResponse }; 'following/invalidate': { req: FollowingInvalidateRequest; res: FollowingInvalidateResponse }; + 'following/list': { req: FollowingListRequest; res: FollowingListResponse }; 'following/requests/accept': { req: FollowingRequestsAcceptRequest; res: EmptyResponse }; 'following/requests/cancel': { req: FollowingRequestsCancelRequest; res: FollowingRequestsCancelResponse }; 'following/requests/list': { req: FollowingRequestsListRequest; res: FollowingRequestsListResponse }; @@ -1086,7 +1087,6 @@ export type Endpoints = { 'users/lists/update': { req: UsersListsUpdateRequest; res: UsersListsUpdateResponse }; 'users/lists/update-membership': { req: UsersListsUpdateMembershipRequest; res: EmptyResponse }; 'users/notes': { req: UsersNotesRequest; res: UsersNotesResponse }; - 'users/notify/list': { req: UsersNotifyListRequest; res: UsersNotifyListResponse }; 'users/pages': { req: UsersPagesRequest; res: UsersPagesResponse }; 'users/reactions': { req: UsersReactionsRequest; res: UsersReactionsResponse }; 'users/recommendation': { req: UsersRecommendationRequest; res: UsersRecommendationResponse }; diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index c2f845d8cc..f7cb34a02e 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -363,6 +363,8 @@ export type FollowingDeleteRequest = operations['following___delete']['requestBo export type FollowingDeleteResponse = operations['following___delete']['responses']['200']['content']['application/json']; export type FollowingInvalidateRequest = operations['following___invalidate']['requestBody']['content']['application/json']; export type FollowingInvalidateResponse = operations['following___invalidate']['responses']['200']['content']['application/json']; +export type FollowingListRequest = operations['following___list']['requestBody']['content']['application/json']; +export type FollowingListResponse = operations['following___list']['responses']['200']['content']['application/json']; export type FollowingRequestsAcceptRequest = operations['following___requests___accept']['requestBody']['content']['application/json']; export type FollowingRequestsCancelRequest = operations['following___requests___cancel']['requestBody']['content']['application/json']; export type FollowingRequestsCancelResponse = operations['following___requests___cancel']['responses']['200']['content']['application/json']; @@ -643,8 +645,6 @@ export type UsersListsUpdateResponse = operations['users___lists___update']['res export type UsersListsUpdateMembershipRequest = operations['users___lists___update-membership']['requestBody']['content']['application/json']; export type UsersNotesRequest = operations['users___notes']['requestBody']['content']['application/json']; export type UsersNotesResponse = operations['users___notes']['responses']['200']['content']['application/json']; -export type UsersNotifyListRequest = operations['users___notify___list']['requestBody']['content']['application/json']; -export type UsersNotifyListResponse = operations['users___notify___list']['responses']['200']['content']['application/json']; export type UsersPagesRequest = operations['users___pages']['requestBody']['content']['application/json']; export type UsersPagesResponse = operations['users___pages']['responses']['200']['content']['application/json']; export type UsersReactionsRequest = operations['users___reactions']['requestBody']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index ecc64039d7..4b6d26b63f 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -2105,6 +2105,15 @@ export type paths = { */ post: operations['following___invalidate']; }; + '/following/list': { + /** + * following/list + * @description List of following users + * + * **Credential required**: *Yes* / **Permission**: *read:following* + */ + post: operations['following___list']; + }; '/following/requests/accept': { /** * following/requests/accept @@ -3852,15 +3861,6 @@ export type paths = { */ post: operations['users___notes']; }; - '/users/notify/list': { - /** - * users/notify/list - * @description List of following users with notification enabled. - * - * **Credential required**: *Yes* / **Permission**: *read:following* - */ - post: operations['users___notify___list']; - }; '/users/pages': { /** * users/pages @@ -22521,6 +22521,80 @@ export interface operations { }; }; }; + following___list: { + requestBody: { + content: { + 'application/json': { + /** @default false */ + notification?: boolean; + /** Format: misskey:id */ + sinceId?: string; + /** Format: misskey:id */ + untilId?: string; + sinceDate?: number; + untilDate?: number; + /** @default 10 */ + limit?: number; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Following'][]; + }; + }; + /** @description Client error */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; following___requests___accept: { requestBody: { content: { @@ -36056,78 +36130,6 @@ export interface operations { }; }; }; - users___notify___list: { - requestBody: { - content: { - 'application/json': { - /** Format: misskey:id */ - sinceId?: string; - /** Format: misskey:id */ - untilId?: string; - sinceDate?: number; - untilDate?: number; - /** @default 10 */ - limit?: number; - }; - }; - }; - responses: { - /** @description OK (with results) */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['UserDetailed'][]; - }; - }; - /** @description Client error */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Error']; - }; - }; - /** @description Authentication error */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Error']; - }; - }; - /** @description Forbidden error */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Error']; - }; - }; - /** @description I'm Ai */ - 418: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Error']; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Error']; - }; - }; - }; - }; users___pages: { requestBody: { content: { From 99081be9fd2404d9a91f4a1f58205254cb54e145 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 09:59:00 +0000 Subject: [PATCH 07/10] Bump version to 2026.5.2-beta.1 --- package.json | 2 +- packages/misskey-js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1a32dc48be..2fbd9ba4cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2026.5.2-beta.0", + "version": "2026.5.2-beta.1", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 90045fd12a..12d63dcd9f 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2026.5.2-beta.0", + "version": "2026.5.2-beta.1", "description": "Misskey SDK for JavaScript", "license": "MIT", "main": "./built/index.js", From fc6c45d175ae37d80fa33709a12b5f033adc7e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Sun, 17 May 2026 19:30:35 +0900 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20add-i18n-key=E3=81=AE=E8=A8=98?= =?UTF-8?q?=E8=BF=B0=E3=81=8C=E9=96=93=E9=81=95=E3=81=A3=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=9F=E3=81=AE=E3=81=A7=E4=BF=AE=E6=AD=A3=20(#17418)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/skills/add-i18n-key/SKILL.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.claude/skills/add-i18n-key/SKILL.md b/.claude/skills/add-i18n-key/SKILL.md index 903cfea217..899c61826d 100644 --- a/.claude/skills/add-i18n-key/SKILL.md +++ b/.claude/skills/add-i18n-key/SKILL.md @@ -26,7 +26,9 @@ _settings: general: "全般" appearance: "外観" -# パラメータ付き (ICU MessageFormat 互換) +# パラメータ付き (単純なプレースホルダ置換) +# ICU MessageFormat の plural / select / number / date などは非対応 +# 使えるのは `{name}` のような単純な置換のみ greeting: "こんにちは、{name}さん" ``` From 2bc0ccb108bfd59227aa86cb1178665d0505544d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 22:14:54 +0000 Subject: [PATCH 09/10] Release: 2026.5.2 --- package.json | 2 +- packages/misskey-js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2fbd9ba4cd..3c52ec40b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2026.5.2-beta.1", + "version": "2026.5.2", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 12d63dcd9f..7fd486067b 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2026.5.2-beta.1", + "version": "2026.5.2", "description": "Misskey SDK for JavaScript", "license": "MIT", "main": "./built/index.js", From badb243021e17d7464741a53dedb3939c42b0893 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 22:15:01 +0000 Subject: [PATCH 10/10] [skip ci] Update CHANGELOG.md (prepend template) --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f026e3f689..bbf9bcbbc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## Unreleased + +### General +- + +### Client +- + +### Server +- + + ## 2026.5.2 ### Note