diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c506c36f6b..25d9cfc1fb 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,7 @@ "version": "22.11.0" }, "ghcr.io/devcontainers-extra/features/pnpm:2": { - "version": "10.6.1" + "version": "10.10.0" } }, "forwardPorts": [3000], diff --git a/.github/workflows/api-misskey-js.yml b/.github/workflows/api-misskey-js.yml index 7d085821b7..6117e69c03 100644 --- a/.github/workflows/api-misskey-js.yml +++ b/.github/workflows/api-misskey-js.yml @@ -22,7 +22,7 @@ jobs: uses: pnpm/action-setup@v4.1.0 - name: Setup Node.js - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/changelog-check.yml b/.github/workflows/changelog-check.yml index 2e94f433b7..5ca27749bb 100644 --- a/.github/workflows/changelog-check.yml +++ b/.github/workflows/changelog-check.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout head uses: actions/checkout@v4.2.2 - name: Setup Node.js - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' diff --git a/.github/workflows/check-misskey-js-autogen.yml b/.github/workflows/check-misskey-js-autogen.yml index 090dc70bd5..22d500c306 100644 --- a/.github/workflows/check-misskey-js-autogen.yml +++ b/.github/workflows/check-misskey-js-autogen.yml @@ -29,7 +29,7 @@ jobs: - name: setup node id: setup-node - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: pnpm diff --git a/.github/workflows/get-api-diff.yml b/.github/workflows/get-api-diff.yml index c5a4f77336..2de73aff09 100644 --- a/.github/workflows/get-api-diff.yml +++ b/.github/workflows/get-api-diff.yml @@ -33,7 +33,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4c8b97e785..f27cce5b97 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -38,7 +38,7 @@ jobs: submodules: true - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - - uses: actions/setup-node@v4.3.0 + - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' @@ -69,7 +69,7 @@ jobs: submodules: true - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - - uses: actions/setup-node@v4.3.0 + - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' @@ -99,7 +99,7 @@ jobs: submodules: true - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - - uses: actions/setup-node@v4.3.0 + - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/locale.yml b/.github/workflows/locale.yml index cee4c27ceb..68e45fdf61 100644 --- a/.github/workflows/locale.yml +++ b/.github/workflows/locale.yml @@ -20,7 +20,7 @@ jobs: submodules: true - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - - uses: actions/setup-node@v4.3.0 + - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/on-release-created.yml b/.github/workflows/on-release-created.yml index 9d15e0fcf1..13390f3aae 100644 --- a/.github/workflows/on-release-created.yml +++ b/.github/workflows/on-release-created.yml @@ -26,7 +26,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 037e6dd7f1..ba745b6a2a 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -35,14 +35,11 @@ jobs: ref: "refs/pull/${{ github.event.number }}/merge" - name: Checkout actual HEAD if: github.event_name == 'pull_request_target' - id: rev - run: | - echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT - git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3) + run: git checkout "$(git rev-list --parents -n1 HEAD | cut -d" " -f3)" - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js 20.x - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' @@ -81,21 +78,16 @@ jobs: if: github.event_name == 'pull_request_target' id: chromatic_pull_request run: | - DIFF="${{ steps.rev.outputs.base }} HEAD" - if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then - DIFF="HEAD" - fi - CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))" + CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF} | xargs))" if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then echo "skip=true" >> $GITHUB_OUTPUT fi - BRANCH="${{ github.event.pull_request.head.user.login }}:$HEAD_REF" - if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then - BRANCH="$HEAD_REF" + BRANCH="${{ github.event.pull_request.head.user.login }}:$GITHUB_HEAD_REF" + if [ "$BRANCH" = "misskey-dev:$GITHUB_HEAD_REF" ]; then + BRANCH="$GITHUB_HEAD_REF" fi pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER") env: - HEAD_REF: ${{ github.event.pull_request.head.ref }} CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - name: Notify that Chromatic detects changes uses: actions/github-script@v7.0.1 diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml index 9c54b3665b..ba4eb27a58 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -62,7 +62,7 @@ jobs: fi done - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -109,7 +109,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-federation.yml b/.github/workflows/test-federation.yml index dc29de4d4f..c739688dc9 100644 --- a/.github/workflows/test-federation.yml +++ b/.github/workflows/test-federation.yml @@ -44,7 +44,7 @@ jobs: fi done - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -71,18 +71,16 @@ jobs: docker compose logs | tail -n 300 exit 1 - name: Test - id: test - continue-on-error: true run: | cd packages/backend/test-federation docker compose run --no-deps tester - name: Log - if: ${{ steps.test.outcome == 'failure' }} + if: always() run: | cd packages/backend/test-federation docker compose logs - exit 1 - name: Stop servers + if: always() run: | cd packages/backend/test-federation docker compose down diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index bec5169ed9..25d263f102 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -38,7 +38,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -93,7 +93,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-misskey-js.yml b/.github/workflows/test-misskey-js.yml index 2d1bd20183..5b3aed9712 100644 --- a/.github/workflows/test-misskey-js.yml +++ b/.github/workflows/test-misskey-js.yml @@ -33,7 +33,7 @@ jobs: uses: pnpm/action-setup@v4.1.0 - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml index b77550a01f..70685e908e 100644 --- a/.github/workflows/test-production.yml +++ b/.github/workflows/test-production.yml @@ -26,7 +26,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/validate-api-json.yml b/.github/workflows/validate-api-json.yml index 4023815cb1..77feb2b373 100644 --- a/.github/workflows/validate-api-json.yml +++ b/.github/workflows/validate-api-json.yml @@ -27,7 +27,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4.1.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/CHANGELOG.md b/CHANGELOG.md index 702b7e52d1..f52bf43171 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Feat: アップロード可能な最大ファイルサイズをロールごとに設定可能に - デフォルトで10MBになっています - Enhance: チャットの新規メッセージをプッシュ通知するように +- Enhance: サーバーブロックの対象になっているサーバーについて、当該サーバーのユーザーや既知投稿を見えないように - Enhance: 依存関係の更新 - Enhance: 翻訳の更新 diff --git a/locales/index.d.ts b/locales/index.d.ts index 97505a1605..1ee01d52f4 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -5402,6 +5402,13 @@ export interface Locale extends ILocale { * 連合ジョブ */ "federationJobs": string; + /** + * ドライブでは、過去にアップロードしたファイルの一覧が表示されます。
+ * ノートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。
+ * ファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。
+ * フォルダを作って整理することもできます。 + */ + "driveAboutTip": string; "_chat": { /** * まだメッセージはありません diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 737e69a376..edb7914110 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1346,6 +1346,7 @@ settingsMigrating: "設定を移行しています。しばらくお待ちくだ readonly: "読み取り専用" goToDeck: "デッキへ戻る" federationJobs: "連合ジョブ" +driveAboutTip: "ドライブでは、過去にアップロードしたファイルの一覧が表示されます。
\nノートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。
\nファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。
\nフォルダを作って整理することもできます。" _chat: noMessagesYet: "まだメッセージはありません" diff --git a/package.json b/package.json index 1c0b492935..2cbb3b41a0 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "misskey", - "version": "2025.4.1-beta.5", + "version": "2025.4.1-beta.7", "codename": "nasubi", "repository": { "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@10.6.1", + "packageManager": "pnpm@10.10.0", "workspaces": [ "packages/frontend-shared", "packages/frontend", @@ -52,29 +52,29 @@ }, "dependencies": { "cssnano": "7.0.6", + "esbuild": "0.25.3", "execa": "9.5.2", "fast-glob": "3.3.3", + "glob": "11.0.2", "ignore-walk": "7.0.0", "js-yaml": "4.1.0", "postcss": "8.5.3", "tar": "7.4.3", "terser": "5.39.0", - "typescript": "5.8.2", - "esbuild": "0.25.0", - "glob": "11.0.1" + "typescript": "5.8.3" }, "devDependencies": { "@misskey-dev/eslint-plugin": "2.1.0", - "@types/node": "22.13.10", - "@typescript-eslint/eslint-plugin": "8.26.0", - "@typescript-eslint/parser": "8.26.0", + "@types/node": "22.15.2", + "@typescript-eslint/eslint-plugin": "8.31.0", + "@typescript-eslint/parser": "8.31.0", "cross-env": "7.0.3", - "cypress": "14.1.0", - "eslint": "9.22.0", + "cypress": "14.3.2", + "eslint": "9.25.1", "globals": "16.0.0", "ncp": "2.0.0", - "pnpm": "10.6.1", - "start-server-and-test": "2.0.10" + "pnpm": "10.10.0", + "start-server-and-test": "2.0.11" }, "optionalDependencies": { "@tensorflow/tfjs-core": "4.22.0" @@ -82,9 +82,6 @@ "pnpm": { "overrides": { "@aiscript-dev/aiscript-languageserver": "-" - }, - "patchedDependencies": { - "re2": "scripts/dependency-patches/re2.patch" } } } diff --git a/packages/backend/package.json b/packages/backend/package.json index 580b6826d0..c4de44df18 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -37,17 +37,17 @@ }, "optionalDependencies": { "@swc/core-android-arm64": "1.3.11", - "@swc/core-darwin-arm64": "1.11.18", - "@swc/core-darwin-x64": "1.11.18", + "@swc/core-darwin-arm64": "1.11.22", + "@swc/core-darwin-x64": "1.11.22", "@swc/core-freebsd-x64": "1.3.11", - "@swc/core-linux-arm-gnueabihf": "1.11.18", - "@swc/core-linux-arm64-gnu": "1.11.18", - "@swc/core-linux-arm64-musl": "1.11.18", - "@swc/core-linux-x64-gnu": "1.11.18", - "@swc/core-linux-x64-musl": "1.11.18", - "@swc/core-win32-arm64-msvc": "1.11.18", - "@swc/core-win32-ia32-msvc": "1.11.18", - "@swc/core-win32-x64-msvc": "1.11.18", + "@swc/core-linux-arm-gnueabihf": "1.11.22", + "@swc/core-linux-arm64-gnu": "1.11.22", + "@swc/core-linux-arm64-musl": "1.11.22", + "@swc/core-linux-x64-gnu": "1.11.22", + "@swc/core-linux-x64-musl": "1.11.22", + "@swc/core-win32-arm64-msvc": "1.11.22", + "@swc/core-win32-ia32-msvc": "1.11.22", + "@swc/core-win32-x64-msvc": "1.11.22", "@tensorflow/tfjs": "4.22.0", "@tensorflow/tfjs-node": "4.22.0", "bufferutil": "4.0.9", @@ -67,8 +67,8 @@ "utf-8-validate": "6.0.5" }, "dependencies": { - "@aws-sdk/client-s3": "3.782.0", - "@aws-sdk/lib-storage": "3.782.0", + "@aws-sdk/client-s3": "3.797.0", + "@aws-sdk/lib-storage": "3.797.0", "@discordapp/twemoji": "15.1.0", "@fastify/accepts": "5.0.2", "@fastify/cookie": "11.0.2", @@ -79,19 +79,19 @@ "@fastify/static": "8.1.1", "@fastify/view": "10.0.2", "@misskey-dev/sharp-read-bmp": "1.3.0", - "@misskey-dev/summaly": "5.2.0", + "@misskey-dev/summaly": "5.2.1", "@napi-rs/canvas": "0.1.69", - "@nestjs/common": "11.0.16", - "@nestjs/core": "11.0.15", - "@nestjs/testing": "11.0.15", + "@nestjs/common": "11.1.0", + "@nestjs/core": "11.1.0", + "@nestjs/testing": "11.1.0", "@peertube/http-signature": "1.7.0", "@sentry/node": "8.55.0", "@sentry/profiling-node": "8.55.0", "@simplewebauthn/server": "12.0.0", "@sinonjs/fake-timers": "11.3.1", "@smithy/node-http-handler": "2.5.0", - "@swc/cli": "0.6.0", - "@swc/core": "1.11.18", + "@swc/cli": "0.7.3", + "@swc/core": "1.11.22", "@twemoji/parser": "15.1.1", "@types/redis-info": "3.0.3", "accepts": "1.3.8", @@ -101,7 +101,7 @@ "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.3", - "bullmq": "5.48.1", + "bullmq": "5.51.1", "cacheable-lookup": "7.0.0", "cbor": "9.0.2", "chalk": "5.4.1", @@ -123,17 +123,17 @@ "hpagent": "1.2.0", "htmlescape": "1.1.1", "http-link-header": "1.1.3", - "ioredis": "5.6.0", + "ioredis": "5.6.1", "ip-cidr": "4.0.2", "ipaddr.js": "2.2.0", "is-svg": "5.1.0", "js-yaml": "4.1.0", - "jsdom": "26.0.0", + "jsdom": "26.1.0", "json5": "2.2.3", "jsonld": "8.3.3", "jsrsasign": "11.1.0", "juice": "11.0.1", - "meilisearch": "0.49.0", + "meilisearch": "0.50.0", "mfm-js": "0.24.0", "microformats-parser": "2.0.2", "mime-types": "2.1.35", @@ -143,15 +143,15 @@ "nanoid": "5.1.5", "nested-property": "4.0.0", "node-fetch": "3.3.2", - "nodemailer": "6.10.0", + "nodemailer": "6.10.1", "nsfwjs": "4.2.0", "oauth": "0.10.2", "oauth2orize": "1.12.0", "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", "otpauth": "9.4.0", - "parse5": "7.2.1", - "pg": "8.14.1", + "parse5": "7.3.0", + "pg": "8.15.6", "pkce-challenge": "4.1.0", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", @@ -166,7 +166,7 @@ "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.2", - "sanitize-html": "2.15.0", + "sanitize-html": "2.16.0", "secure-json-parse": "3.0.2", "sharp": "0.34.1", "slacc": "0.0.10", @@ -187,10 +187,10 @@ }, "devDependencies": { "@jest/globals": "29.7.0", - "@nestjs/platform-express": "10.4.15", - "@sentry/vue": "9.12.0", + "@nestjs/platform-express": "10.4.17", + "@sentry/vue": "9.14.0", "@simplewebauthn/types": "12.0.0", - "@swc/jest": "0.2.37", + "@swc/jest": "0.2.38", "@types/accepts": "1.3.7", "@types/archiver": "6.0.3", "@types/bcryptjs": "2.4.6", @@ -207,12 +207,12 @@ "@types/jsrsasign": "10.5.15", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "22.14.0", + "@types/node": "22.15.2", "@types/nodemailer": "6.4.17", "@types/oauth": "0.9.6", "@types/oauth2orize": "1.11.5", "@types/oauth2orize-pkce": "0.1.2", - "@types/pg": "8.11.11", + "@types/pg": "8.11.14", "@types/pug": "2.0.10", "@types/qrcode": "1.5.5", "@types/random-seed": "0.3.5", @@ -228,8 +228,8 @@ "@types/vary": "1.1.3", "@types/web-push": "3.6.4", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.29.1", - "@typescript-eslint/parser": "8.29.1", + "@typescript-eslint/eslint-plugin": "8.31.0", + "@typescript-eslint/parser": "8.31.0", "aws-sdk-client-mock": "4.1.0", "cross-env": "7.0.3", "eslint-plugin-import": "2.31.0", @@ -237,7 +237,7 @@ "fkill": "9.0.0", "jest": "29.7.0", "jest-mock": "29.7.0", - "nodemon": "3.1.9", + "nodemon": "3.1.10", "pid-port": "1.0.2", "simple-oauth2": "5.1.0", "supertest": "7.1.0" diff --git a/packages/backend/src/core/FanoutTimelineEndpointService.ts b/packages/backend/src/core/FanoutTimelineEndpointService.ts index ce8cc83dfd..1ffeb4b3a4 100644 --- a/packages/backend/src/core/FanoutTimelineEndpointService.ts +++ b/packages/backend/src/core/FanoutTimelineEndpointService.ts @@ -8,10 +8,12 @@ import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import type { MiUser } from '@/models/User.js'; import type { MiNote } from '@/models/Note.js'; +import type { MiMeta } from '@/models/Meta.js'; import { Packed } from '@/misc/json-schema.js'; import type { NotesRepository } from '@/models/_.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { FanoutTimelineName, FanoutTimelineService } from '@/core/FanoutTimelineService.js'; +import { UtilityService } from '@/core/UtilityService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { isQuote, isRenote } from '@/misc/is-renote.js'; import { CacheService } from '@/core/CacheService.js'; @@ -30,6 +32,7 @@ type TimelineOptions = { alwaysIncludeMyNotes?: boolean; ignoreAuthorFromBlock?: boolean; ignoreAuthorFromMute?: boolean; + ignoreAuthorFromInstanceBlock?: boolean; excludeNoFiles?: boolean; excludeReplies?: boolean; excludePureRenotes: boolean; @@ -42,9 +45,13 @@ export class FanoutTimelineEndpointService { @Inject(DI.notesRepository) private notesRepository: NotesRepository, + @Inject(DI.meta) + private meta: MiMeta, + private noteEntityService: NoteEntityService, private cacheService: CacheService, private fanoutTimelineService: FanoutTimelineService, + private utilityService: UtilityService, ) { } @@ -119,6 +126,19 @@ export class FanoutTimelineEndpointService { }; } + { + const parentFilter = filter; + filter = (note) => { + if (!ps.ignoreAuthorFromInstanceBlock) { + if (this.utilityService.isBlockedHost(this.meta.blockedHosts, note.userHost)) return false; + } + if (note.userId !== note.renoteUserId && this.utilityService.isBlockedHost(this.meta.blockedHosts, note.renoteUserHost)) return false; + if (note.userId !== note.replyUserId && this.utilityService.isBlockedHost(this.meta.blockedHosts, note.replyUserHost)) return false; + + return parentFilter(note); + }; + } + const redisTimeline: MiNote[] = []; let readFromRedis = 0; let lastSuccessfulRate = 1; // rateをキャッシュする? diff --git a/packages/backend/src/core/QueryService.ts b/packages/backend/src/core/QueryService.ts index 412ab33b3f..119eb49c02 100644 --- a/packages/backend/src/core/QueryService.ts +++ b/packages/backend/src/core/QueryService.ts @@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Brackets, ObjectLiteral } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { MiUser } from '@/models/User.js'; -import type { UserProfilesRepository, FollowingsRepository, ChannelFollowingsRepository, BlockingsRepository, NoteThreadMutingsRepository, MutingsRepository, RenoteMutingsRepository } from '@/models/_.js'; +import type { UserProfilesRepository, FollowingsRepository, ChannelFollowingsRepository, BlockingsRepository, NoteThreadMutingsRepository, MutingsRepository, RenoteMutingsRepository, MiMeta } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; import type { SelectQueryBuilder } from 'typeorm'; @@ -36,6 +36,9 @@ export class QueryService { @Inject(DI.renoteMutingsRepository) private renoteMutingsRepository: RenoteMutingsRepository, + @Inject(DI.meta) + private meta: MiMeta, + private idService: IdService, ) { } @@ -251,4 +254,37 @@ export class QueryService { q.setParameters(mutingQuery.getParameters()); } + + @bindThis + public generateBlockedHostQueryForNote(q: SelectQueryBuilder, excludeAuthor?: boolean): void { + let nonBlockedHostQuery: (part: string) => string; + if (this.meta.blockedHosts.length === 0) { + nonBlockedHostQuery = () => '1=1'; + } else { + nonBlockedHostQuery = (match: string) => `${match} NOT ILIKE ALL(ARRAY[:...blocked])`; + q.setParameters({ blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }); + } + + if (excludeAuthor) { + const instanceSuspension = (user: string) => new Brackets(qb => qb + .where(`note.${user}Id IS NULL`) // no corresponding user + .orWhere(`note.userId = note.${user}Id`) + .orWhere(`note.${user}Host IS NULL`) // local + .orWhere(nonBlockedHostQuery(`note.${user}Host`))); + + q + .andWhere(instanceSuspension('replyUser')) + .andWhere(instanceSuspension('renoteUser')); + } else { + const instanceSuspension = (user: string) => new Brackets(qb => qb + .where(`note.${user}Id IS NULL`) // no corresponding user + .orWhere(`note.${user}Host IS NULL`) // local + .orWhere(nonBlockedHostQuery(`note.${user}Host`))); + + q + .andWhere(instanceSuspension('user')) + .andWhere(instanceSuspension('replyUser')) + .andWhere(instanceSuspension('renoteUser')); + } + } } diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index aa787c93de..d94281920e 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -234,6 +234,7 @@ export class SearchService { } this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); if (me) this.queryService.generateMutedUserQueryForNotes(query, me); if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); @@ -295,9 +296,14 @@ export class SearchService { this.cacheService.userBlockedCache.fetch(me.id), ]) : [new Set(), new Set()]; - const notes = (await this.notesRepository.findBy({ - id: In(res.hits.map(x => x.id)), - })).filter(note => { + + const query = this.notesRepository.createQueryBuilder('note'); + + query.where('note.id IN (:...noteIds)', { noteIds: res.hits.map(x => x.id) }); + + this.queryService.generateBlockedHostQueryForNote(query); + + const notes = (await query.getMany()).filter(note => { if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false; if (me && isUserRelated(note, userIdsWhoMeMuting)) return false; return true; diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index a44eb6720b..4708dab73c 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -111,6 +111,7 @@ export default class extends Endpoint { // eslint- // NOTE: センシティブ除外の設定はこのエンドポイントでは無視する。 // https://github.com/misskey-dev/misskey/pull/15346#discussion_r1929950255 + this.queryService.generateBlockedHostQueryForNote(query); this.queryService.generateVisibilityQuery(query, me); this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index cec5f8fd9c..620cdb0f5d 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -121,6 +121,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('note.channel', 'channel'); + this.queryService.generateBlockedHostQueryForNote(query); if (me) { this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/chat/messages/delete.ts b/packages/backend/src/server/api/endpoints/chat/messages/delete.ts index 63b75fb6a7..52a054303b 100644 --- a/packages/backend/src/server/api/endpoints/chat/messages/delete.ts +++ b/packages/backend/src/server/api/endpoints/chat/messages/delete.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchMessage: { message: 'No such message.', diff --git a/packages/backend/src/server/api/endpoints/chat/messages/react.ts b/packages/backend/src/server/api/endpoints/chat/messages/react.ts index 5f61e7e992..2197e7bf80 100644 --- a/packages/backend/src/server/api/endpoints/chat/messages/react.ts +++ b/packages/backend/src/server/api/endpoints/chat/messages/react.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchMessage: { message: 'No such message.', diff --git a/packages/backend/src/server/api/endpoints/chat/messages/unreact.ts b/packages/backend/src/server/api/endpoints/chat/messages/unreact.ts index 6784bb6ecf..adfcd232f9 100644 --- a/packages/backend/src/server/api/endpoints/chat/messages/unreact.ts +++ b/packages/backend/src/server/api/endpoints/chat/messages/unreact.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchMessage: { message: 'No such message.', diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/delete.ts b/packages/backend/src/server/api/endpoints/chat/rooms/delete.ts index 82a8e1f30d..1ea81448c1 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/delete.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/delete.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchRoom: { message: 'No such room.', diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/ignore.ts b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/ignore.ts index b8a228089b..88ea234527 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/ignore.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/ignore.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchRoom: { message: 'No such room.', diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/join.ts b/packages/backend/src/server/api/endpoints/chat/rooms/join.ts index d561f9e03f..550b4da1a6 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/join.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/join.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchRoom: { message: 'No such room.', diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/leave.ts b/packages/backend/src/server/api/endpoints/chat/rooms/leave.ts index a3ad0c2d6f..f99b408d67 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/leave.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/leave.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchRoom: { message: 'No such room.', diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/mute.ts b/packages/backend/src/server/api/endpoints/chat/rooms/mute.ts index 11cbe7b8b9..ee60f92505 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/mute.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/mute.ts @@ -16,9 +16,6 @@ export const meta = { kind: 'write:chat', - res: { - }, - errors: { noSuchRoom: { message: 'No such room.', diff --git a/packages/backend/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts index 7638aae442..2b65407cea 100644 --- a/packages/backend/src/server/api/endpoints/clips/notes.ts +++ b/packages/backend/src/server/api/endpoints/clips/notes.ts @@ -85,6 +85,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .andWhere('clipNote.clipId = :clipId', { clipId: clip.id }); + this.queryService.generateBlockedHostQueryForNote(query); if (me) { this.queryService.generateVisibilityQuery(query, me); this.queryService.generateMutedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts index e73c98282c..218a3c1a4c 100644 --- a/packages/backend/src/server/api/endpoints/notes/children.ts +++ b/packages/backend/src/server/api/endpoints/notes/children.ts @@ -70,6 +70,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); if (me) { this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts index dcd971360d..e7aba2d306 100644 --- a/packages/backend/src/server/api/endpoints/notes/featured.ts +++ b/packages/backend/src/server/api/endpoints/notes/featured.ts @@ -11,6 +11,7 @@ import { DI } from '@/di-symbols.js'; import { FeaturedService } from '@/core/FeaturedService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { CacheService } from '@/core/CacheService.js'; +import { QueryService } from '@/core/QueryService.js'; export const meta = { tags: ['notes'], @@ -52,6 +53,7 @@ export default class extends Endpoint { // eslint- private cacheService: CacheService, private noteEntityService: NoteEntityService, private featuredService: FeaturedService, + private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { let noteIds: string[]; @@ -94,6 +96,8 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('note.channel', 'channel'); + this.queryService.generateBlockedHostQueryForNote(query); + const notes = (await query.getMany()).filter(note => { if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false; if (me && isUserRelated(note, userIdsWhoMeMuting)) return false; diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index 99d1c9f19c..39b519a599 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -243,6 +243,7 @@ export default class extends Endpoint { // eslint- } this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); this.queryService.generateMutedUserRenotesQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index 97acf2ad39..8b2d5397b2 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -156,6 +156,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); if (me) this.queryService.generateMutedUserQueryForNotes(query, me); if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); if (me) this.queryService.generateMutedUserRenotesQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts index bbb63646e9..f5cddd5bad 100644 --- a/packages/backend/src/server/api/endpoints/notes/mentions.ts +++ b/packages/backend/src/server/api/endpoints/notes/mentions.ts @@ -72,6 +72,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateMutedNoteThreadQuery(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/renotes.ts b/packages/backend/src/server/api/endpoints/notes/renotes.ts index b34d9261a1..178e311ed1 100644 --- a/packages/backend/src/server/api/endpoints/notes/renotes.ts +++ b/packages/backend/src/server/api/endpoints/notes/renotes.ts @@ -72,6 +72,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); if (me) this.queryService.generateMutedUserQueryForNotes(query, me); if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/replies.ts b/packages/backend/src/server/api/endpoints/notes/replies.ts index f36af1a328..d9aaed2f10 100644 --- a/packages/backend/src/server/api/endpoints/notes/replies.ts +++ b/packages/backend/src/server/api/endpoints/notes/replies.ts @@ -56,6 +56,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); if (me) this.queryService.generateMutedUserQueryForNotes(query, me); if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts index c45851548a..079231d432 100644 --- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts +++ b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts @@ -81,6 +81,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); if (me) this.queryService.generateMutedUserQueryForNotes(query, me); if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index a88b28892e..42752eaeec 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -199,6 +199,7 @@ export default class extends Endpoint { // eslint- })); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); this.queryService.generateMutedUserRenotesQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts index 80f1c69b25..58a4223207 100644 --- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts @@ -184,6 +184,7 @@ export default class extends Endpoint { // eslint- })); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); this.queryService.generateMutedUserRenotesQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/roles/notes.ts b/packages/backend/src/server/api/endpoints/roles/notes.ts index 6cd9f80929..b0d3f6d2f9 100644 --- a/packages/backend/src/server/api/endpoints/roles/notes.ts +++ b/packages/backend/src/server/api/endpoints/roles/notes.ts @@ -102,6 +102,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/users/featured-notes.ts b/packages/backend/src/server/api/endpoints/users/featured-notes.ts index e01f19ba7a..053fd60548 100644 --- a/packages/backend/src/server/api/endpoints/users/featured-notes.ts +++ b/packages/backend/src/server/api/endpoints/users/featured-notes.ts @@ -11,6 +11,7 @@ import { DI } from '@/di-symbols.js'; import { FeaturedService } from '@/core/FeaturedService.js'; import { CacheService } from '@/core/CacheService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; +import { QueryService } from '@/core/QueryService.js'; export const meta = { tags: ['notes'], @@ -49,6 +50,7 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private featuredService: FeaturedService, private cacheService: CacheService, + private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { const userIdsWhoBlockingMe = me ? await this.cacheService.userBlockedCache.fetch(me.id) : new Set(); @@ -85,6 +87,8 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('note.channel', 'channel'); + this.queryService.generateBlockedHostQueryForNote(query); + const notes = (await query.getMany()).filter(note => { if (me && isUserRelated(note, userIdsWhoBlockingMe, false)) return false; if (me && isUserRelated(note, userIdsWhoMeMuting, true)) return false; diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index f5b7a07b01..b0585f75fc 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -129,6 +129,7 @@ export default class extends Endpoint { // eslint- redisTimelines, useDbFallback: true, ignoreAuthorFromMute: true, + ignoreAuthorFromInstanceBlock: true, excludeReplies: ps.withChannelNotes && !ps.withReplies, // userTimelineWithChannel may include replies excludeNoFiles: ps.withChannelNotes && ps.withFiles, // userTimelineWithChannel may include notes without files excludePureRenotes: !ps.withRenotes, @@ -184,6 +185,7 @@ export default class extends Endpoint { // eslint- } this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query, true); if (me) { this.queryService.generateMutedUserQueryForNotes(query, me, { id: ps.userId }); this.queryService.generateBlockedUserQueryForNotes(query, me); diff --git a/packages/backend/src/server/api/endpoints/users/reactions.ts b/packages/backend/src/server/api/endpoints/users/reactions.ts index 7805ae3288..bb9000a7a0 100644 --- a/packages/backend/src/server/api/endpoints/users/reactions.ts +++ b/packages/backend/src/server/api/endpoints/users/reactions.ts @@ -102,6 +102,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('reaction.note', 'note'); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateBlockedHostQueryForNote(query); const reactions = (await query .limit(ps.limit) diff --git a/packages/backend/test-federation/compose.tpl.yml b/packages/backend/test-federation/compose.tpl.yml index 25770063d3..a7e907c3ee 100644 --- a/packages/backend/test-federation/compose.tpl.yml +++ b/packages/backend/test-federation/compose.tpl.yml @@ -74,10 +74,6 @@ services: source: ../../../pnpm-workspace.yaml target: /misskey/pnpm-workspace.yaml read_only: true - - type: bind - source: ../../../scripts/dependency-patches - target: /misskey/scripts/dependency-patches - read_only: true - type: bind source: ./certificates/rootCA.crt target: /usr/local/share/ca-certificates/rootCA.crt diff --git a/packages/backend/test-federation/compose.yml b/packages/backend/test-federation/compose.yml index dfa51b940a..4df4ced365 100644 --- a/packages/backend/test-federation/compose.yml +++ b/packages/backend/test-federation/compose.yml @@ -70,10 +70,6 @@ services: source: ../../../pnpm-workspace.yaml target: /misskey/pnpm-workspace.yaml read_only: true - - type: bind - source: ../../../scripts/dependency-patches - target: /misskey/scripts/dependency-patches - read_only: true - type: bind source: ./certificates/rootCA.crt target: /usr/local/share/ca-certificates/rootCA.crt @@ -118,10 +114,6 @@ services: source: ../../../pnpm-workspace.yaml target: /misskey/pnpm-workspace.yaml read_only: true - - type: bind - source: ../../../scripts/dependency-patches - target: /misskey/scripts/dependency-patches - read_only: true working_dir: /misskey command: > bash -c " diff --git a/packages/frontend-embed/package.json b/packages/frontend-embed/package.json index c253a653ee..6a2d6afb38 100644 --- a/packages/frontend-embed/package.json +++ b/packages/frontend-embed/package.json @@ -26,29 +26,29 @@ "mfm-js": "0.24.0", "misskey-js": "workspace:*", "punycode.js": "2.3.1", - "rollup": "4.39.0", - "sass": "1.86.3", - "shiki": "3.2.2", + "rollup": "4.40.0", + "sass": "1.87.0", + "shiki": "3.3.0", "tinycolor2": "1.6.0", "tsc-alias": "1.8.15", "tsconfig-paths": "4.2.0", "typescript": "5.8.3", "uuid": "11.1.0", - "vite": "6.3.1", + "vite": "6.3.3", "vue": "3.5.13" }, "devDependencies": { - "@misskey-dev/summaly": "5.2.0", + "@misskey-dev/summaly": "5.2.1", "@testing-library/vue": "8.1.0", "@types/estree": "1.0.7", "@types/micromatch": "4.0.9", - "@types/node": "22.14.0", + "@types/node": "22.15.2", "@types/punycode.js": "npm:@types/punycode@2.1.4", "@types/tinycolor2": "1.4.6", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.29.1", - "@typescript-eslint/parser": "8.29.1", - "@vitest/coverage-v8": "3.1.1", + "@typescript-eslint/eslint-plugin": "8.31.0", + "@typescript-eslint/parser": "8.31.0", + "@vitest/coverage-v8": "3.1.2", "@vue/runtime-core": "3.5.13", "acorn": "8.14.1", "cross-env": "7.0.3", @@ -58,13 +58,13 @@ "happy-dom": "17.4.4", "intersection-observer": "0.12.2", "micromatch": "4.0.8", - "msw": "2.7.3", - "nodemon": "3.1.9", + "msw": "2.7.5", + "nodemon": "3.1.10", "prettier": "3.5.3", "start-server-and-test": "2.0.11", "vite-plugin-turbosnap": "1.0.3", - "vue-component-type-helpers": "2.2.8", + "vue-component-type-helpers": "2.2.10", "vue-eslint-parser": "10.1.3", - "vue-tsc": "2.2.8" + "vue-tsc": "2.2.10" } } diff --git a/packages/frontend-shared/package.json b/packages/frontend-shared/package.json index b22bdc713b..1ec6eb3559 100644 --- a/packages/frontend-shared/package.json +++ b/packages/frontend-shared/package.json @@ -21,12 +21,12 @@ "lint": "pnpm typecheck && pnpm eslint" }, "devDependencies": { - "@types/node": "22.14.0", - "@typescript-eslint/eslint-plugin": "8.29.1", - "@typescript-eslint/parser": "8.29.1", - "esbuild": "0.25.2", + "@types/node": "22.15.2", + "@typescript-eslint/eslint-plugin": "8.31.0", + "@typescript-eslint/parser": "8.31.0", + "esbuild": "0.25.3", "eslint-plugin-vue": "10.0.0", - "nodemon": "3.1.9", + "nodemon": "3.1.10", "typescript": "5.8.3", "vue-eslint-parser": "10.1.3" }, diff --git a/packages/frontend/package.json b/packages/frontend/package.json index a771885bcb..02f050467f 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -24,7 +24,7 @@ "@rollup/plugin-json": "6.1.0", "@rollup/plugin-replace": "6.0.2", "@rollup/pluginutils": "5.1.4", - "@sentry/vue": "9.12.0", + "@sentry/vue": "9.14.0", "@syuilo/aiscript": "0.19.0", "@tabler/icons-webfont": "3.31.0", "@twemoji/parser": "15.1.1", @@ -36,12 +36,12 @@ "broadcast-channel": "7.1.0", "buraha": "0.0.1", "canvas-confetti": "1.9.3", - "chart.js": "4.4.8", + "chart.js": "4.4.9", "chartjs-adapter-date-fns": "3.0.0", "chartjs-chart-matrix": "2.1.1", "chartjs-plugin-gradient": "0.6.1", "chartjs-plugin-zoom": "2.2.0", - "chromatic": "11.28.0", + "chromatic": "11.28.2", "compare-versions": "6.1.1", "cropperjs": "2.0.0", "date-fns": "4.1.0", @@ -60,13 +60,13 @@ "misskey-reversi": "workspace:*", "photoswipe": "5.4.4", "punycode.js": "2.3.1", - "rollup": "4.39.0", - "sanitize-html": "2.15.0", - "sass": "1.86.3", - "shiki": "3.2.2", + "rollup": "4.40.0", + "sanitize-html": "2.16.0", + "sass": "1.87.0", + "shiki": "3.3.0", "strict-event-emitter-types": "2.0.0", "textarea-caret": "3.1.0", - "three": "0.175.0", + "three": "0.176.0", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", "tsc-alias": "1.8.15", @@ -74,13 +74,13 @@ "typescript": "5.8.3", "uuid": "11.1.0", "v-code-diff": "1.13.1", - "vite": "6.3.1", + "vite": "6.3.3", "vue": "3.5.13", "vuedraggable": "next", "wanakana": "5.3.1" }, "devDependencies": { - "@misskey-dev/summaly": "5.2.0", + "@misskey-dev/summaly": "5.2.1", "@storybook/addon-actions": "8.6.12", "@storybook/addon-essentials": "8.6.12", "@storybook/addon-interactions": "8.6.12", @@ -104,21 +104,21 @@ "@types/estree": "1.0.7", "@types/matter-js": "0.19.8", "@types/micromatch": "4.0.9", - "@types/node": "22.14.0", + "@types/node": "22.15.2", "@types/punycode.js": "npm:@types/punycode@2.1.4", "@types/sanitize-html": "2.15.0", "@types/seedrandom": "3.0.8", "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.29.1", - "@typescript-eslint/parser": "8.29.1", - "@vitest/coverage-v8": "3.1.1", + "@typescript-eslint/eslint-plugin": "8.31.0", + "@typescript-eslint/parser": "8.31.0", + "@vitest/coverage-v8": "3.1.2", "@vue/compiler-core": "3.5.13", "@vue/runtime-core": "3.5.13", "acorn": "8.14.1", "cross-env": "7.0.3", - "cypress": "14.3.0", + "cypress": "14.3.2", "eslint-plugin-import": "2.31.0", "eslint-plugin-vue": "10.0.0", "fast-glob": "3.3.3", @@ -126,9 +126,9 @@ "intersection-observer": "0.12.2", "micromatch": "4.0.8", "minimatch": "10.0.1", - "msw": "2.7.3", + "msw": "2.7.5", "msw-storybook-addon": "2.0.4", - "nodemon": "3.1.9", + "nodemon": "3.1.10", "prettier": "3.5.3", "react": "19.1.0", "react-dom": "19.1.0", @@ -137,10 +137,10 @@ "storybook": "8.6.12", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "vite-plugin-turbosnap": "1.0.3", - "vitest": "3.1.1", + "vitest": "3.1.2", "vitest-fetch-mock": "0.4.5", - "vue-component-type-helpers": "2.2.8", + "vue-component-type-helpers": "2.2.10", "vue-eslint-parser": "10.1.3", - "vue-tsc": "2.2.8" + "vue-tsc": "2.2.10" } } diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue index 6270ac8314..a1f76ac563 100644 --- a/packages/frontend/src/components/MkDrive.vue +++ b/packages/frontend/src/components/MkDrive.vue @@ -45,6 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only @contextmenu.stop="onContextmenu" >
+
{ if (prefer.s.enableInfiniteScroll && loadMoreFiles.value) { nextTick(() => { diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue index 2f42403613..1236b843f2 100644 --- a/packages/frontend/src/components/MkFolder.vue +++ b/packages/frontend/src/components/MkFolder.vue @@ -31,10 +31,6 @@ SPDX-License-Identifier: AGPL-3.0-only :leaveActiveClass="prefer.s.animation ? $style.transition_toggle_leaveActive : ''" :enterFromClass="prefer.s.animation ? $style.transition_toggle_enterFrom : ''" :leaveToClass="prefer.s.animation ? $style.transition_toggle_leaveTo : ''" - @enter="enter" - @afterEnter="afterEnter" - @leave="leave" - @afterLeave="afterLeave" >
@@ -90,32 +86,6 @@ const bgSame = ref(false); const opened = ref(props.defaultOpen); const openedAtLeastOnce = ref(props.defaultOpen); -function enter(el: Element) { - if (!(el instanceof HTMLElement)) return; - const elementHeight = el.getBoundingClientRect().height; - el.style.height = '0'; - el.offsetHeight; // reflow - el.style.height = `${Math.min(elementHeight, props.maxHeight ?? Infinity)}px`; -} - -function afterEnter(el: Element) { - if (!(el instanceof HTMLElement)) return; - el.style.height = ''; -} - -function leave(el: Element) { - if (!(el instanceof HTMLElement)) return; - const elementHeight = el.getBoundingClientRect().height; - el.style.height = `${elementHeight}px`; - el.offsetHeight; // reflow - el.style.height = '0'; -} - -function afterLeave(el: Element) { - if (!(el instanceof HTMLElement)) return; - el.style.height = ''; -} - function toggle() { if (!opened.value) { openedAtLeastOnce.value = true; @@ -137,16 +107,18 @@ onMounted(() => { diff --git a/packages/frontend/src/pages/admin/custom-emojis-manager.local.list.vue b/packages/frontend/src/pages/admin/custom-emojis-manager.local.list.vue index 260177c894..59b780bff6 100644 --- a/packages/frontend/src/pages/admin/custom-emojis-manager.local.list.vue +++ b/packages/frontend/src/pages/admin/custom-emojis-manager.local.list.vue @@ -285,7 +285,7 @@ const searchQuery = ref({ localOnly: null, roles: [], sortOrders: [], - limit: 25, + limit: 100, }); let searchWindowOpening = false; diff --git a/packages/frontend/src/pages/admin/custom-emojis-manager.remote.vue b/packages/frontend/src/pages/admin/custom-emojis-manager.remote.vue index c868a700f1..2fd7e331a2 100644 --- a/packages/frontend/src/pages/admin/custom-emojis-manager.remote.vue +++ b/packages/frontend/src/pages/admin/custom-emojis-manager.remote.vue @@ -142,6 +142,10 @@ SPDX-License-Identifier: AGPL-3.0-only