diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d4678ec5e0..b1c256225d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,7 +9,7 @@ updates: directory: "/" schedule: interval: daily - open-pull-requests-limit: 100 + open-pull-requests-limit: 0 # Add only the root, not each workspace item # https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027 @@ -17,7 +17,7 @@ updates: directory: "/" schedule: interval: daily - open-pull-requests-limit: 10 + open-pull-requests-limit: 0 # List dependencies required to be updated together, sharing the same version numbers. # Those who simply have the common owner (e.g. @fastify) don't need to be listed. groups: diff --git a/.github/workflows/api-misskey-js.yml b/.github/workflows/api-misskey-js.yml index 6f4219b54b..fdd128be33 100644 --- a/.github/workflows/api-misskey-js.yml +++ b/.github/workflows/api-misskey-js.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - run: corepack enable - name: Setup Node.js - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/changelog-check.yml b/.github/workflows/changelog-check.yml index fdca621cfc..52acbfebeb 100644 --- a/.github/workflows/changelog-check.yml +++ b/.github/workflows/changelog-check.yml @@ -12,9 +12,9 @@ jobs: steps: - name: Checkout head - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - name: Setup Node.js - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.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 bb15541941..50a8c3ab34 100644 --- a/.github/workflows/check-misskey-js-autogen.yml +++ b/.github/workflows/check-misskey-js-autogen.yml @@ -18,7 +18,7 @@ jobs: if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} steps: - name: checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 with: submodules: true persist-credentials: false @@ -29,7 +29,7 @@ jobs: - name: setup node id: setup-node - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version-file: '.node-version' cache: pnpm @@ -66,7 +66,7 @@ jobs: if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} steps: - name: checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 with: submodules: true persist-credentials: false diff --git a/.github/workflows/check-misskey-js-version.yml b/.github/workflows/check-misskey-js-version.yml index 99c29ac974..2b15cbee53 100644 --- a/.github/workflows/check-misskey-js-version.yml +++ b/.github/workflows/check-misskey-js-version.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - name: Check version run: | if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then diff --git a/.github/workflows/check-spdx-license-id.yml b/.github/workflows/check-spdx-license-id.yml index 05582008b5..bc6be308d1 100644 --- a/.github/workflows/check-spdx-license-id.yml +++ b/.github/workflows/check-spdx-license-id.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - name: Check run: | counter=0 diff --git a/.github/workflows/check_copyright_year.yml b/.github/workflows/check_copyright_year.yml index 03dfcd0a0b..eaf922d4bc 100644 --- a/.github/workflows/check_copyright_year.yml +++ b/.github/workflows/check_copyright_year.yml @@ -10,7 +10,7 @@ jobs: check_copyright_year: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 - run: | if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then echo "Please change copyright year!" diff --git a/.github/workflows/deploy-test-environment.yml b/.github/workflows/deploy-test-environment.yml index 66b15beb91..46baf7421b 100644 --- a/.github/workflows/deploy-test-environment.yml +++ b/.github/workflows/deploy-test-environment.yml @@ -28,7 +28,7 @@ jobs: wait_time: ${{ steps.get-wait-time.outputs.wait_time }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - name: Check allowed users id: check-allowed-users diff --git a/.github/workflows/docker-develop.yml b/.github/workflows/docker-develop.yml index ac2b1b4d35..56dedf273d 100644 --- a/.github/workflows/docker-develop.yml +++ b/.github/workflows/docker-develop.yml @@ -27,7 +27,7 @@ jobs: platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Check out the repo - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index db899ba386..eb98273ba0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -32,7 +32,7 @@ jobs: platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Check out the repo - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Docker meta diff --git a/.github/workflows/dockle.yml b/.github/workflows/dockle.yml index c3dba4213d..3054607913 100644 --- a/.github/workflows/dockle.yml +++ b/.github/workflows/dockle.yml @@ -15,7 +15,7 @@ jobs: DOCKER_CONTENT_TRUST: 1 DOCKLE_VERSION: 0.4.14 steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 - name: Download and install dockle v${{ env.DOCKLE_VERSION }} run: | curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb" diff --git a/.github/workflows/get-api-diff.yml b/.github/workflows/get-api-diff.yml index 6805e8bc3c..2da9647460 100644 --- a/.github/workflows/get-api-diff.yml +++ b/.github/workflows/get-api-diff.yml @@ -30,14 +30,14 @@ jobs: ref: refs/pull/${{ github.event.number }}/merge steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: ref: ${{ matrix.ref }} submodules: true - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2f6938d2e4..0f9d25ff35 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -36,12 +36,12 @@ jobs: pnpm_install: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: fetch-depth: 0 submodules: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4.1.0 + - uses: actions/setup-node@v4.2.0 with: node-version-file: '.node-version' cache: 'pnpm' @@ -67,12 +67,12 @@ jobs: eslint-cache-version: v1 eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }} steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: fetch-depth: 0 submodules: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4.1.0 + - uses: actions/setup-node@v4.2.0 with: node-version-file: '.node-version' cache: 'pnpm' @@ -97,12 +97,12 @@ jobs: - sw - misskey-js steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: fetch-depth: 0 submodules: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4.1.0 + - uses: actions/setup-node@v4.2.0 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/locale.yml b/.github/workflows/locale.yml index 95d29bf828..2daeaa3bd7 100644 --- a/.github/workflows/locale.yml +++ b/.github/workflows/locale.yml @@ -18,12 +18,12 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: fetch-depth: 0 submodules: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4.1.0 + - uses: actions/setup-node@v4.2.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 fc224a6239..8e4ad4368b 100644 --- a/.github/workflows/on-release-created.yml +++ b/.github/workflows/on-release-created.yml @@ -23,13 +23,13 @@ jobs: node-version: [22.11.0] steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index be294201f0..9e5a79faac 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -26,12 +26,12 @@ jobs: NODE_OPTIONS: "--max_old_space_size=7168" steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 if: github.event_name != 'pull_request_target' with: fetch-depth: 0 submodules: true - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 if: github.event_name == 'pull_request_target' with: fetch-depth: 0 @@ -46,7 +46,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js 20.x - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml index 99a9f99b75..2b8092cf45 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -45,7 +45,7 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true - name: Install pnpm @@ -66,7 +66,7 @@ jobs: fi done - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -108,13 +108,13 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-federation.yml b/.github/workflows/test-federation.yml index 74cdff80f1..e7b5d7b098 100644 --- a/.github/workflows/test-federation.yml +++ b/.github/workflows/test-federation.yml @@ -47,7 +47,7 @@ jobs: fi done - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index 6c09896d06..e489ebf07c 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -36,13 +36,13 @@ jobs: node-version: [22.11.0] steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -86,7 +86,7 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true # https://github.com/cypress-io/cypress-docker-images/issues/150 @@ -98,7 +98,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.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 d88dc18bd8..05f757acc1 100644 --- a/.github/workflows/test-misskey-js.yml +++ b/.github/workflows/test-misskey-js.yml @@ -31,12 +31,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.2.2 - run: corepack enable - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml index 5269358e38..56e42213ff 100644 --- a/.github/workflows/test-production.yml +++ b/.github/workflows/test-production.yml @@ -21,13 +21,13 @@ jobs: node-version: [22.11.0] steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.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 65afcd4cd0..a8b2402988 100644 --- a/.github/workflows/validate-api-json.yml +++ b/.github/workflows/validate-api-json.yml @@ -25,13 +25,13 @@ jobs: node-version: [22.11.0] steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.2.2 with: submodules: true - name: Install pnpm uses: pnpm/action-setup@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@v4.2.0 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/CHANGELOG.md b/CHANGELOG.md index dc3d9969c3..bd996af636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ -## Unreleased +## 2025.2.1 ### General - Enhance: アンテナでセンシティブなチャンネルのノートを除外できるように `#14177` - Feat: アクセストークン発行時に通知するように +- 依存関係の更新 ### Client - Feat: 投稿フォームで画像をプレビュー可能に @@ -10,13 +11,21 @@ - Enhance: アンテナ、リスト等の名前をカラム名のデフォルト値にするように `#13992` - Enhance: クライアントエラー画面の多言語対応 - Enhance: 開発者モードでメニューからファイルIDをコピー出来るように `#15441' +- Enhance: ノートに埋め込まれたメディアのコンテキストメニューから管理者用のファイル管理画面を開けるように ( #15440 ) +- Enhance: リアクションする際に確認ダイアログを表示できるように +- Enhance: CWの注釈で入力済みの文字数を表示 - Fix: コンディショナルロールを手動で割り当てできる導線を削除 `#13529` - Fix: 埋め込みプレイヤーから外部ページに移動できない問題を修正 +- Fix: Play の再読込時に UI が以前の状態を引き継いでしまう問題を修正 `#14378` +- Fix: カスタム絵文字管理画面(beta)にてisSensitive/localOnlyの絞り込みが上手くいかない問題の修正 ( #15445 ) +- Fix: CWの注釈が100文字を超えている場合、ノート投稿ボタンを非アクティブに ### Server - Fix: `following/invalidate`でフォロワーを解除しようとしているユーザーの情報を返すように - Fix: オブジェクトストレージの設定でPrefixを設定していなかった場合nullまたは空文字になる問題を修正 - +- Fix: pgroongaでの検索時にはじめのキーワードのみが検索に使用される問題を修正 + (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/886) +- Fix: メールアドレスの形式が正しくなければ以降の処理を行わないように ## 2025.2.0 diff --git a/locales/index.d.ts b/locales/index.d.ts index b723ea3dea..97e41c8a9e 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -5258,6 +5258,14 @@ export interface Locale extends ILocale { * このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。 */ "federationDisabled": string; + /** + * リアクションする際に確認する + */ + "confirmOnReact": string; + /** + * " {emoji} " をリアクションしますか? + */ + "reactAreYouSure": ParameterizedString<"emoji">; "_accountSettings": { /** * コンテンツの表示にログインを必須にする diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 7988bb7e21..844bc74c8a 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1310,6 +1310,8 @@ availableRoles: "利用可能なロール" acknowledgeNotesAndEnable: "注意事項を理解した上でオンにします。" federationSpecified: "このサーバーはホワイトリスト連合で運用されています。管理者が指定したサーバー以外とやり取りすることはできません。" federationDisabled: "このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。" +confirmOnReact: "リアクションする際に確認する" +reactAreYouSure: "\" {emoji} \" をリアクションしますか?" _accountSettings: requireSigninToViewContents: "コンテンツの表示にログインを必須にする" diff --git a/package.json b/package.json index 52c139342f..222ca2e455 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "misskey", - "version": "2025.2.0", + "version": "2025.2.1-alpha.0", "codename": "nasubi", "repository": { "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@9.6.0", + "packageManager": "pnpm@9.15.4", "workspaces": [ "packages/frontend-shared", "packages/frontend", @@ -47,35 +47,35 @@ "cleanall": "pnpm clean-all" }, "resolutions": { - "chokidar": "3.5.3", + "chokidar": "3.6.0", "lodash": "4.17.21" }, "dependencies": { - "cssnano": "6.1.2", + "cssnano": "7.0.6", "execa": "8.0.1", - "fast-glob": "3.3.2", + "fast-glob": "3.3.3", "ignore-walk": "6.0.5", "js-yaml": "4.1.0", - "postcss": "8.4.49", + "postcss": "8.5.2", "tar": "6.2.1", - "terser": "5.36.0", - "typescript": "5.6.3", - "esbuild": "0.24.0", - "glob": "11.0.0" + "terser": "5.39.0", + "typescript": "5.7.3", + "esbuild": "0.25.0", + "glob": "11.0.1" }, "devDependencies": { - "@misskey-dev/eslint-plugin": "2.0.3", - "@types/node": "22.9.0", - "@typescript-eslint/eslint-plugin": "7.17.0", - "@typescript-eslint/parser": "7.17.0", + "@misskey-dev/eslint-plugin": "2.1.0", + "@types/node": "22.13.4", + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", "cross-env": "7.0.3", - "cypress": "13.15.2", - "eslint": "9.14.0", - "globals": "15.12.0", + "cypress": "14.0.3", + "eslint": "9.20.1", + "globals": "15.15.0", "ncp": "2.0.0", - "start-server-and-test": "2.0.8" + "start-server-and-test": "2.0.10" }, "optionalDependencies": { - "@tensorflow/tfjs-core": "4.4.0" + "@tensorflow/tfjs-core": "4.22.0" } } diff --git a/packages/backend/package.json b/packages/backend/package.json index 757912755a..cee5c7205b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -37,20 +37,20 @@ }, "optionalDependencies": { "@swc/core-android-arm64": "1.3.11", - "@swc/core-darwin-arm64": "1.3.56", - "@swc/core-darwin-x64": "1.3.56", + "@swc/core-darwin-arm64": "1.10.16", + "@swc/core-darwin-x64": "1.10.16", "@swc/core-freebsd-x64": "1.3.11", - "@swc/core-linux-arm-gnueabihf": "1.3.56", - "@swc/core-linux-arm64-gnu": "1.3.56", - "@swc/core-linux-arm64-musl": "1.3.56", - "@swc/core-linux-x64-gnu": "1.3.56", - "@swc/core-linux-x64-musl": "1.3.56", - "@swc/core-win32-arm64-msvc": "1.3.56", - "@swc/core-win32-ia32-msvc": "1.3.56", - "@swc/core-win32-x64-msvc": "1.3.56", - "@tensorflow/tfjs": "4.4.0", - "@tensorflow/tfjs-node": "4.4.0", - "bufferutil": "4.0.7", + "@swc/core-linux-arm-gnueabihf": "1.10.16", + "@swc/core-linux-arm64-gnu": "1.10.16", + "@swc/core-linux-arm64-musl": "1.10.16", + "@swc/core-linux-x64-gnu": "1.10.16", + "@swc/core-linux-x64-musl": "1.10.16", + "@swc/core-win32-arm64-msvc": "1.10.16", + "@swc/core-win32-ia32-msvc": "1.10.16", + "@swc/core-win32-x64-msvc": "1.10.16", + "@tensorflow/tfjs": "4.22.0", + "@tensorflow/tfjs-node": "4.22.0", + "bufferutil": "4.0.9", "slacc-android-arm-eabi": "0.0.10", "slacc-android-arm64": "0.0.10", "slacc-darwin-arm64": "0.0.10", @@ -64,37 +64,37 @@ "slacc-linux-x64-musl": "0.0.10", "slacc-win32-arm64-msvc": "0.0.10", "slacc-win32-x64-msvc": "0.0.10", - "utf-8-validate": "6.0.3" + "utf-8-validate": "6.0.5" }, "dependencies": { - "@aws-sdk/client-s3": "3.620.0", - "@aws-sdk/lib-storage": "3.620.0", - "@bull-board/api": "6.5.0", - "@bull-board/fastify": "6.5.0", - "@bull-board/ui": "6.5.0", + "@aws-sdk/client-s3": "3.749.0", + "@aws-sdk/lib-storage": "3.749.0", + "@bull-board/api": "6.7.7", + "@bull-board/fastify": "6.7.7", + "@bull-board/ui": "6.7.7", "@discordapp/twemoji": "15.1.0", - "@fastify/accepts": "5.0.1", - "@fastify/cookie": "11.0.1", - "@fastify/cors": "10.0.1", - "@fastify/express": "4.0.1", - "@fastify/http-proxy": "10.0.1", - "@fastify/multipart": "9.0.1", - "@fastify/static": "8.0.2", - "@fastify/view": "10.0.1", + "@fastify/accepts": "5.0.2", + "@fastify/cookie": "11.0.2", + "@fastify/cors": "10.0.2", + "@fastify/express": "4.0.2", + "@fastify/http-proxy": "10.0.2", + "@fastify/multipart": "9.0.3", + "@fastify/static": "8.1.0", + "@fastify/view": "10.0.2", "@misskey-dev/sharp-read-bmp": "1.2.0", - "@misskey-dev/summaly": "5.1.0", - "@napi-rs/canvas": "0.1.56", - "@nestjs/common": "10.4.7", - "@nestjs/core": "10.4.7", - "@nestjs/testing": "10.4.7", + "@misskey-dev/summaly": "5.2.0", + "@napi-rs/canvas": "0.1.67", + "@nestjs/common": "11.0.9", + "@nestjs/core": "11.0.9", + "@nestjs/testing": "11.0.9", "@peertube/http-signature": "1.7.0", - "@sentry/node": "8.38.0", - "@sentry/profiling-node": "8.38.0", - "@simplewebauthn/server": "10.0.1", - "@sinonjs/fake-timers": "11.2.2", + "@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.3.12", - "@swc/core": "1.9.2", + "@swc/cli": "0.6.0", + "@swc/core": "1.10.16", "@twemoji/parser": "15.1.1", "accepts": "1.3.8", "ajv": "8.17.1", @@ -103,10 +103,10 @@ "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.3", - "bullmq": "5.26.1", + "bullmq": "5.41.1", "cacheable-lookup": "7.0.0", "cbor": "9.0.2", - "chalk": "5.3.0", + "chalk": "5.4.1", "chalk-template": "1.1.0", "chokidar": "3.6.0", "cli-highlight": "2.1.11", @@ -114,46 +114,46 @@ "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "fastify": "5.0.0", + "fastify": "5.2.1", "fastify-raw-body": "5.0.0", "feed": "4.2.2", "file-type": "19.6.0", "fluent-ffmpeg": "2.1.3", - "form-data": "4.0.1", - "got": "14.4.4", - "happy-dom": "15.11.4", + "form-data": "4.0.2", + "got": "14.4.6", + "happy-dom": "16.8.1", "hpagent": "1.2.0", "htmlescape": "1.1.1", "http-link-header": "1.1.3", - "ioredis": "5.4.1", + "ioredis": "5.5.0", "ip-cidr": "4.0.2", "ipaddr.js": "2.2.0", "is-svg": "5.1.0", "js-yaml": "4.1.0", - "jsdom": "24.1.1", + "jsdom": "26.0.0", "json5": "2.2.3", - "jsonld": "8.3.2", + "jsonld": "8.3.3", "jsrsasign": "11.1.0", "juice": "11.0.0", - "meilisearch": "0.45.0", + "meilisearch": "0.48.2", "mfm-js": "0.24.0", "microformats-parser": "2.0.2", "mime-types": "2.1.35", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", "ms": "3.0.0-canary.1", - "nanoid": "5.0.8", + "nanoid": "5.1.0", "nested-property": "4.0.0", "node-fetch": "3.3.2", - "nodemailer": "6.9.16", + "nodemailer": "6.10.0", "nsfwjs": "4.2.0", "oauth": "0.10.0", "oauth2orize": "1.12.0", "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", - "otpauth": "9.3.4", + "otpauth": "9.3.6", "parse5": "7.2.1", - "pg": "8.13.1", + "pg": "8.13.3", "pkce-challenge": "4.1.0", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", @@ -167,19 +167,19 @@ "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.1", - "sanitize-html": "2.13.1", - "secure-json-parse": "2.7.0", + "sanitize-html": "2.14.0", + "secure-json-parse": "3.0.2", "sharp": "0.33.5", "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", - "systeminformation": "5.23.5", + "systeminformation": "5.25.11", "tinycolor2": "1.6.0", "tmp": "0.2.3", "tsc-alias": "1.8.10", "tsconfig-paths": "4.2.0", "typeorm": "0.3.20", - "typescript": "5.6.3", + "typescript": "5.7.3", "ulid": "2.3.0", "vary": "1.1.2", "web-push": "3.6.7", @@ -188,8 +188,8 @@ }, "devDependencies": { "@jest/globals": "29.7.0", - "@nestjs/platform-express": "10.4.7", - "@simplewebauthn/types": "10.0.0", + "@nestjs/platform-express": "10.4.15", + "@simplewebauthn/types": "12.0.0", "@swc/jest": "0.2.37", "@types/accepts": "1.3.7", "@types/archiver": "6.0.3", @@ -204,15 +204,15 @@ "@types/js-yaml": "4.0.9", "@types/jsdom": "21.1.7", "@types/jsonld": "1.5.15", - "@types/jsrsasign": "10.5.14", + "@types/jsrsasign": "10.5.15", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "22.9.0", - "@types/nodemailer": "6.4.16", + "@types/node": "22.13.4", + "@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.10", + "@types/pg": "8.11.11", "@types/pug": "2.0.10", "@types/qrcode": "1.5.5", "@types/random-seed": "0.3.5", @@ -226,18 +226,18 @@ "@types/tmp": "0.2.6", "@types/vary": "1.1.3", "@types/web-push": "3.6.4", - "@types/ws": "8.5.13", - "@typescript-eslint/eslint-plugin": "7.17.0", - "@typescript-eslint/parser": "7.17.0", - "aws-sdk-client-mock": "4.0.1", + "@types/ws": "8.5.14", + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", + "aws-sdk-client-mock": "4.1.0", "cross-env": "7.0.3", - "eslint-plugin-import": "2.30.0", + "eslint-plugin-import": "2.31.0", "execa": "8.0.1", "fkill": "9.0.0", "jest": "29.7.0", "jest-mock": "29.7.0", - "nodemon": "3.1.7", - "pid-port": "1.0.0", + "nodemon": "3.1.9", + "pid-port": "1.0.2", "simple-oauth2": "5.1.0" } } diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index c0b1484804..d5fd2ba558 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -105,8 +105,8 @@ type Source = { logging?: { sql?: { - disableQueryTruncation? : boolean, - enableQueryParamLogging? : boolean, + disableQueryTruncation?: boolean, + enableQueryParamLogging?: boolean, } } }; @@ -166,8 +166,8 @@ export type Config = { signToActivityPubGet: boolean | undefined; logging?: { sql?: { - disableQueryTruncation? : boolean, - enableQueryParamLogging? : boolean, + disableQueryTruncation?: boolean, + enableQueryParamLogging?: boolean, } } diff --git a/packages/backend/src/core/CaptchaService.ts b/packages/backend/src/core/CaptchaService.ts index 8c7f66236e..ee081f29b0 100644 --- a/packages/backend/src/core/CaptchaService.ts +++ b/packages/backend/src/core/CaptchaService.ts @@ -43,7 +43,7 @@ export type CaptchaSetting = { siteKey: string | null; secretKey: string | null; } -} +}; export class CaptchaError extends Error { public readonly code: CaptchaErrorCode; @@ -59,11 +59,11 @@ export class CaptchaError extends Error { export type CaptchaSaveSuccess = { success: true; -} +}; export type CaptchaSaveFailure = { success: false; error: CaptchaError; -} +}; export type CaptchaSaveResult = CaptchaSaveSuccess | CaptchaSaveFailure; type CaptchaResponse = { diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index da198d0e42..45d7ea11e4 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -164,6 +164,13 @@ export class EmailService { available: boolean; reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned' | 'network' | 'blacklist'; }> { + if (!this.utilityService.validateEmailFormat(emailAddress)) { + return { + available: false, + reason: 'format', + }; + } + const exist = await this.userProfilesRepository.countBy({ emailVerified: true, email: emailAddress, diff --git a/packages/backend/src/core/FanoutTimelineService.ts b/packages/backend/src/core/FanoutTimelineService.ts index f6dabfadcd..24999bf4da 100644 --- a/packages/backend/src/core/FanoutTimelineService.ts +++ b/packages/backend/src/core/FanoutTimelineService.ts @@ -9,7 +9,7 @@ import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; -export type FanoutTimelineName = +export type FanoutTimelineName = ( // home timeline | `homeTimeline:${string}` | `homeTimelineWithFiles:${string}` // only notes with files are included @@ -37,6 +37,7 @@ export type FanoutTimelineName = // role timelines | `roleTimeline:${string}` // any notes are included +); @Injectable() export class FanoutTimelineService { diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index 03646ff566..224fdabc4c 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -211,7 +211,7 @@ type SerializedAll = { type UndefinedAsNullAll = { [K in keyof T]: T[K] extends undefined ? null : T[K]; -} +}; export interface InternalEventTypes { userChangeSuspendedState: { id: MiUser['id']; isSuspended: MiUser['isSuspended']; }; diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index bf06d4457e..00208927e2 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -492,7 +492,8 @@ export class MfmService { appendChildren(nodes, body); - const serialized = new XMLSerializer().serializeToString(body); + // Remove the unnecessary namespace + const serialized = new XMLSerializer().serializeToString(body).replace(/^\s*

