diff --git a/.github/workflows/check-misskey-js-autogen.yml b/.github/workflows/check-misskey-js-autogen.yml index 8fad129115..4aa0646b7b 100644 --- a/.github/workflows/check-misskey-js-autogen.yml +++ b/.github/workflows/check-misskey-js-autogen.yml @@ -5,24 +5,23 @@ on: branches: - master - develop + - improve-misskey-js-autogen-check paths: - packages/backend/** jobs: - check-misskey-js-autogen: + # pull_request_target safety: permissions: read-all, and there are no secrets used in this job + generate-misskey-js: runs-on: ubuntu-latest permissions: - pull-requests: write - - env: - api_json_name: "api-head.json" - + contents: read + if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} steps: - name: checkout uses: actions/checkout@v4.1.1 with: submodules: true - ref: ${{ github.event.pull_request.head.sha }} + ref: refs/pull/${{ github.event.pull_request.number }}/merge - name: setup pnpm uses: pnpm/action-setup@v3 @@ -39,79 +38,81 @@ jobs: - name: install dependencies run: pnpm i --frozen-lockfile - - name: wait get-api-diff - uses: lewagon/wait-on-check-action@v1.3.3 + # generate api.json + - name: Copy Config + run: cp .config/example.yml .config/default.yml + - name: Build + run: pnpm build + - name: Generate API JSON + run: pnpm --filter backend generate-api-json + + # build misskey js + - name: Build misskey-js + run: |- + cp packages/backend/built/api.json packages/misskey-js/generator/api.json + pnpm run --filter misskey-js-type-generator generate + + # packages/misskey-js/generator/built/autogen + - name: Upload Generated + uses: actions/upload-artifact@v4 with: - ref: ${{ github.event.pull_request.head.sha }} - check-regexp: get-from-misskey .+ - repo-token: ${{ secrets.GITHUB_TOKEN }} - wait-interval: 30 + name: generated-misskey-js + path: packages/misskey-js/generator/built/autogen - - name: Download artifact - uses: actions/github-script@v7.0.1 + # pull_request_target safety: permissions: read-all, and there are no secrets used in this job + get-actual-misskey-js: + runs-on: ubuntu-latest + permissions: + contents: read + if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} + steps: + - name: checkout + uses: actions/checkout@v4.1.1 with: - script: | - const fs = require('fs'); + submodules: true + ref: refs/pull/${{ github.event.pull_request.number }}/merge - const workflows = await github.rest.actions.listWorkflowRunsForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - head_sha: `${{ github.event.pull_request.head.sha }}` - }).then(x => x.data.workflow_runs); + - name: Upload From Merged + uses: actions/upload-artifact@v4 + with: + name: actual-misskey-js + path: packages/misskey-js/src/autogen - console.log(workflows.map(x => ({name: x.name, title: x.display_title}))); + # pull_request_target safety: nothing is cloned from repository + comment-misskey-js-autogen: + runs-on: ubuntu-latest + needs: [generate-misskey-js, get-actual-misskey-js] + permissions: + pull-requests: write + steps: + - name: download generated-misskey-js + uses: actions/download-artifact@v4 + with: + name: generated-misskey-js + path: misskey-js-generated - const run_id = workflows.find(x => x.name.includes("Get api.json from Misskey")).id; + - name: download actual-misskey-js + uses: actions/download-artifact@v4 + with: + name: actual-misskey-js + path: misskey-js-actual - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: run_id, - }); + - name: check misskey-js changes + id: check-changes + run: | + diff -r -u --label=generated --label=on-tree ./misskey-js-generated ./misskey-js-actual > misskey-js.diff || true - let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name.startsWith("api-artifact-") || artifact.name == "api-artifact" - }); + if [ -s misskey-js.diff ]; then + echo "changes=true" >> $GITHUB_OUTPUT + else + echo "changes=false" >> $GITHUB_OUTPUT + fi - await Promise.all(matchArtifacts.map(async (artifact) => { - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - archive_format: 'zip', - }); - await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data)); - })); - - - name: unzip artifacts - run: |- - find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d . ';' - ls -la - - - name: get head checksum - run: |- - checksum=$(realpath head_checksum) - - cd packages/misskey-js/src - find autogen -type f -exec sh -c 'echo $(sed -E "s/^\s+\*\s+generatedAt:.+$//" {} | sha256sum | cut -d" " -f 1) {}' \; > $checksum - cd ../../.. - - - name: build autogen - run: |- - checksum=$(realpath ${api_json_name}_checksum) - mv $api_json_name packages/misskey-js/generator/api.json - - cd packages/misskey-js/generator - pnpm run generate - cd built - find autogen -type f -exec sh -c 'echo $(sed -E "s/^\s+\*\s+generatedAt:.+$//" {} | sha256sum | cut -d" " -f 1) {}' \; > $checksum - cd ../../../.. - - - name: check update for type definitions - run: diff head_checksum ${api_json_name}_checksum + - name: Print full diff + run: cat ./misskey-js.diff - name: send message - if: failure() + if: steps.check-changes.outputs.changes == 'true' uses: thollander/actions-comment-pull-request@v2 with: comment_tag: check-misskey-js-autogen @@ -125,7 +126,7 @@ jobs: ``` - name: send message - if: success() + if: steps.check-changes.outputs.changes == 'false' uses: thollander/actions-comment-pull-request@v2 with: comment_tag: check-misskey-js-autogen diff --git a/.github/workflows/deploy-test-environment.yml b/.github/workflows/deploy-test-environment.yml index 77cdcfaf88..66b15beb91 100644 --- a/.github/workflows/deploy-test-environment.yml +++ b/.github/workflows/deploy-test-environment.yml @@ -50,12 +50,9 @@ jobs: - name: Get PR ref id: get-ref - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - PR_NUMBER=$(jq --raw-output .issue.number $GITHUB_EVENT_PATH) - PR_REF=$(gh pr view $PR_NUMBER --json headRefName -q '.headRefName') - echo "pr-ref=$PR_REF" > $GITHUB_OUTPUT + PR_REF="refs/pull/${{ github.event.issue.number }}/head" + echo "pr-ref=$PR_REF" >> $GITHUB_OUTPUT - name: Extract wait time id: get-wait-time diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 31e974edaa..9b3f85fe1d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -92,6 +92,6 @@ jobs: - run: pnpm i --frozen-lockfile - run: pnpm --filter misskey-js run build if: ${{ matrix.workspace == 'backend' }} - - run: pnpm --filter misskey-reversi run build:tsc + - run: pnpm --filter misskey-reversi run build if: ${{ matrix.workspace == 'backend' }} - run: pnpm --filter ${{ matrix.workspace }} run typecheck diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 87481b12cf..ca82f4bcf3 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -87,12 +87,13 @@ jobs: if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then echo "skip=true" >> $GITHUB_OUTPUT fi - BRANCH="${{ github.event.pull_request.head.user.login }}:${{ github.event.pull_request.head.ref }}" - if [ "$BRANCH" = "misskey-dev:${{ github.event.pull_request.head.ref }}" ]; then - BRANCH="${{ github.event.pull_request.head.ref }}" + BRANCH="${{ github.event.pull_request.head.user.login }}:$HEAD_REF" + if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then + BRANCH="$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 49a6a39805..a803db4508 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -45,6 +45,8 @@ jobs: with: version: 8 run_install: false + - name: Install FFmpeg + uses: FedericoCarboni/setup-ffmpeg@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 188e146cdd..1f3ae412ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,21 +2,43 @@ ### Note - コントロールパネル内にあるサマリープロキシの設定個所がセキュリティから全般へ変更となります。 +- 悪意のある第三者がリモートユーザーになりすましたアクティビティを受け取れてしまう問題を修正しました。詳しくは[GitHub security advisory](https://github.com/misskey-dev/misskey/security/advisories/GHSA-2vxv-pv3m-3wvj)をご覧ください。 ### General - Enhance: URLプレビューの有効化・無効化を設定できるように #13569 - Enhance: アンテナでBotによるノートを除外できるように (Cherry-picked from https://github.com/MisskeyIO/misskey/pull/545) +- Enhance: クリップのノート数を表示するように +- Enhance: コンディショナルロールの条件として以下を新たに追加 (#13667) + - 猫ユーザーか + - botユーザーか + - サスペンド済みユーザーか + - 鍵アカウントユーザーか + - 「アカウントを見つけやすくする」が有効なユーザーか - Fix: Play作成時に設定した公開範囲が機能していない問題を修正 +- Fix: 正規化されていない状態のhashtagが連合されてきたhtmlに含まれているとhashtagが正しくhashtagに復元されない問題を修正 ### Client +- Feat: アップロードするファイルの名前をランダム文字列にできるように - Enhance: 自分のノートの添付ファイルから直接ファイルの詳細ページに飛べるように - Enhance: 広告がMisskeyと同一ドメインの場合はRouterで遷移するように - Enhance: リアクション・いいねの総数を表示するように - Enhance: リアクション受け入れが「いいねのみ」の場合はリアクション絵文字一覧を表示しないように - Enhance: 設定>プラグインのページからプラグインの簡易的なログやエラーを見られるように - 実装の都合により、プラグインは1つエラーを起こした時に即時停止するようになりました -- Enhance: ページのデザインを変更 +- Enhance: ページのデザインを変更 +- Enhance: 2要素認証(ワンタイムパスワード)の入力欄を改善 +- Enhance: 「今日誕生日のフォロー中ユーザー」ウィジェットを手動でリロードできるように +- Enhance: 映像・音声の再生にブラウザのネイティブプレイヤーを使用できるように +- Enhance: 映像・音声の再生メニューに「再生速度」「ループ再生」「ピクチャインピクチャ」を追加 +- Enhance: 映像・音声の再生にキーボードショートカットが使えるように +- Enhance: ノートについているリアクションの「もっと!」から、リアクションの一覧を表示できるように +- Enhance: リプライにて引用がある場合テキストが空でもノートできるように + - 引用したいノートのURLをコピーしリプライ投稿画面にペーストして添付することで達成できます +- Enhance: フォローするかどうかの確認ダイアログを出せるように +- Enhance: Playを手動でリロードできるように +- Enhance: 通報のコメント内のリンクをクリックした際、ウィンドウで開くように +- Chore: AiScriptを0.18.0にバージョンアップ - Fix: 一部のページ内リンクが正しく動作しない問題を修正 - Fix: 周年の実績が閏年を考慮しない問題を修正 - Fix: ローカルURLのプレビューポップアップが左上に表示される @@ -26,12 +48,37 @@ (Cherry-picked from https://github.com/MisskeyIO/misskey/pull/528) - Fix: コードブロックのシンタックスハイライトで使用される定義ファイルをCDNから取得するように #13177 - CDNから取得せずMisskey本体にバンドルする場合は`pacakges/frontend/vite.config.ts`を修正してください。 +- Fix: タイムゾーンによっては、「今日誕生日のフォロー中ユーザー」ウィジェットが正しく動作しない問題を修正 +- Fix: CWのみの引用リノートが詳細ページで純粋なリノートとして誤って扱われてしまう問題を修正 +- Fix: ノート詳細ページにおいてCW付き引用リノートのCWボタンのラベルに「引用」が含まれていない問題を修正 +- Fix: ダイアログの入力で字数制限に違反していてもEnterキーが押せてしまう問題を修正 +- Fix: ダイレクト投稿の宛先が保存されない問題を修正 +- Fix: Playのページを離れたときに、Playが正常に初期化されない問題を修正 +- Fix: ページのOGP URLが間違っているのを修正 +- Fix: リバーシの対局を正しく共有できないことがある問題を修正 +- Fix: 通知をグループ化している際に、人数が正常に表示されないことがある問題を修正 +- Fix: 連合なしの状態の読み書きができない問題を修正 ### Server - Enhance: エンドポイント`antennas/update`の必須項目を`antennaId`のみに - Enhance: misskey-dev/summaly@5.1.0の取り込み(プレビュー生成処理の効率化) +- Fix: リモートから配送されたアクティビティにJSON-LD compactionをかける - Fix: フォローリクエストを作成する際に既存のものは削除するように (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/440) +- Fix: エンドポイント`notes/translate`のエラーを改善 +- Fix: CleanRemoteFilesProcessorService report progress from 100% (#13632) +- Fix: 一部の音声ファイルが映像ファイルとして扱われる問題を修正 +- Fix: リプライのみの引用リノートと、CWのみの引用リノートが純粋なリノートとして誤って扱われてしまう問題を修正 +- Fix: 登録にメール認証が必須になっている場合、登録されているメールアドレスを削除できないように + (Cherry-picked from https://github.com/MisskeyIO/misskey/pull/606) +- Fix: Add Cache-Control to Bull Board +- Fix: nginx経由で/files/にRangeリクエストされた場合に正しく応答できないのを修正 +- Fix: 一部のタイムラインのストリーミングでインスタンスミュートが効かない問題を修正 +- Fix: グローバルタイムラインで返信が表示されないことがある問題を修正 +- Fix: リノートをミュートしたユーザの投稿のリノートがミュートされる問題を修正 +- Fix: AP Link等は添付ファイル扱いしないようになど (#13754) +- Enhance: ドライブのファイルがNSFWかどうか個別に連合されるように (#13756) + - 可能な場合、ノートの添付ファイルのセンシティブ判定がファイル単位になります ## 2024.3.1 diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index c2d92e1663..281f2e6ccd 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -30,9 +30,13 @@ Cypress.Commands.add('visitHome', () => { }) Cypress.Commands.add('resetState', () => { + // iframe.contentWindow.indexedDB.deleteDatabase() がchromeのバグで使用できないため、indexedDBを無効化している。 + // see https://github.com/misskey-dev/misskey/issues/13605#issuecomment-2053652123 + /* cy.window().then(win => { win.indexedDB.deleteDatabase('keyval-store'); }); + */ cy.request('POST', '/api/reset-db', {}).as('reset'); cy.get('@reset').its('status').should('equal', 204); cy.reload(true); diff --git a/locales/index.d.ts b/locales/index.d.ts index 70586d7a87..779a5d2c3f 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4920,6 +4920,42 @@ export interface Locale extends ILocale { * 使用しない場合は空欄にしてください */ "notUsePleaseLeaveBlank": string; + /** + * ワンタイムパスワードを使う + */ + "useTotp": string; + /** + * バックアップコードを使う + */ + "useBackupCode": string; + /** + * アプリを起動 + */ + "launchApp": string; + /** + * 動画・音声の再生にブラウザのUIを使用する + */ + "useNativeUIForVideoAudioPlayer": string; + /** + * オリジナルのファイル名を保持 + */ + "keepOriginalFilename": string; + /** + * この設定をオフにすると、アップロード時にファイル名が自動でランダム文字列に置き換えられます。 + */ + "keepOriginalFilenameDescription": string; + /** + * 説明文はありません + */ + "noDescription": string; + /** + * フォローの際常に確認する + */ + "alwaysConfirmFollow": string; + /** + * お問い合わせ + */ + "inquiry": string; "_bubbleGame": { /** * 遊び方 @@ -6560,6 +6596,26 @@ export interface Locale extends ILocale { * リモートユーザー */ "isRemote": string; + /** + * 猫ユーザー + */ + "isCat": string; + /** + * botユーザー + */ + "isBot": string; + /** + * サスペンド済みユーザー + */ + "isSuspended": string; + /** + * 鍵アカウントユーザー + */ + "isLocked": string; + /** + * 「アカウントを見つけやすくする」が有効なユーザー + */ + "isExplorable": string; /** * アカウント作成から~以内 */ @@ -7534,13 +7590,9 @@ export interface Locale extends ILocale { */ "step1": ParameterizedString<"a" | "b">; /** - * 次に、表示されているQRコードをアプリでスキャンします。 + * 次に、表示されているQRコードをアプリでスキャンするか、ボタンをクリックして端末上でアプリを開きます。 */ "step2": string; - /** - * QRコードをクリックすると、お使いの端末にインストールされている認証アプリやキーリングに登録できます。 - */ - "step2Click": string; /** * デスクトップアプリを使用する場合は次のURIを入力します */ @@ -7633,6 +7685,10 @@ export interface Locale extends ILocale { * バックアップコードが全て使用されました。認証アプリを利用できない場合、これ以上アカウントにアクセスできなくなります。認証アプリを再登録してください。 */ "backupCodesExhaustedWarning": string; + /** + * 詳細なガイドはこちら + */ + "moreDetailedGuideHere": string; }; "_permissions": { /** @@ -8818,6 +8874,14 @@ export interface Locale extends ILocale { * ボタン */ "button": string; + /** + * 動的ブロック + */ + "dynamic": string; + /** + * このブロックは廃止されています。今後は{play}を利用してください。 + */ + "dynamicDescription": ParameterizedString<"play">; /** * ノート埋め込み */ @@ -9826,6 +9890,20 @@ export interface Locale extends ILocale { */ "summaryProxyDescription2": string; }; + "_mediaControls": { + /** + * ピクチャインピクチャ + */ + "pip": string; + /** + * 再生速度 + */ + "playbackRate": string; + /** + * ループ再生 + */ + "loop": string; + }; } declare const locales: { [lang: string]: Locale; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index cada6d855f..8f17215802 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1226,6 +1226,15 @@ loading: "読み込み中" surrender: "やめる" gameRetry: "リトライ" notUsePleaseLeaveBlank: "使用しない場合は空欄にしてください" +useTotp: "ワンタイムパスワードを使う" +useBackupCode: "バックアップコードを使う" +launchApp: "アプリを起動" +useNativeUIForVideoAudioPlayer: "動画・音声の再生にブラウザのUIを使用する" +keepOriginalFilename: "オリジナルのファイル名を保持" +keepOriginalFilenameDescription: "この設定をオフにすると、アップロード時にファイル名が自動でランダム文字列に置き換えられます。" +noDescription: "説明文はありません" +alwaysConfirmFollow: "フォローの際常に確認する" +inquiry: "お問い合わせ" _bubbleGame: howToPlay: "遊び方" @@ -1695,6 +1704,11 @@ _role: roleAssignedTo: "マニュアルロールにアサイン済み" isLocal: "ローカルユーザー" isRemote: "リモートユーザー" + isCat: "猫ユーザー" + isBot: "botユーザー" + isSuspended: "サスペンド済みユーザー" + isLocked: "鍵アカウントユーザー" + isExplorable: "「アカウントを見つけやすくする」が有効なユーザー" createdLessThan: "アカウント作成から~以内" createdMoreThan: "アカウント作成から~経過" followersLessThanOrEq: "フォロワー数が~以下" @@ -1981,8 +1995,7 @@ _2fa: alreadyRegistered: "既に設定は完了しています。" registerTOTP: "認証アプリの設定を開始" step1: "まず、{a}や{b}などの認証アプリをお使いのデバイスにインストールします。" - step2: "次に、表示されているQRコードをアプリでスキャンします。" - step2Click: "QRコードをクリックすると、お使いの端末にインストールされている認証アプリやキーリングに登録できます。" + step2: "次に、表示されているQRコードをアプリでスキャンするか、ボタンをクリックして端末上でアプリを開きます。" step2Uri: "デスクトップアプリを使用する場合は次のURIを入力します" step3Title: "確認コードを入力" step3: "アプリに表示されている確認コード(トークン)を入力します。" @@ -2006,6 +2019,7 @@ _2fa: backupCodesDescription: "認証アプリが使用できなくなった場合、以下のバックアップコードを使ってアカウントにアクセスできます。これらのコードは必ず安全な場所に保管してください。各コードは一回だけ使用できます。" backupCodeUsedWarning: "バックアップコードが使用されました。認証アプリが使えなくなっている場合、なるべく早く認証アプリを再設定してください。" backupCodesExhaustedWarning: "バックアップコードが全て使用されました。認証アプリを利用できない場合、これ以上アカウントにアクセスできなくなります。認証アプリを再登録してください。" + moreDetailedGuideHere: "詳細なガイドはこちら" _permissions: "read:account": "アカウントの情報を見る" @@ -2328,6 +2342,8 @@ _pages: section: "セクション" image: "画像" button: "ボタン" + dynamic: "動的ブロック" + dynamicDescription: "このブロックは廃止されています。今後は{play}を利用してください。" note: "ノート埋め込み" _note: @@ -2617,3 +2633,8 @@ _urlPreviewSetting: summaryProxy: "プレビューを生成するプロキシのエンドポイント" summaryProxyDescription: "Misskey本体ではなく、サマリープロキシを使用してプレビューを生成します。" summaryProxyDescription2: "プロキシには下記パラメータがクエリ文字列として連携されます。プロキシ側がこれらをサポートしない場合、設定値は無視されます。" + +_mediaControls: + pip: "ピクチャインピクチャ" + playbackRate: "再生速度" + loop: "ループ再生" diff --git a/package.json b/package.json index 8f5ab0b124..84d6db5124 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,9 @@ "postcss": "8.4.35", "tar": "6.2.0", "terser": "5.28.1", - "typescript": "5.3.3" + "typescript": "5.3.3", + "esbuild": "0.19.11", + "glob": "10.3.10" }, "devDependencies": { "@types/node": "^20.11.28", diff --git a/packages/backend/.swcrc b/packages/backend/.swcrc index 0504a2d389..845190b5f4 100644 --- a/packages/backend/.swcrc +++ b/packages/backend/.swcrc @@ -19,5 +19,6 @@ }, "target": "es2022" }, - "minify": false + "minify": false, + "sourceMaps": "inline" } diff --git a/packages/backend/assets/redoc.html b/packages/backend/assets/redoc.html index a9ebf662fc..2557b4532e 100644 --- a/packages/backend/assets/redoc.html +++ b/packages/backend/assets/redoc.html @@ -19,6 +19,6 @@