/, '

'); happyDOM.close().catch(err => {}); diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index 64e3f2f56a..bc62559e46 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -220,7 +220,7 @@ export class SearchService { .leftJoinAndSelect('renote.user', 'renoteUser'); if (this.config.fulltextSearch?.provider === 'sqlPgroonga') { - query.andWhere('note.text &@ :q', { q }); + query.andWhere('note.text &@~ :q', { q }); } else { query.andWhere('LOWER(note.text) LIKE :q', { q: `%${ sqlLikeEscape(q.toLowerCase()) }%` }); } diff --git a/packages/backend/src/core/UserWebhookService.ts b/packages/backend/src/core/UserWebhookService.ts index b1728671ae..9b0a598a1b 100644 --- a/packages/backend/src/core/UserWebhookService.ts +++ b/packages/backend/src/core/UserWebhookService.ts @@ -15,7 +15,7 @@ import { QueueService } from '@/core/QueueService.js'; import type { OnApplicationShutdown } from '@nestjs/common'; export type UserWebhookPayload = - T extends 'note' | 'reply' | 'renote' |'mention' ? { + T extends 'note' | 'reply' | 'renote' | 'mention' ? { note: Packed<'Note'>, } : T extends 'follow' | 'unfollow' ? { diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index fcb750d3bf..23fb928ac9 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -38,6 +38,14 @@ export class UtilityService { return this.punyHost(uri) === this.toPuny(this.config.host); } + // メールアドレスのバリデーションを行う + // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address + @bindThis + public validateEmailFormat(email: string): boolean { + const regexp = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; + return regexp.test(email); + } + @bindThis public isBlockedHost(blockedHosts: string[], host: string | null): boolean { if (host == null) return false; diff --git a/packages/backend/src/core/WebAuthnService.ts b/packages/backend/src/core/WebAuthnService.ts index ed75e4f467..372e1e2ab7 100644 --- a/packages/backend/src/core/WebAuthnService.ts +++ b/packages/backend/src/core/WebAuthnService.ts @@ -127,11 +127,11 @@ export class WebAuthnService { const { registrationInfo } = verification; return { - credentialID: registrationInfo.credentialID, - credentialPublicKey: registrationInfo.credentialPublicKey, + credentialID: registrationInfo.credential.id, + credentialPublicKey: registrationInfo.credential.publicKey, attestationObject: registrationInfo.attestationObject, fmt: registrationInfo.fmt, - counter: registrationInfo.counter, + counter: registrationInfo.credential.counter, userVerified: registrationInfo.userVerified, credentialDeviceType: registrationInfo.credentialDeviceType, credentialBackedUp: registrationInfo.credentialBackedUp, @@ -212,9 +212,9 @@ export class WebAuthnService { expectedChallenge: challenge, expectedOrigin: relyingParty.origin, expectedRPID: relyingParty.rpId, - authenticator: { - credentialID: key.id, - credentialPublicKey: Buffer.from(key.publicKey, 'base64url'), + credential: { + id: key.id, + publicKey: Buffer.from(key.publicKey, 'base64url'), counter: key.counter, transports: key.transports ? key.transports as AuthenticatorTransportFuture[] : undefined, }, @@ -292,9 +292,9 @@ export class WebAuthnService { expectedChallenge: challenge, expectedOrigin: relyingParty.origin, expectedRPID: relyingParty.rpId, - authenticator: { - credentialID: key.id, - credentialPublicKey: Buffer.from(key.publicKey, 'base64url'), + credential: { + id: key.id, + publicKey: Buffer.from(key.publicKey, 'base64url'), counter: key.counter, transports: key.transports ? key.transports as AuthenticatorTransportFuture[] : undefined, }, diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index d3c087a153..fbd3892dd4 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -57,12 +57,14 @@ const ajv = new Ajv(); function isLocalUser(user: MiUser): user is MiLocalUser; function isLocalUser(user: T): user is (T & { host: null; }); + function isLocalUser(user: MiUser | { host: MiUser['host'] }): boolean { return user.host == null; } function isRemoteUser(user: MiUser): user is MiRemoteUser; function isRemoteUser(user: T): user is (T & { host: string; }); + function isRemoteUser(user: MiUser | { host: MiUser['host'] }): boolean { return !isLocalUser(user); } @@ -78,7 +80,7 @@ export type UserRelation = { isBlocked: boolean isMuted: boolean isRenoteMuted: boolean -} +}; @Injectable() export class UserEntityService implements OnModuleInit { diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index f612591eda..ac74d68c95 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -143,7 +143,7 @@ type OfSchema = { readonly anyOf?: ReadonlyArray; readonly oneOf?: ReadonlyArray; readonly allOf?: ReadonlyArray; -} +}; export interface Schema extends OfSchema { readonly type?: TypeStringef; @@ -217,7 +217,7 @@ type ObjectSchemaTypeDef

= : p['anyOf'] extends ReadonlyArray ? never : // see CONTRIBUTING.md p['allOf'] extends ReadonlyArray ? UnionToIntersection> : - any + any; type ObjectSchemaType

= NullOrUndefined>; diff --git a/packages/backend/src/misc/json-value.ts b/packages/backend/src/misc/json-value.ts index bd7fe12058..195f7c4d47 100644 --- a/packages/backend/src/misc/json-value.ts +++ b/packages/backend/src/misc/json-value.ts @@ -4,7 +4,7 @@ */ export type JsonValue = JsonArray | JsonObject | string | number | boolean | null; -export type JsonObject = {[K in string]?: JsonValue}; +export type JsonObject = { [K in string]?: JsonValue }; export type JsonArray = JsonValue[]; export function isJsonObject(value: JsonValue | undefined): value is JsonObject { diff --git a/packages/backend/src/models/User.ts b/packages/backend/src/models/User.ts index 96de30c4c2..549d78a22c 100644 --- a/packages/backend/src/models/User.ts +++ b/packages/backend/src/models/User.ts @@ -288,24 +288,24 @@ export class MiUser { export type MiLocalUser = MiUser & { host: null; uri: null; -} +}; export type MiPartialLocalUser = Partial & { id: MiUser['id']; host: null; uri: null; -} +}; export type MiRemoteUser = MiUser & { host: string; uri: string; -} +}; export type MiPartialRemoteUser = Partial & { id: MiUser['id']; host: string; uri: string; -} +}; export const localUsernameSchema = { type: 'string', pattern: /^\w{1,20}$/.toString().slice(1, -1) } as const; export const passwordSchema = { type: 'string', minLength: 1 } as const; diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts index d09240eba1..8a0b7d97d7 100644 --- a/packages/backend/src/postgres.ts +++ b/packages/backend/src/postgres.ts @@ -92,7 +92,7 @@ const sqlLogger = dbLogger.createSubLogger('sql', 'gray'); export type LoggerProps = { disableQueryTruncation?: boolean; enableQueryParamLogging?: boolean; -} +}; function highlightSql(sql: string) { return highlight.highlight(sql, { diff --git a/packages/backend/src/queue/processors/CheckModeratorsActivityProcessorService.ts b/packages/backend/src/queue/processors/CheckModeratorsActivityProcessorService.ts index 2e84430e72..c9fe4fca73 100644 --- a/packages/backend/src/queue/processors/CheckModeratorsActivityProcessorService.ts +++ b/packages/backend/src/queue/processors/CheckModeratorsActivityProcessorService.ts @@ -29,7 +29,7 @@ export type ModeratorInactivityEvaluationResult = { isModeratorsInactive: boolean; inactiveModerators: MiUser[]; remainingTime: ModeratorInactivityRemainingTime; -} +}; export type ModeratorInactivityRemainingTime = { time: number; diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 004fe1382d..079e014da8 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -107,12 +107,12 @@ export class InboxProcessorService implements OnApplicationShutdown { // それでもわからなければ終了 if (authUser == null) { - throw new Bull.UnrecoverableError('skip: failed to resolve user'); + throw new Bull.UnrecoverableError(`skip: failed to resolve user ${getApId(activity.actor)}`); } // publicKey がなくても終了 if (authUser.key == null) { - throw new Bull.UnrecoverableError('skip: failed to resolve user publicKey'); + throw new Bull.UnrecoverableError(`skip: failed to resolve user publicKey ${getApId(activity.actor)}`); } // HTTP-Signatureの検証 diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts index 5db919a149..757daea88b 100644 --- a/packages/backend/src/queue/types.ts +++ b/packages/backend/src/queue/types.ts @@ -38,7 +38,7 @@ export type RelationshipJobData = { silent?: boolean; requestId?: string; withReplies?: boolean; -} +}; export type DbJobData = DbJobMap[T]; @@ -61,11 +61,11 @@ export type DbJobMap = { importUserLists: DbUserImportJobData; importCustomEmojis: DbUserImportJobData; deleteAccount: DbUserDeleteJobData; -} +}; export type DbJobDataWithUser = { user: ThinUser; -} +}; export type DbExportFollowingData = { user: ThinUser; @@ -75,7 +75,7 @@ export type DbExportFollowingData = { export type DBExportAntennasData = { user: ThinUser -} +}; export type DbUserDeleteJobData = { user: ThinUser; @@ -91,7 +91,7 @@ export type DbUserImportJobData = { export type DBAntennaImportJobData = { user: ThinUser, antenna: Antenna -} +}; export type DbUserImportToDbJobData = { user: ThinUser; diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index a9a2ebc041..7f4ca9c0e0 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -122,7 +122,7 @@ export type IEndpointMeta = (Omit & { requireAdmin: true, kind: (typeof permissions)[number], -}) +}); export interface IEndpoint { name: string; diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index 84cb552369..686aea423c 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -82,8 +82,8 @@ export default abstract class Channel { this.connection = connection; } - public send(payload: { type: string, body: JsonValue }): void - public send(type: string, payload: JsonValue): void + public send(payload: { type: string, body: JsonValue }): void; + public send(type: string, payload: JsonValue): void; @bindThis public send(typeOrPayload: { type: string, body: JsonValue } | string, payload?: JsonValue) { const type = payload === undefined ? (typeOrPayload as { type: string, body: JsonValue }).type : (typeOrPayload as string); @@ -108,4 +108,4 @@ export type MiChannelService = { requireCredential: T; kind: T extends true ? string : string | null | undefined; create: (id: string, connection: Connection) => Channel; -} +}; diff --git a/packages/backend/test-federation/test/utils.ts b/packages/backend/test-federation/test/utils.ts index 093277cdb4..db8da5025a 100644 --- a/packages/backend/test-federation/test/utils.ts +++ b/packages/backend/test-federation/test/utils.ts @@ -22,7 +22,7 @@ export type LoginUser = SigninResponse & { client: Misskey.api.APIClient; username: string; password: string; -} +}; /** used for avoiding overload and some endpoints */ export type Request = < diff --git a/packages/backend/test/e2e/fetch-resource.ts b/packages/backend/test/e2e/fetch-resource.ts index 8ea4cb9800..b85cebf724 100644 --- a/packages/backend/test/e2e/fetch-resource.ts +++ b/packages/backend/test/e2e/fetch-resource.ts @@ -10,13 +10,13 @@ import { channel, clip, cookie, galleryPost, page, play, post, signup, simpleGet import type { SimpleGetResponse } from '../utils.js'; import type * as misskey from 'misskey-js'; -// Request Accept +// Request Accept in lowercase const ONLY_AP = 'application/activity+json'; const PREFER_AP = 'application/activity+json, */*'; const PREFER_HTML = 'text/html, */*'; const UNSPECIFIED = '*/*'; -// Response Content-Type +// Response Content-Type in lowercase const AP = 'application/activity+json; charset=utf-8'; const HTML = 'text/html; charset=utf-8'; const JSON_UTF8 = 'application/json; charset=utf-8'; @@ -44,7 +44,8 @@ describe('Webリソース', () => { const { path, accept, cookie, type } = param; const res = await simpleGet(path, accept, cookie); assert.strictEqual(res.status, 200); - assert.strictEqual(res.type, type ?? HTML); + // Header values are case-insensitive + assert.strictEqual(res.type?.toLowerCase(), (type ?? HTML).toLowerCase()); return res; }; @@ -95,8 +96,7 @@ describe('Webリソース', () => { describe.each([ { path: '/', type: HTML }, { path: '/docs/ja-JP/about', type: HTML }, // "指定されたURLに該当するページはありませんでした。" - // fastify-static gives charset=UTF-8 instead of utf-8 and that's okay - { path: '/api-doc', type: 'text/html; charset=UTF-8' }, + { path: '/api-doc', type: HTML }, { path: '/api.json', type: JSON_UTF8 }, { path: '/api-console', type: HTML }, { path: '/_info_card_', type: HTML }, diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts index 36af8823f6..7350da3cae 100644 --- a/packages/backend/test/unit/MfmService.ts +++ b/packages/backend/test/unit/MfmService.ts @@ -24,13 +24,13 @@ describe('MfmService', () => { describe('toHtml', () => { test('br', () => { const input = 'foo\nbar\nbaz'; - const output = '

foo
bar
baz

'; + const output = '

foo
bar
baz

'; assert.equal(mfmService.toHtml(mfm.parse(input)), output); }); test('br alt', () => { const input = 'foo\r\nbar\rbaz'; - const output = '

foo
bar
baz

'; + const output = '

foo
bar
baz

'; assert.equal(mfmService.toHtml(mfm.parse(input)), output); }); diff --git a/packages/frontend-embed/package.json b/packages/frontend-embed/package.json index ab5026ab0d..97d10938b6 100644 --- a/packages/frontend-embed/package.json +++ b/packages/frontend-embed/package.json @@ -12,12 +12,12 @@ "dependencies": { "@discordapp/twemoji": "15.1.0", "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-replace": "5.0.7", - "@rollup/pluginutils": "5.1.3", - "@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.29.0-mi.1913+5921534bc.tar.gz", + "@rollup/plugin-replace": "6.0.2", + "@rollup/pluginutils": "5.1.4", + "@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.30.0-mi.1932+ab127beee.tar.gz", "@twemoji/parser": "15.1.1", - "@vitejs/plugin-vue": "5.2.0", - "@vue/compiler-sfc": "3.5.12", + "@vitejs/plugin-vue": "5.2.1", + "@vue/compiler-sfc": "3.5.13", "astring": "1.9.0", "buraha": "0.0.1", "estree-walker": "3.0.3", @@ -25,47 +25,46 @@ "misskey-js": "workspace:*", "frontend-shared": "workspace:*", "punycode.js": "2.3.1", - "rollup": "4.26.0", - "sass": "1.79.4", - "shiki": "1.22.2", + "rollup": "4.34.7", + "sass": "1.85.0", + "shiki": "2.4.1", "tinycolor2": "1.6.0", "tsc-alias": "1.8.10", "tsconfig-paths": "4.2.0", - "typescript": "5.6.3", - "uuid": "10.0.0", + "typescript": "5.7.3", + "uuid": "11.0.5", "json5": "2.2.3", - "vite": "5.4.11", - "vue": "3.5.12" + "vite": "6.1.0", + "vue": "3.5.13" }, "devDependencies": { - "@misskey-dev/summaly": "5.1.0", + "@misskey-dev/summaly": "5.2.0", "@testing-library/vue": "8.1.0", "@types/estree": "1.0.6", "@types/micromatch": "4.0.9", - "@types/node": "22.9.0", + "@types/node": "22.13.4", "@types/punycode.js": "npm:@types/punycode@2.1.4", "@types/tinycolor2": "1.4.6", - "@types/uuid": "10.0.0", - "@types/ws": "8.5.13", - "@typescript-eslint/eslint-plugin": "7.17.0", - "@typescript-eslint/parser": "7.17.0", - "@vitest/coverage-v8": "1.6.0", - "@vue/runtime-core": "3.5.12", + "@types/ws": "8.5.14", + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", + "@vitest/coverage-v8": "3.0.5", + "@vue/runtime-core": "3.5.13", "acorn": "8.14.0", "cross-env": "7.0.3", "eslint-plugin-import": "2.31.0", - "eslint-plugin-vue": "9.31.0", - "fast-glob": "3.3.2", - "happy-dom": "10.0.3", + "eslint-plugin-vue": "9.32.0", + "fast-glob": "3.3.3", + "happy-dom": "17.1.0", "intersection-observer": "0.12.2", "micromatch": "4.0.8", - "msw": "2.6.4", - "nodemon": "3.1.7", - "prettier": "3.3.3", - "start-server-and-test": "2.0.8", + "msw": "2.7.0", + "nodemon": "3.1.9", + "prettier": "3.5.1", + "start-server-and-test": "2.0.10", "vite-plugin-turbosnap": "1.0.3", - "vue-component-type-helpers": "2.1.10", + "vue-component-type-helpers": "2.2.2", "vue-eslint-parser": "9.4.3", - "vue-tsc": "2.1.10" + "vue-tsc": "2.2.2" } } diff --git a/packages/frontend-embed/src/post-message.ts b/packages/frontend-embed/src/post-message.ts index fd8eb8a5d2..93b57c380b 100644 --- a/packages/frontend-embed/src/post-message.ts +++ b/packages/frontend-embed/src/post-message.ts @@ -21,7 +21,7 @@ export type MiPostMessageEvent ({ name: x[1] as string, diff --git a/packages/frontend-shared/js/i18n.ts b/packages/frontend-shared/js/i18n.ts index 18232691fa..480cfcd642 100644 --- a/packages/frontend-shared/js/i18n.ts +++ b/packages/frontend-shared/js/i18n.ts @@ -2,6 +2,7 @@ * SPDX-FileCopyrightText: syuilo and misskey-project * SPDX-License-Identifier: AGPL-3.0-only */ + import type { ILocale, ParameterizedString } from '../../../locales/index.js'; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/frontend-shared/js/scroll.ts b/packages/frontend-shared/js/scroll.ts index 4f2e9105c3..508864b12c 100644 --- a/packages/frontend-shared/js/scroll.ts +++ b/packages/frontend-shared/js/scroll.ts @@ -134,7 +134,6 @@ export function scrollToBottom( export function isTopVisible(el: HTMLElement, tolerance = 1): boolean { const scrollTop = getScrollPosition(el); - if (_DEV_) console.log(scrollTop, tolerance, scrollTop <= tolerance); return scrollTop <= tolerance; } diff --git a/packages/frontend-shared/package.json b/packages/frontend-shared/package.json index 4e681393c6..b9ed5e00cc 100644 --- a/packages/frontend-shared/package.json +++ b/packages/frontend-shared/package.json @@ -21,13 +21,13 @@ "lint": "pnpm typecheck && pnpm eslint" }, "devDependencies": { - "@types/node": "22.9.0", - "@typescript-eslint/eslint-plugin": "7.17.0", - "@typescript-eslint/parser": "7.17.0", - "esbuild": "0.24.0", - "eslint-plugin-vue": "9.31.0", - "nodemon": "3.1.7", - "typescript": "5.6.3", + "@types/node": "22.13.4", + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", + "esbuild": "0.25.0", + "eslint-plugin-vue": "9.32.0", + "nodemon": "3.1.9", + "typescript": "5.7.3", "vue-eslint-parser": "9.4.3" }, "files": [ @@ -35,6 +35,6 @@ ], "dependencies": { "misskey-js": "workspace:*", - "vue": "3.5.12" + "vue": "3.5.13" } } diff --git a/packages/frontend/eslint.config.js b/packages/frontend/eslint.config.js index 7805256fd4..8aa70c66a2 100644 --- a/packages/frontend/eslint.config.js +++ b/packages/frontend/eslint.config.js @@ -47,6 +47,8 @@ export default [ '@typescript-eslint/no-empty-interface': ['error', { allowSingleExtends: true, }], + // defineExposeが誤検知されてしまう + '@typescript-eslint/no-unused-expressions': 'off', 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], // window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため // e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 804160baad..2e5923819c 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -21,27 +21,27 @@ "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@misskey-dev/browser-image-resizer": "2024.1.0", "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-replace": "5.0.7", - "@rollup/pluginutils": "5.1.3", + "@rollup/plugin-replace": "6.0.2", + "@rollup/pluginutils": "5.1.4", "@syuilo/aiscript": "0.19.0", - "@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.29.0-mi.1913+5921534bc.tar.gz", + "@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.30.0-mi.1932+ab127beee.tar.gz", "@twemoji/parser": "15.1.1", - "@vitejs/plugin-vue": "5.2.0", - "@vue/compiler-sfc": "3.5.12", + "@vitejs/plugin-vue": "5.2.1", + "@vue/compiler-sfc": "3.5.13", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15", "astring": "1.9.0", "broadcast-channel": "7.0.0", "buraha": "0.0.1", "canvas-confetti": "1.9.3", - "chart.js": "4.4.6", + "chart.js": "4.4.7", "chartjs-adapter-date-fns": "3.0.0", "chartjs-chart-matrix": "2.0.1", "chartjs-plugin-gradient": "0.6.1", - "chartjs-plugin-zoom": "2.0.1", - "chromatic": "11.18.1", + "chartjs-plugin-zoom": "2.2.0", + "chromatic": "11.25.2", "compare-versions": "6.1.1", "cropperjs": "2.0.0-rc.2", - "date-fns": "2.30.0", + "date-fns": "4.1.0", "estree-walker": "3.0.3", "eventemitter3": "5.0.1", "frontend-shared": "workspace:*", @@ -49,92 +49,91 @@ "insert-text-at-cursor": "0.3.0", "is-file-animated": "1.0.2", "json5": "2.2.3", - "matter-js": "0.19.0", + "matter-js": "0.20.0", "mfm-js": "0.24.0", "misskey-bubble-game": "workspace:*", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", "photoswipe": "5.4.4", "punycode.js": "2.3.1", - "rollup": "4.26.0", - "sanitize-html": "2.13.1", - "sass": "1.79.3", - "shiki": "1.22.2", + "rollup": "4.34.7", + "sanitize-html": "2.14.0", + "sass": "1.85.0", + "shiki": "2.4.1", "strict-event-emitter-types": "2.0.0", "textarea-caret": "3.1.0", - "three": "0.169.0", + "three": "0.173.0", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", "tsc-alias": "1.8.10", "tsconfig-paths": "4.2.0", - "typescript": "5.6.3", - "uuid": "10.0.0", + "typescript": "5.7.3", + "uuid": "11.0.5", "v-code-diff": "1.13.1", - "vite": "5.4.11", - "vue": "3.5.12", + "vite": "6.1.0", + "vue": "3.5.13", "vuedraggable": "next" }, "devDependencies": { - "@misskey-dev/summaly": "5.1.0", - "@storybook/addon-actions": "8.4.4", - "@storybook/addon-essentials": "8.4.4", - "@storybook/addon-interactions": "8.4.4", - "@storybook/addon-links": "8.4.4", - "@storybook/addon-mdx-gfm": "8.4.4", - "@storybook/addon-storysource": "8.4.4", - "@storybook/blocks": "8.4.4", - "@storybook/components": "8.4.4", - "@storybook/core-events": "8.4.4", - "@storybook/manager-api": "8.4.4", - "@storybook/preview-api": "8.4.4", - "@storybook/react": "8.4.4", - "@storybook/react-vite": "8.4.4", - "@storybook/test": "8.4.4", - "@storybook/theming": "8.4.4", - "@storybook/types": "8.4.4", - "@storybook/vue3": "8.4.4", - "@storybook/vue3-vite": "8.4.4", + "@misskey-dev/summaly": "5.2.0", + "@storybook/addon-actions": "8.5.6", + "@storybook/addon-essentials": "8.5.6", + "@storybook/addon-interactions": "8.5.6", + "@storybook/addon-links": "8.5.6", + "@storybook/addon-mdx-gfm": "8.5.6", + "@storybook/addon-storysource": "8.5.6", + "@storybook/blocks": "8.5.6", + "@storybook/components": "8.5.6", + "@storybook/core-events": "8.5.6", + "@storybook/manager-api": "8.5.6", + "@storybook/preview-api": "8.5.6", + "@storybook/react": "8.5.6", + "@storybook/react-vite": "8.5.6", + "@storybook/test": "8.5.6", + "@storybook/theming": "8.5.6", + "@storybook/types": "8.5.6", + "@storybook/vue3": "8.5.6", + "@storybook/vue3-vite": "8.5.6", "@testing-library/vue": "8.1.0", - "@types/canvas-confetti": "^1.6.4", + "@types/canvas-confetti": "1.9.0", "@types/estree": "1.0.6", - "@types/matter-js": "0.19.7", + "@types/matter-js": "0.19.8", "@types/micromatch": "4.0.9", - "@types/node": "22.9.0", + "@types/node": "22.13.4", "@types/punycode.js": "npm:@types/punycode@2.1.4", "@types/sanitize-html": "2.13.0", "@types/seedrandom": "3.0.8", "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", - "@types/uuid": "10.0.0", - "@types/ws": "8.5.13", - "@typescript-eslint/eslint-plugin": "7.17.0", - "@typescript-eslint/parser": "7.17.0", - "@vitest/coverage-v8": "1.6.0", - "@vue/runtime-core": "3.5.12", + "@types/ws": "8.5.14", + "@typescript-eslint/eslint-plugin": "8.24.0", + "@typescript-eslint/parser": "8.24.0", + "@vitest/coverage-v8": "3.0.5", + "@vue/runtime-core": "3.5.13", "acorn": "8.14.0", "cross-env": "7.0.3", - "cypress": "13.15.2", + "cypress": "14.0.3", "eslint-plugin-import": "2.31.0", - "eslint-plugin-vue": "9.31.0", - "fast-glob": "3.3.2", - "happy-dom": "10.0.3", + "eslint-plugin-vue": "9.32.0", + "fast-glob": "3.3.3", + "happy-dom": "17.1.0", "intersection-observer": "0.12.2", "micromatch": "4.0.8", - "msw": "2.6.4", + "msw": "2.7.0", "msw-storybook-addon": "2.0.4", - "nodemon": "3.1.7", - "prettier": "3.3.3", - "react": "18.3.1", - "react-dom": "18.3.1", + "nodemon": "3.1.9", + "prettier": "3.5.1", + "react": "19.0.0", + "react-dom": "19.0.0", "seedrandom": "3.0.5", - "start-server-and-test": "2.0.8", - "storybook": "8.4.4", + "start-server-and-test": "2.0.10", + "storybook": "8.5.6", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "vite-plugin-turbosnap": "1.0.3", - "vitest": "1.6.0", - "vitest-fetch-mock": "0.2.2", - "vue-component-type-helpers": "2.1.10", + "vitest": "3.0.5", + "vitest-fetch-mock": "0.4.3", + "vue-component-type-helpers": "2.2.2", "vue-eslint-parser": "9.4.3", - "vue-tsc": "2.1.10" + "vue-tsc": "2.2.2" } } diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue index b1167bbac6..134f8226d4 100644 --- a/packages/frontend/src/components/MkCaptcha.vue +++ b/packages/frontend/src/components/MkCaptcha.vue @@ -50,6 +50,8 @@ type CaptchaContainer = { }; declare global { + // Window を拡張してるため、空ではない + // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface Window extends CaptchaContainer { } } diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue index b095a1cd4a..6c9fa3167a 100644 --- a/packages/frontend/src/components/MkDialog.vue +++ b/packages/frontend/src/components/MkDialog.vue @@ -142,6 +142,7 @@ const okButtonDisabledReason = computed 0) { + menu.push({ type: 'divider' }, ...details); + } + if (defaultStore.state.devMode) { menu.push({ type: 'divider' }, { icon: 'ti ti-id', diff --git a/packages/frontend/src/components/MkMediaImage.vue b/packages/frontend/src/components/MkMediaImage.vue index bd6decd082..3645a4a66e 100644 --- a/packages/frontend/src/components/MkMediaImage.vue +++ b/packages/frontend/src/components/MkMediaImage.vue @@ -133,10 +133,9 @@ function showMenu(ev: MouseEvent) { }); } + const details: MenuItem[] = []; if ($i?.id === props.image.userId) { - menuItems.push({ - type: 'divider', - }, { + details.push({ type: 'link', text: i18n.ts._fileViewer.title, icon: 'ti ti-info-circle', @@ -144,6 +143,19 @@ function showMenu(ev: MouseEvent) { }); } + if (iAmModerator) { + details.push({ + type: 'link', + text: i18n.ts.moderation, + icon: 'ti ti-photo-exclamation', + to: `/admin/file/${props.image.id}`, + }); + } + + if (details.length > 0) { + menuItems.push({ type: 'divider' }, ...details); + } + if (defaultStore.state.devMode) { menuItems.push({ type: 'divider' }, { icon: 'ti ti-id', diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue index dec190f16c..26372e1a52 100644 --- a/packages/frontend/src/components/MkMediaVideo.vue +++ b/packages/frontend/src/components/MkMediaVideo.vue @@ -242,10 +242,9 @@ function showMenu(ev: MouseEvent) { }); } + const details: MenuItem[] = []; if ($i?.id === props.video.userId) { - menu.push({ - type: 'divider', - }, { + details.push({ type: 'link', text: i18n.ts._fileViewer.title, icon: 'ti ti-info-circle', @@ -253,6 +252,19 @@ function showMenu(ev: MouseEvent) { }); } + if (iAmModerator) { + details.push({ + type: 'link', + text: i18n.ts.moderation, + icon: 'ti ti-photo-exclamation', + to: `/admin/file/${props.video.id}`, + }); + } + + if (details.length > 0) { + menu.push({ type: 'divider' }, ...details); + } + if (defaultStore.state.devMode) { menu.push({ type: 'divider' }, { icon: 'ti ti-id', diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 919734f763..193dfe5b7e 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -489,7 +489,16 @@ function react(): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, note.value, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, async (reaction) => { + if (defaultStore.state.confirmOnReact) { + const confirm = await os.confirm({ + type: 'question', + text: i18n.tsx.reactAreYouSure({ emoji: reaction.replace('@.', '') }), + }); + + if (confirm.canceled) return; + } + sound.playMisskeySfx('reaction'); if (props.mock) { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index fa1358da3d..835a663868 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -452,7 +452,16 @@ function react(): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, note.value, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, async (reaction) => { + if (defaultStore.state.confirmOnReact) { + const confirm = await os.confirm({ + type: 'question', + text: i18n.tsx.reactAreYouSure({ emoji: reaction.replace('@.', '') }), + }); + + if (confirm.canceled) return; + } + sound.playMisskeySfx('reaction'); misskeyApi('notes/reactions/create', { diff --git a/packages/frontend/src/components/MkNotificationSelectWindow.vue b/packages/frontend/src/components/MkNotificationSelectWindow.vue index 90a3e48187..a0fb7fea83 100644 --- a/packages/frontend/src/components/MkNotificationSelectWindow.vue +++ b/packages/frontend/src/components/MkNotificationSelectWindow.vue @@ -39,7 +39,7 @@ import MkModalWindow from '@/components/MkModalWindow.vue'; import { notificationTypes } from '@@/js/const.js'; import { i18n } from '@/i18n.js'; -type TypesMap = Record> +type TypesMap = Record>; const emit = defineEmits<{ (ev: 'done', v: { excludeTypes: string[] }): void, diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index 49ed4197de..ad0a332f99 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -65,7 +65,10 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.notSpecifiedMentionWarning }} - - +
+ +
{{ maxCwTextLength - cwTextLength }}
+