diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index d9f38b823..d9d5660b6 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -23,13 +23,7 @@ services: environment: DFLY_snapshot_cron: '* * * * *' DFLY_version_check: false - DFLY_tcp_backlog: 2048 DFLY_default_lua_flags: allow-undeclared-keys - DFLY_pipeline_squash: 0 - DFLY_multi_exec_squash: false - DFLY_conn_io_threads: 4 - DFLY_epoll_file_threads: 4 - DFLY_proactor_threads: 4 networks: - internal_network volumes: @@ -37,7 +31,7 @@ services: db: restart: unless-stopped - image: postgres:15-alpine + image: postgres:17-alpine networks: - internal_network environment: diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 62b586217..000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @SWREI diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index d42b58abc..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -github: [misskey-dev] -patreon: syuilo diff --git a/.github/ISSUE_TEMPLATE/01_bug-report.yml b/.github/ISSUE_TEMPLATE/01_bug-report.yml deleted file mode 100644 index 89b8e7959..000000000 --- a/.github/ISSUE_TEMPLATE/01_bug-report.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: 🐛 Bug Report -description: Create a report to help us improve -labels: ["⚠️bug?"] - -body: - - type: markdown - attributes: - value: | - Thanks for reporting! - First, in order to avoid duplicate Issues, please search to see if the problem you found has already been reported. - Also, If you are NOT owner/admin of server, PLEASE DONT REPORT SERVER SPECIFIC ISSUES TO HERE! (e.g. feature XXX is not working in misskey.example) Please try with another misskey servers, and if your issue is only reproducible with specific server, contact your server's owner/admin first. - - - type: textarea - attributes: - label: 💡 Summary - description: Tell us what the bug is - validations: - required: true - - - type: textarea - attributes: - label: 🥰 Expected Behavior - description: Tell us what should happen - validations: - required: true - - - type: textarea - attributes: - label: 🤬 Actual Behavior - description: | - Tell us what happens instead of the expected behavior. - Please include errors from the developer console and/or server log files if you have access to them. - validations: - required: true - - - type: textarea - attributes: - label: 📝 Steps to Reproduce - placeholder: | - 1. - 2. - 3. - validations: - required: false - - - type: textarea - attributes: - label: 💻 Frontend Environment - description: | - Tell us where on the platform it happens - DO NOT WRITE "latest". Please provide the specific version. - - Examples: - * Model and OS of the device(s): MacBook Pro (14inch, 2021), macOS Ventura 13.4 - * Browser: Chrome 113.0.5672.126 - * Server URL: misskey.io - * Misskey: 13.x.x - value: | - * Model and OS of the device(s): - * Browser: - * Server URL: - * Misskey: - render: markdown - validations: - required: false - - - type: textarea - attributes: - label: 🛰 Backend Environment (for server admin) - description: | - Tell us where on the platform it happens - DO NOT WRITE "latest". Please provide the specific version. - If you are using a managed service, put that after the version. - - Examples: - * Installation Method or Hosting Service: docker compose, k8s/docker, systemd, "Misskey install shell script", development environment - * Misskey: 13.x.x - * Node: 22.x.x - * PostgreSQL: 15.x.x - * Redis: 7.x.x - * OS and Architecture: Ubuntu 22.04.2 LTS aarch64 - value: | - * Installation Method or Hosting Service: - * Misskey: - * Node: - * PostgreSQL: - * Redis: - * OS and Architecture: - render: markdown - validations: - required: false - - - type: checkboxes - attributes: - label: Do you want to address this bug yourself? - options: - - label: Yes, I will patch the bug myself and send a pull request diff --git a/.github/ISSUE_TEMPLATE/02_feature-request.yml b/.github/ISSUE_TEMPLATE/02_feature-request.yml deleted file mode 100644 index 8d7b0b253..000000000 --- a/.github/ISSUE_TEMPLATE/02_feature-request.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: ✨ Feature Request -description: Suggest an idea for this project -labels: ["✨Feature"] - -body: - - type: textarea - attributes: - label: Summary - description: Tell us what the suggestion is - validations: - required: true - - type: textarea - attributes: - label: Purpose - description: Describe the specific problem or need you think this feature will solve, and who it will help. - validations: - required: true - - type: checkboxes - attributes: - label: Do you want to implement this feature yourself? - options: - - label: Yes, I will implement this by myself and send a pull request diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index e8b65dc3b..000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -contact_links: - - name: 💬 Misskey official Discord - url: https://discord.gg/Wp8gVStHW3 - about: Chat freely about Misskey diff --git a/.github/PULL_REQUEST_TEMPLATE/01_bug.md b/.github/PULL_REQUEST_TEMPLATE/01_bug.md deleted file mode 100644 index 0739fee70..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/01_bug.md +++ /dev/null @@ -1,23 +0,0 @@ - - -## What - - - -## Why - - - -## Additional info (optional) - - - -## Checklist -- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md) -- [ ] Test working in a local environment -- [ ] (If needed) Update CHANGELOG.md -- [ ] (If possible) Add tests diff --git a/.github/PULL_REQUEST_TEMPLATE/02_enhance.md b/.github/PULL_REQUEST_TEMPLATE/02_enhance.md deleted file mode 100644 index 0739fee70..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/02_enhance.md +++ /dev/null @@ -1,23 +0,0 @@ - - -## What - - - -## Why - - - -## Additional info (optional) - - - -## Checklist -- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md) -- [ ] Test working in a local environment -- [ ] (If needed) Update CHANGELOG.md -- [ ] (If possible) Add tests diff --git a/.github/PULL_REQUEST_TEMPLATE/03_release.md b/.github/PULL_REQUEST_TEMPLATE/03_release.md deleted file mode 100644 index b5b832e1d..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/03_release.md +++ /dev/null @@ -1,20 +0,0 @@ -## Summary -This is a release PR. - -For more information on the release instructions, please see: -https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md#release - -## For reviewers -- CHANGELOGに抜け漏れは無いか -- バージョンの上げ方は適切か -- 他にこのリリースに含めなければならない変更は無いか -- 全体的な変更内容を俯瞰し問題は無いか -- レビューされていないコミットがある場合は、それが問題ないか -- 最終的な動作確認を行い問題は無いか - -などを確認し、リリースする準備が整っていると思われる場合は approve してください。 - -## Checklist -- [ ] package.jsonのバージョンが正しく更新されている -- [ ] CHANGELOGが過不足無く更新されている -- [ ] CIが全て通っている diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 1b033cce3..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,20 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: -- package-ecosystem: github-actions - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 100 - -# Add only the root, not each workspace item -# https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027 -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 0 diff --git a/.github/labeler.yml b/.github/labeler.yml deleted file mode 100644 index a77f73706..000000000 --- a/.github/labeler.yml +++ /dev/null @@ -1,34 +0,0 @@ -'packages/backend': -- any: - - changed-files: - - any-glob-to-any-file: ['packages/backend/**/*'] - -'packages/backend:test': -- any: - - changed-files: - - any-glob-to-any-file: ['packages/backend/test/**/*'] - -'packages/frontend': -- any: - - changed-files: - - any-glob-to-any-file: ['packages/frontend/**/*'] - -'packages/frontend:test': -- any: - - changed-files: - - any-glob-to-any-file: ['cypress/**/*'] - -'packages/sw': -- any: - - changed-files: - - any-glob-to-any-file: ['packages/sw/**/*'] - -'packages/misskey-js': -- any: - - changed-files: - - any-glob-to-any-file: ['packages/misskey-js/**/*'] - -'packages/misskey-js:test': -- any: - - changed-files: - - any-glob-to-any-file: ['packages/misskey-js/test/**/*', 'packages/misskey-js/test-d/**/*'] diff --git a/.github/misskey/test.yml b/.github/misskey/test.yml deleted file mode 100644 index 7a4aa4ae6..000000000 --- a/.github/misskey/test.yml +++ /dev/null @@ -1,15 +0,0 @@ -url: 'http://misskey.local' - -# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ) -port: 61812 - -db: - host: 127.0.0.1 - port: 54312 - db: test-misskey - user: postgres - pass: '' -redis: - host: 127.0.0.1 - port: 56312 -id: aidx diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index e78b82c47..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,24 +0,0 @@ - - -## What - - - -## Why - - - -## Additional info (optional) - - - -## Checklist -- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md) -- [ ] Test working in a local environment -- [ ] (If needed) Add story of storybook -- [ ] (If needed) Update CHANGELOG.md -- [ ] (If possible) Add tests diff --git a/.github/unused/test-backend.yml b/.github/unused/test-backend.yml deleted file mode 100644 index 3d640b210..000000000 --- a/.github/unused/test-backend.yml +++ /dev/null @@ -1,136 +0,0 @@ -name: Test (backend) - -on: - push: - branches: - - oscar - paths: - - packages/backend/** - # for permissions - - packages/misskey-js/** - pull_request: - paths: - - packages/backend/** - # for permissions - - packages/misskey-js/** - -jobs: - unit: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [22.x] - - services: - postgres: - image: postgres:15 - ports: - - 54312:5432 - env: - POSTGRES_DB: test-misskey - POSTGRES_HOST_AUTH_METHOD: trust - dragonfly: - image: docker.dragonflydb.io/dragonflydb/dragonfly - options: --ulimit "memlock=-1" - env: - DFLY_version_check: false - DFLY_tcp_backlog: 2048 - DFLY_default_lua_flags: allow-undeclared-keys - DFLY_pipeline_squash: 0 - DFLY_multi_exec_squash: false - DFLY_conn_io_threads: 4 - DFLY_epoll_file_threads: 4 - DFLY_proactor_threads: 4 - ports: - - 56312:6379 - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Install FFmpeg - uses: FedericoCarboni/setup-ffmpeg@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - name: Check pnpm-lock.yaml - run: git diff --exit-code pnpm-lock.yaml - - name: Copy Configure - run: cp .github/misskey/test.yml .config - - name: Build - run: pnpm build - - name: Test - run: pnpm --filter backend test-and-coverage - - name: Upload to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./packages/backend/coverage/coverage-final.json - - e2e: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [22.x] - - services: - postgres: - image: postgres:15 - ports: - - 54312:5432 - env: - POSTGRES_DB: test-misskey - POSTGRES_HOST_AUTH_METHOD: trust - dragonfly: - image: docker.dragonflydb.io/dragonflydb/dragonfly - options: --ulimit "memlock=-1" - env: - DFLY_version_check: false - DFLY_tcp_backlog: 2048 - DFLY_default_lua_flags: allow-undeclared-keys - DFLY_pipeline_squash: 0 - DFLY_multi_exec_squash: false - DFLY_conn_io_threads: 4 - DFLY_epoll_file_threads: 4 - DFLY_proactor_threads: 4 - ports: - - 56312:6379 - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - name: Check pnpm-lock.yaml - run: git diff --exit-code pnpm-lock.yaml - - name: Copy Configure - run: cp .github/misskey/test.yml .config - - name: Build - run: pnpm build - - name: Test - run: pnpm --filter backend test-and-coverage:e2e - - name: Upload to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./packages/backend/coverage/coverage-final.json diff --git a/.github/workflows/api-misskey-js.yml b/.github/workflows/api-misskey-js.yml deleted file mode 100644 index eda561f91..000000000 --- a/.github/workflows/api-misskey-js.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: API report (misskey.js) - -on: - push: - paths: - - packages/misskey-js/** - pull_request: - paths: - - packages/misskey-js/** - -jobs: - report: - - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - - name: Setup Node.js - uses: actions/setup-node@v4.3.0 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm i --frozen-lockfile - - - name: Build - run: pnpm --filter misskey-js build - - - name: Check files - run: ls packages/misskey-js/built - - - name: API report - run: pnpm --filter misskey-js api-prod - - - name: Show report - if: always() - run: cat packages/misskey-js/temp/misskey-js.api.md diff --git a/.github/workflows/check-misskey-js-version.yml b/.github/workflows/check-misskey-js-version.yml deleted file mode 100644 index 2b715b7ae..000000000 --- a/.github/workflows/check-misskey-js-version.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Check Misskey JS version - -on: - push: - branches: - - oscar - paths: - - packages/misskey-js/package.json - - package.json - pull_request: - paths: - - packages/misskey-js/package.json - - package.json - -jobs: - check-version: - # ルートの package.json と packages/misskey-js/package.json のバージョンが一致しているかを確認する - name: Check version - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Check version - run: | - if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then - echo "Version mismatch!" - exit 1 - fi diff --git a/.github/workflows/docker-beta.yml b/.github/workflows/docker-beta.yml deleted file mode 100644 index e69de29bb..000000000 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index b816f1185..000000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Publish Docker Image - -on: - push: - branches: - - oscar - tags: - - '**-oscar.*' - workflow_dispatch: - -jobs: - push_to_registry: - name: Push Docker image to GitHub Container Registry - runs-on: ubuntu-22.04 - if: github.repository == 'oscar-surf/misskey' - steps: - - name: Check out the repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - with: - platforms: linux/amd64 - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/oscar-surf/misskey - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Prepare image tags - run: | - echo "FORMATTED_BRANCH_NAME=$(echo ${{ github.ref_name }} | sed -e 's/\//-/g' )" >> $GITHUB_ENV - - name: Build and Push to GitHub Container Registry - uses: docker/build-push-action@v6 - with: - builder: ${{ steps.buildx.outputs.name }} - context: . - push: true - platforms: ${{ steps.buildx.outputs.platforms }} - provenance: false - labels: ${{ env.FORMATTED_BRANCH_NAME }} - cache-from: type=registry,ref=ghcr.io/oscar-surf/misskey:oscar-buildcache - cache-to: type=registry,ref=ghcr.io/oscar-surf/misskey:oscar-buildcache,mode=max - tags: | - ghcr.io/oscar-surf/misskey:latest - ghcr.io/oscar-surf/misskey:${{ env.FORMATTED_BRANCH_NAME }} diff --git a/.github/workflows/dockle.yml b/.github/workflows/dockle.yml deleted file mode 100644 index 7d61df8ff..000000000 --- a/.github/workflows/dockle.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Dockle - -on: - push: - branches: - - oscar - pull_request: - -jobs: - dockle: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Build an image from Dockerfile - uses: docker/build-push-action@v6 - with: - context: . - push: false - provenance: false - cache-from: type=registry,ref=ghcr.io/oscar-surf/misskey:oscar-buildcache - tags: | - misskey:scan - - name: Run dockle - uses: docker://goodwithtech/dockle:v0.4.14 - env: - DOCKLE_OUTPUT_FORMAT: list - DOCKLE_EXIT_CODE: 1 - DOCKLE_EXIT_LEVEL: WARN - DOCKLE_IGNORES: CIS-DI-0005,CIS-DI-0010 - DOCKLE_DEBUG: true - with: - args: 'misskey:scan' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 48493f2c0..000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Lint - -on: - push: - branches: - - oscar - paths: - - packages/backend/** - - packages/frontend/** - - packages/sw/** - - packages/misskey-js/** - - packages/shared/.eslintrc.js - pull_request: - paths: - - packages/backend/** - - packages/frontend/** - - packages/sw/** - - packages/misskey-js/** - - packages/shared/.eslintrc.js - -jobs: - pnpm_install: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - uses: pnpm/action-setup@v4 - with: - run_install: false - - uses: actions/setup-node@v4.3.0 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - lint: - needs: [pnpm_install] - runs-on: ubuntu-latest - continue-on-error: true - strategy: - matrix: - workspace: - - backend - - frontend - - sw - - misskey-js - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - uses: pnpm/action-setup@v4 - with: - run_install: false - - uses: actions/setup-node@v4.3.0 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - run: pnpm --filter ${{ matrix.workspace }} run eslint - - typecheck: - needs: [pnpm_install] - runs-on: ubuntu-latest - continue-on-error: true - strategy: - matrix: - workspace: - - backend - - misskey-js - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - uses: pnpm/action-setup@v4 - with: - run_install: false - - uses: actions/setup-node@v4.3.0 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - run: pnpm -r run build:tsc - if: ${{ matrix.workspace == 'backend' }} - - run: pnpm --filter misskey-js run build - if: ${{ matrix.workspace == 'backend' }} - - run: pnpm --filter ${{ matrix.workspace }} run typecheck diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml deleted file mode 100644 index 9a0e4a899..000000000 --- a/.github/workflows/test-frontend.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Test (frontend) - -on: - push: - branches: - - oscar - paths: - - packages/frontend/** - # for permissions - - packages/misskey-js/** - # for e2e - - packages/backend/** - - pull_request: - paths: - - packages/frontend/** - # for permissions - - packages/misskey-js/** - # for e2e - - packages/backend/** - -jobs: - vitest: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [22.x] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - name: Check pnpm-lock.yaml - run: git diff --exit-code pnpm-lock.yaml - - name: Copy Configure - run: cp .github/misskey/test.yml .config - - name: Build - run: pnpm build - - name: Test - run: pnpm --filter frontend test-and-coverage - - name: Upload Coverage - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./packages/frontend/coverage/coverage-final.json diff --git a/.github/workflows/test-misskey-js.yml b/.github/workflows/test-misskey-js.yml deleted file mode 100644 index 460a9461f..000000000 --- a/.github/workflows/test-misskey-js.yml +++ /dev/null @@ -1,62 +0,0 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Test (misskey.js) - -on: - push: - branches: - - oscar - paths: - - packages/misskey-js/** - pull_request: - paths: - - packages/misskey-js/** - -jobs: - test: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [22.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - - name: Install dependencies - run: pnpm i --frozen-lockfile - - - name: Check pnpm-lock.yaml - run: git diff --exit-code pnpm-lock.yaml - - - name: Build - run: pnpm --filter misskey-js build - - - name: Test - run: pnpm --filter misskey-js test - env: - CI: true - - - name: Upload Coverage - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./packages/misskey-js/coverage/coverage-final.json diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml deleted file mode 100644 index ec2e831d9..000000000 --- a/.github/workflows/test-production.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Test (production install and build) - -on: - push: - branches: - - oscar - pull_request: - -env: - NODE_ENV: production - -jobs: - production: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [22.x] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - run: pnpm i --frozen-lockfile - - name: Check pnpm-lock.yaml - run: git diff --exit-code pnpm-lock.yaml - - name: Copy Configure - run: cp .github/misskey/test.yml .config/default.yml - - name: Build - run: pnpm build diff --git a/.github/workflows/validate-api-json.yml b/.github/workflows/validate-api-json.yml deleted file mode 100644 index 486303f22..000000000 --- a/.github/workflows/validate-api-json.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Test (backend) - -on: - push: - branches: - - oscar - paths: - - packages/backend/** - pull_request: - paths: - - packages/backend/** - -jobs: - validate-api-json: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [22.x] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - run_install: false - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4.3.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - name: Install Redocly CLI - run: npm i -g @redocly/cli - - run: pnpm i --frozen-lockfile - - name: Check pnpm-lock.yaml - run: git diff --exit-code pnpm-lock.yaml - - name: Copy Configure - run: cp .config/example.yml .config/default.yml - - name: Build and generate - run: pnpm build && pnpm --filter backend generate-api-json - - name: Validation - run: npx @redocly/cli lint --extends=minimal ./packages/backend/built/api.json diff --git a/Dockerfile b/Dockerfile index 73f7be639..77c5f6f8d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,7 +46,7 @@ RUN apt-get update \ WORKDIR /misskey COPY --link pnpm-lock.yaml ./ -RUN npm install -g pnpm@10 +RUN npm install -g pnpm@10 && mkdir -p /root/.local/share/pnpm/.tools RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ pnpm fetch --ignore-scripts @@ -81,6 +81,7 @@ WORKDIR /misskey COPY --chown=misskey:misskey pnpm-lock.yaml ./ RUN npm install -g pnpm@10 +COPY --chown=misskey:misskey --from=target-builder /root/.local/share/pnpm/.tools ./.local/share/pnpm/.tools COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules diff --git a/chart/templates/Deployment.yml b/chart/templates/Deployment.yml index 2d3c89e67..ca45ca9c1 100644 --- a/chart/templates/Deployment.yml +++ b/chart/templates/Deployment.yml @@ -27,7 +27,7 @@ spec: ports: - containerPort: 3000 - name: postgres - image: postgres:15-alpine + image: postgres:17-alpine env: - name: POSTGRES_USER value: "example-misskey-user" @@ -42,20 +42,8 @@ spec: env: - name: DFLY_version_check value: false - - name: DFLY_tcp_backlog - value: 2048 - name: DFLY_default_lua_flags value: allow-undeclared-keys - - name: DFLY_pipeline_squash - value: 0 - - name: DFLY_multi_exec_squash - value: false - - name: DFLY_conn_io_threads - value: 4 - - name: DFLY_epoll_file_threads - value: 4 - - name: DFLY_proactor_threads - value: 4 ports: - containerPort: 6379 volumes: diff --git a/docker-compose.local-db.yml b/docker-compose.local-db.yml index 25793bc4f..c33b94e66 100644 --- a/docker-compose.local-db.yml +++ b/docker-compose.local-db.yml @@ -11,13 +11,7 @@ services: environment: DFLY_snapshot_cron: '* * * * *' DFLY_version_check: false - DFLY_tcp_backlog: 2048 DFLY_default_lua_flags: allow-undeclared-keys - DFLY_pipeline_squash: 0 - DFLY_multi_exec_squash: false - DFLY_conn_io_threads: 4 - DFLY_epoll_file_threads: 4 - DFLY_proactor_threads: 4 ports: - "6379:6379" volumes: @@ -25,7 +19,7 @@ services: db: restart: always - image: postgres:15-alpine + image: postgres:17-alpine ports: - "5432:5432" env_file: diff --git a/docker-compose_example.yml b/docker-compose_example.yml index 379bc3d77..602dc5d30 100644 --- a/docker-compose_example.yml +++ b/docker-compose_example.yml @@ -31,13 +31,7 @@ services: environment: DFLY_snapshot_cron: '* * * * *' DFLY_version_check: false - DFLY_tcp_backlog: 2048 DFLY_default_lua_flags: allow-undeclared-keys - DFLY_pipeline_squash: 0 - DFLY_multi_exec_squash: false - DFLY_conn_io_threads: 4 - DFLY_epoll_file_threads: 4 - DFLY_proactor_threads: 4 networks: - internal_network volumes: @@ -45,7 +39,7 @@ services: db: restart: always - image: postgres:15-alpine + image: postgres:17-alpine networks: - internal_network env_file: diff --git a/package.json b/package.json index b44b533a4..b261898bb 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "misskey", - "version": "2024.5.0-oscar.24b", + "version": "2024.5.0-oscar.25", "codename": "nasubi", "repository": { "type": "git", "url": "https://git.psec.dev/oscar-surf/misskey.git" }, - "packageManager": "pnpm@10.7.0", + "packageManager": "pnpm@10.11.0", "workspaces": [ "packages/frontend", "packages/backend", @@ -22,9 +22,9 @@ "build": "pnpm build-pre && pnpm -r build && pnpm build-assets", "build-storybook": "pnpm --filter frontend build-storybook", "build-misskey-js-with-types": "pnpm build-pre && pnpm -r build:tsc && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api", - "start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js", - "start:docker": "pnpm check:connect && cd packages/backend && exec node ./built/boot/entry.js", - "start:test": "cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js", + "start": "pnpm check:connect && cd packages/backend && cross-env-shell \"node $MK_NODE_ARGS ./built/boot/entry.js\"", + "start:docker": "pnpm check:connect && cd packages/backend && exec cross-env-shell \"node $MK_NODE_ARGS ./built/boot/entry.js\"", + "start:test": "cd packages/backend && cross-env NODE_ENV=test cross-env-shell \"node $MK_NODE_ARGS ./built/boot/entry.js\"", "init": "pnpm migrate", "migrate": "cd packages/backend && pnpm migrate", "revert": "cd packages/backend && pnpm revert", @@ -47,39 +47,47 @@ }, "resolutions": { "@aiscript-dev/aiscript-languageserver": "github:aiscript-dev/aiscript-languageserver#0.1.6", + "@misskey-dev/summaly": "github:MisskeyIO/summaly#5.2.1-io.1", + "@tensorflow/tfjs": "4.22.0", "@tensorflow/tfjs-core": "4.22.0", - "axios": "1.8.4", + "@tensorflow/tfjs-node": "4.22.0", + "@types/punycode": "2.1.4", + "@types/punycode.js": "npm:@types/punycode@2.1.4", + "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.16", + "axios": "1.9.0", "chokidar": "4.0.3", "cookie": "1.0.2", "cookie-signature": "1.2.2", "debug": "4.4.0", - "esbuild": "0.25.2", + "esbuild": "0.25.4", "jpeg-js": "0.4.4", "lodash": "4.17.21", - "sharp": "0.33.5", + "sharp": "0.34.0-rc.0", + "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "tough-cookie": "5.1.2", + "webgl-audiovisualizer": "github:tar-bin/webgl-audiovisualizer", "web-streams-polyfill": "4.1.0" }, "dependencies": { - "cssnano": "7.0.6", - "execa": "9.5.2", + "cssnano": "7.0.7", + "execa": "9.5.3", "js-yaml": "4.1.0", "postcss": "8.5.3", - "terser": "5.39.0", - "typescript": "5.8.2" + "terser": "5.39.1", + "typescript": "5.8.3" }, "devDependencies": { - "@types/node": "22.13.14", + "@types/node": "22.15.17", "@typescript-eslint/eslint-plugin": "7.10.0", "@typescript-eslint/parser": "7.10.0", "cross-env": "7.0.3", - "cypress": "14.2.1", + "cypress": "14.3.3", "eslint": "8.57.1", "ncp": "2.0.0", "start-server-and-test": "2.0.11" }, "optionalDependencies": { - "@tensorflow/tfjs-core": "4.22.0" + "@tensorflow/tfjs-core": "managed" }, "pnpm": { "neverBuiltDependencies": [] diff --git a/packages/backend/migration/1745247339195-SSO-wantEmailAddressNormalized.js b/packages/backend/migration/1745247339195-SSO-wantEmailAddressNormalized.js new file mode 100644 index 000000000..9d65b3127 --- /dev/null +++ b/packages/backend/migration/1745247339195-SSO-wantEmailAddressNormalized.js @@ -0,0 +1,11 @@ +export class SSOWantEmailAddressNormalized1745247339195 { + name = 'SSOWantEmailAddressNormalized1745247339195' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "sso_service_provider" ADD "wantEmailAddressNormalized" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "sso_service_provider" DROP COLUMN "wantEmailAddressNormalized"`); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 523464d42..4d6832a67 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -33,18 +33,18 @@ "generate-api-json": "pnpm build && node ./scripts/generate_api_json.js" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.11.13", - "@swc/core-darwin-x64": "1.11.13", - "@swc/core-linux-arm-gnueabihf": "1.11.13", - "@swc/core-linux-arm64-gnu": "1.11.13", - "@swc/core-linux-arm64-musl": "1.11.13", - "@swc/core-linux-x64-gnu": "1.11.13", - "@swc/core-linux-x64-musl": "1.11.13", - "@swc/core-win32-arm64-msvc": "1.11.13", - "@swc/core-win32-ia32-msvc": "1.11.13", - "@swc/core-win32-x64-msvc": "1.11.13", - "@tensorflow/tfjs": "4.22.0", - "@tensorflow/tfjs-node": "4.22.0", + "@swc/core-darwin-arm64": "1.11.24", + "@swc/core-darwin-x64": "1.11.24", + "@swc/core-linux-arm-gnueabihf": "1.11.24", + "@swc/core-linux-arm64-gnu": "1.11.24", + "@swc/core-linux-arm64-musl": "1.11.24", + "@swc/core-linux-x64-gnu": "1.11.24", + "@swc/core-linux-x64-musl": "1.11.24", + "@swc/core-win32-arm64-msvc": "1.11.24", + "@swc/core-win32-ia32-msvc": "1.11.24", + "@swc/core-win32-x64-msvc": "1.11.24", + "@tensorflow/tfjs": "managed", + "@tensorflow/tfjs-node": "managed", "bufferutil": "4.0.9", "slacc-android-arm-eabi": "0.0.10", "slacc-android-arm64": "0.0.10", @@ -63,11 +63,11 @@ }, "dependencies": { "@authenio/samlify-node-xmllint": "2.0.0", - "@aws-sdk/client-s3": "3.779.0", - "@aws-sdk/lib-storage": "3.779.0", - "@bull-board/api": "6.7.10", - "@bull-board/fastify": "6.7.10", - "@bull-board/ui": "6.7.10", + "@aws-sdk/client-s3": "3.808.0", + "@aws-sdk/lib-storage": "3.808.0", + "@bull-board/api": "6.9.6", + "@bull-board/fastify": "6.9.6", + "@bull-board/ui": "6.9.6", "@discordapp/twemoji": "15.1.0", "@elastic/elasticsearch": "8.17.1", "@fastify/accepts": "5.0.2", @@ -78,20 +78,20 @@ "@fastify/http-proxy": "11.1.2", "@fastify/multipart": "9.0.3", "@fastify/static": "8.1.1", - "@fastify/view": "11.0.0", - "@misskey-dev/sharp-read-bmp": "1.2.0", - "@misskey-dev/summaly": "github:MisskeyIO/summaly#5.1.3", - "@napi-rs/canvas": "0.1.68", - "@nestjs/common": "11.0.12", - "@nestjs/core": "11.0.12", - "@nestjs/testing": "11.0.12", + "@fastify/view": "11.1.0", + "@misskey-dev/sharp-read-bmp": "1.3.0", + "@misskey-dev/summaly": "managed", + "@napi-rs/canvas": "0.1.70", + "@nestjs/common": "11.1.0", + "@nestjs/core": "11.1.0", + "@nestjs/testing": "11.1.0", "@peertube/http-signature": "1.7.0", "@simplewebauthn/server": "13.1.1", "@sinonjs/fake-timers": "11.3.1", "@smithy/node-http-handler": "4.0.4", - "@swc/cli": "0.6.0", - "@swc/core": "1.11.13", - "@twemoji/parser": "15.1.1", + "@swc/cli": "0.7.7", + "@swc/core": "1.11.24", + "@twemoji/parser": "16.0.0", "accepts": "1.3.8", "ajv": "8.17.1", "archiver": "7.0.1", @@ -99,39 +99,39 @@ "bcryptjs": "3.0.2", "blurhash": "2.0.5", "body-parser": "2.2.0", - "bullmq": "5.45.2", + "bullmq": "5.52.2", "cacheable-lookup": "7.0.0", "cbor": "10.0.3", "chalk": "5.4.1", "chalk-template": "1.1.0", - "chokidar": "4.0.3", + "chokidar": "managed", "cli-highlight": "2.1.11", - "color-convert": "3.0.1", + "color-convert": "3.1.0", "content-disposition": "0.5.4", "date-fns": "4.1.0", "deep-email-validator": "0.1.21", - "fastify": "5.2.2", + "fastify": "5.3.3", "fastify-http-errors-enhanced": "6.0.1", "fastify-raw-body": "5.0.0", - "feed": "4.2.2", - "file-type": "20.4.1", + "feed": "5.0.1", + "file-type": "20.5.0", "fluent-ffmpeg": "2.1.3", "form-data": "4.0.2", "got": "14.4.7", "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", - "jose": "6.0.10", + "is-svg": "6.0.0", + "jose": "6.0.11", "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", - "meilisearch": "0.49.0", + "meilisearch": "0.50.0", "mfm-js": "0.24.0", "microformats-parser": "2.0.2", "mime-types": "3.0.1", @@ -142,15 +142,15 @@ "nested-property": "4.0.0", "node-fetch": "3.3.2", "node-forge": "1.3.1", - "nodemailer": "6.10.0", + "nodemailer": "7.0.3", "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.16.0", "pino": "9.6.0", "pino-pretty": "13.0.0", "pkce-challenge": "5.0.0", @@ -162,37 +162,37 @@ "qrcode": "1.5.4", "random-seed": "0.3.0", "ratelimiter": "3.4.1", - "re2": "1.21.4", + "re2": "1.21.5", "reflect-metadata": "0.2.2", "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.2", - "samlify": "2.9.1", - "sanitize-html": "2.15.0", + "samlify": "2.10.0", + "sanitize-html": "2.16.0", "secure-json-parse": "4.0.0", - "sharp": "0.33.5", + "sharp": "managed", "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "systeminformation": "5.25.11", "tinycolor2": "1.6.0", "tmp": "0.2.3", - "tsc-alias": "1.8.13", + "tsc-alias": "1.8.16", "tsconfig-paths": "4.2.0", - "typeorm": "0.3.21", - "typescript": "5.8.2", + "typeorm": "0.3.23", + "typescript": "5.8.3", "ulid": "3.0.0", "vary": "1.1.2", "web-push": "3.6.7", - "ws": "8.18.1", + "ws": "8.18.2", "xev": "3.0.2", "xmlbuilder": "15.1.1" }, "devDependencies": { "@jest/globals": "29.7.0", "@misskey-dev/eslint-plugin": "1.0.0", - "@nestjs/platform-express": "11.0.12", - "@swc/jest": "0.2.37", + "@nestjs/platform-express": "11.1.0", + "@swc/jest": "0.2.38", "@types/accepts": "1.3.7", "@types/archiver": "6.0.3", "@types/body-parser": "1.19.5", @@ -208,21 +208,21 @@ "@types/jsrsasign": "10.5.15", "@types/mime-types": "2.1.4", "@types/ms": "2.1.0", - "@types/node": "22.13.14", + "@types/node": "22.15.17", "@types/node-forge": "1.3.11", "@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.15.1", "@types/psl": "1.1.3", "@types/pug": "2.0.10", - "@types/punycode.js": "npm:@types/punycode@2.1.4", + "@types/punycode.js": "managed", "@types/qrcode": "1.5.5", "@types/random-seed": "0.3.5", "@types/ratelimiter": "3.4.6", "@types/rename": "1.0.7", - "@types/sanitize-html": "2.15.0", + "@types/sanitize-html": "2.16.0", "@types/semver": "7.7.0", "@types/simple-oauth2": "5.0.7", "@types/sinonjs__fake-timers": "8.1.5", @@ -230,18 +230,18 @@ "@types/tmp": "0.2.6", "@types/vary": "1.1.3", "@types/web-push": "3.6.4", - "@types/ws": "8.18.0", + "@types/ws": "8.18.1", "@typescript-eslint/eslint-plugin": "7.10.0", "@typescript-eslint/parser": "7.10.0", "aws-sdk-client-mock": "4.1.0", "cross-env": "7.0.3", "eslint": "8.57.1", "eslint-plugin-import": "2.31.0", - "execa": "9.5.2", + "execa": "9.5.3", "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" } diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 65e58a560..bcf3e8f68 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -127,6 +127,8 @@ type Source = { perUserNotificationsMaxCount?: number; deactivateAntennaThreshold?: number; pidFile: string; + + extraHead?: string; }; export type Config = { @@ -232,6 +234,7 @@ export type Config = { perUserNotificationsMaxCount: number; deactivateAntennaThreshold: number; pidFile: string; + extraHead: string | undefined; }; const _filename = fileURLToPath(import.meta.url); @@ -341,6 +344,7 @@ export function loadConfig(): Config { perUserNotificationsMaxCount: config.perUserNotificationsMaxCount ?? 500, deactivateAntennaThreshold: config.deactivateAntennaThreshold ?? (1000 * 60 * 60 * 24 * 7), pidFile: config.pidFile, + extraHead: config.extraHead, }; } diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index 9cc821602..7061685dc 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -99,7 +99,7 @@ export class SearchService { if (config.meilisearch?.scope) { this.meilisearchIndexScope = config.meilisearch.scope; } - /*this.meilisearchNoteIndex.updateSettings({ + this.meilisearchNoteIndex.updateSettings({ searchableAttributes: [ 'text', 'cw', @@ -120,11 +120,10 @@ export class SearchService { pagination: { maxTotalHits: 10000, }, - });*/ + }); } else if (this.elasticsearch) { this.elasticsearchNoteIndex = `${config.elasticsearch!.index}`; this.elasticsearchIdField = `${config.host}_id`; - /* 外部からindexさせるのでこの処理は不要 this.elasticsearch.indices.exists({ index: this.elasticsearchNoteIndex, }).then((indexExists: boolean) => { @@ -178,7 +177,6 @@ export class SearchService { }).catch((error: any) => { this.logger.error('Error while checking if index exists', error); }); - */ } } @@ -217,7 +215,6 @@ export class SearchService { primaryKey: 'id', }); } else if (this.elasticsearch) { - /* 外部からindexさせるのでこの処理は不要 const body = { createdAt: createdAt.getTime(), userId: note.userId, @@ -234,7 +231,6 @@ export class SearchService { }).catch((error: any) => { this.logger.error(error); }); - */ } } @@ -245,14 +241,12 @@ export class SearchService { if (this.meilisearch) { await this.meilisearchNoteIndex?.deleteDocument(note.id); } else if (this.elasticsearch) { - /* 外部からindexさせるのでこの処理は不要 await this.elasticsearch.delete({ index: `${this.elasticsearchNoteIndex}-${this.idService.parse(note.id).date.toISOString().slice(0, 7).replace(/-/g, '')}`, id: note.id, }).catch((error) => { this.logger.error(error); }); - */ } } @@ -266,7 +260,7 @@ export class SearchService { query: { match_all: {}, }, - }).catch((error) => { + }).catch((error: any) => { this.logger.error(error); }); } @@ -383,7 +377,7 @@ export class SearchService { const noteIds = res.hits.hits.map((hit) => { const source = hit._source as Record; return (source[this.elasticsearchIdField] as string) || null; - }).filter((id): id is string => id !== null); + }).filter((id: any): id is string => id !== null); if (noteIds.length === 0) return []; const notes = await this.notesRepository.findBy({ id: In(noteIds), diff --git a/packages/backend/src/core/entities/MetaEntityService.ts b/packages/backend/src/core/entities/MetaEntityService.ts index a006f6faf..6b4961dbe 100644 --- a/packages/backend/src/core/entities/MetaEntityService.ts +++ b/packages/backend/src/core/entities/MetaEntityService.ts @@ -17,6 +17,7 @@ import { InstanceActorService } from '@/core/InstanceActorService.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; +import { envOption } from '@/env.js'; @Injectable() export class MetaEntityService { @@ -66,7 +67,7 @@ export class MetaEntityService { feedbackUrl: instance.feedbackUrl, impressumUrl: instance.impressumUrl, privacyPolicyUrl: instance.privacyPolicyUrl, - disableRegistration: instance.disableRegistration, + disableRegistration: instance.disableRegistration || envOption.disableRegistration, emailRequiredForSignup: instance.emailRequiredForSignup, canSkipInitialTutorial: instance.canSkipInitialTutorial, enableHcaptcha: instance.enableHcaptcha, diff --git a/packages/backend/src/env.ts b/packages/backend/src/env.ts index 317b35b65..af03582c8 100644 --- a/packages/backend/src/env.ts +++ b/packages/backend/src/env.ts @@ -12,6 +12,7 @@ const envOption = { logJson: false, withLogTime: false, quiet: false, + disableRegistration: false, }; for (const key of Object.keys(envOption) as (keyof typeof envOption)[]) { diff --git a/packages/backend/src/models/SingleSignOnServiceProvider.ts b/packages/backend/src/models/SingleSignOnServiceProvider.ts index 03a095754..85ce1cfdc 100644 --- a/packages/backend/src/models/SingleSignOnServiceProvider.ts +++ b/packages/backend/src/models/SingleSignOnServiceProvider.ts @@ -79,4 +79,9 @@ export class MiSingleSignOnServiceProvider { default: true, }) public wantAssertionsSigned: boolean; + + @Column('boolean', { + default: true, + }) + public wantEmailAddressNormalized: boolean; } diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index a0f909d93..10cd119f6 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -20,6 +20,7 @@ import { FastifyReplyError } from '@/misc/fastify-reply-error.js'; import { bindThis } from '@/decorators.js'; import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js'; import { LoggerService } from '@/core/LoggerService.js'; +import { envOption } from '@/env.js'; import { SigninService } from './SigninService.js'; import type { FastifyRequest, FastifyReply } from 'fastify'; import { randomUUID } from 'node:crypto'; @@ -136,7 +137,7 @@ export class SignupApiService { let ticket: MiRegistrationTicket | null = null; - if (instance.disableRegistration) { + if (instance.disableRegistration || envOption.disableRegistration) { if (invitationCode == null || typeof invitationCode !== 'string') { logger.error('Invalid request: invitation code is required.'); reply.code(400); diff --git a/packages/backend/src/server/api/endpoints/admin/sso/create.ts b/packages/backend/src/server/api/endpoints/admin/sso/create.ts index 79cfafe9c..f6e28d7a2 100644 --- a/packages/backend/src/server/api/endpoints/admin/sso/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/sso/create.ts @@ -84,6 +84,10 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + wantEmailAddressNormalized: { + type: 'boolean', + optional: false, nullable: false, + }, }, }, } as const; @@ -101,6 +105,7 @@ export const paramDef = { cipherAlgorithm: { type: 'string', nullable: true }, wantAuthnRequestsSigned: { type: 'boolean', nullable: false, default: false }, wantAssertionsSigned: { type: 'boolean', nullable: false, default: true }, + wantEmailAddressNormalized: { type: 'boolean', nullable: false, default: true }, useCertificate: { type: 'boolean', nullable: false, default: true }, secret: { type: 'string', nullable: true }, }, @@ -157,6 +162,7 @@ export default class extends Endpoint { // eslint- cipherAlgorithm: ps.cipherAlgorithm ? ps.cipherAlgorithm : null, wantAuthnRequestsSigned: ps.wantAuthnRequestsSigned, wantAssertionsSigned: ps.wantAssertionsSigned, + wantEmailAddressNormalized: ps.wantEmailAddressNormalized, }).then(r => this.singleSignOnServiceProviderRepository.findOneByOrFail({ id: r.identifiers[0].id })); this.moderationLogService.log(me, 'createSSOServiceProvider', { @@ -178,6 +184,7 @@ export default class extends Endpoint { // eslint- cipherAlgorithm: ssoServiceProvider.cipherAlgorithm, wantAuthnRequestsSigned: ssoServiceProvider.wantAuthnRequestsSigned, wantAssertionsSigned: ssoServiceProvider.wantAssertionsSigned, + wantEmailAddressNormalized: ssoServiceProvider.wantEmailAddressNormalized, }; }); } diff --git a/packages/backend/src/server/api/endpoints/admin/sso/list.ts b/packages/backend/src/server/api/endpoints/admin/sso/list.ts index 9adc9bc54..6c2031488 100644 --- a/packages/backend/src/server/api/endpoints/admin/sso/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/sso/list.ts @@ -77,6 +77,10 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + wantEmailAddressNormalized: { + type: 'boolean', + optional: false, nullable: false, + }, }, }, }, @@ -116,6 +120,7 @@ export default class extends Endpoint { // eslint- cipherAlgorithm: service.cipherAlgorithm, wantAuthnRequestsSigned: service.wantAuthnRequestsSigned, wantAssertionsSigned: service.wantAssertionsSigned, + wantEmailAddressNormalized: service.wantEmailAddressNormalized, })); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/sso/update.ts b/packages/backend/src/server/api/endpoints/admin/sso/update.ts index da8597cb4..870bdac58 100644 --- a/packages/backend/src/server/api/endpoints/admin/sso/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/sso/update.ts @@ -37,6 +37,7 @@ export const paramDef = { cipherAlgorithm: { type: 'string', nullable: true }, wantAuthnRequestsSigned: { type: 'boolean', nullable: false }, wantAssertionsSigned: { type: 'boolean', nullable: false }, + wantEmailAddressNormalized: { type: 'boolean', nullable: false }, regenerateCertificate: { type: 'boolean', nullable: true }, secret: { type: 'string', nullable: true }, }, @@ -92,6 +93,7 @@ export default class extends Endpoint { // eslint- cipherAlgorithm: ps.cipherAlgorithm !== '' ? ps.cipherAlgorithm : null, wantAuthnRequestsSigned: ps.wantAuthnRequestsSigned, wantAssertionsSigned: ps.wantAssertionsSigned, + wantEmailAddressNormalized: ps.wantEmailAddressNormalized, }); const updatedService = await this.singleSignOnServiceProviderRepository.findOneByOrFail({ id: service.id }); diff --git a/packages/backend/src/server/sso/JWTIdentifyProviderService.ts b/packages/backend/src/server/sso/JWTIdentifyProviderService.ts index 4e202688f..7d9b7fc7a 100644 --- a/packages/backend/src/server/sso/JWTIdentifyProviderService.ts +++ b/packages/backend/src/server/sso/JWTIdentifyProviderService.ts @@ -180,7 +180,9 @@ export class JWTIdentifyProviderService { preferred_username: user.username, profile: `${this.config.url}/@${user.username}`, picture: user.avatarUrl ?? undefined, - email: profile.emailVerified ? normalizeEmailAddress(profile.email) : `${user.username}@${this.config.hostname}`, + email: profile.emailVerified + ? (ssoServiceProvider.wantEmailAddressNormalized ? normalizeEmailAddress(profile.email) : profile.email) + : `${user.username}@users.${this.config.hostname}`, email_verified: profile.emailVerified, mfa_enabled: profile.twoFactorEnabled, updated_at: Math.floor((user.updatedAt?.getTime() ?? user.createdAt.getTime()) / 1000), diff --git a/packages/backend/src/server/sso/SAMLIdentifyProviderService.ts b/packages/backend/src/server/sso/SAMLIdentifyProviderService.ts index b0399ad6e..b8f236190 100644 --- a/packages/backend/src/server/sso/SAMLIdentifyProviderService.ts +++ b/packages/backend/src/server/sso/SAMLIdentifyProviderService.ts @@ -444,7 +444,9 @@ export class SAMLIdentifyProviderService { 'saml:Subject': { 'saml:NameID': { '@Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', - '#text': profile.emailVerified ? normalizeEmailAddress(profile.email) : `${user.username}@${this.config.hostname}`, + '#text': profile.emailVerified + ? (ssoServiceProvider.wantEmailAddressNormalized ? normalizeEmailAddress(profile.email) : profile.email) + : `${user.username}@users.${this.config.hostname}`, }, 'saml:SubjectConfirmation': { '@Method': 'urn:oasis:names:tc:SAML:2.0:cm:bearer', @@ -569,7 +571,9 @@ export class SAMLIdentifyProviderService { '@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', 'saml:AttributeValue': { '@xsi:type': 'xs:string', - '#text': profile.emailVerified ? normalizeEmailAddress(profile.email) : `${user.username}@${this.config.hostname}`, + '#text': profile.emailVerified + ? (ssoServiceProvider.wantEmailAddressNormalized ? normalizeEmailAddress(profile.email) : profile.email) + : `${user.username}@users.${this.config.hostname}`, }, }, { diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index 4aeb74de7..a738efd50 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -197,6 +197,7 @@ export class ClientServerService { instanceUrl: this.config.url, metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(meta)), now: Date.now(), + extraHead: this.config.extraHead, }; } @@ -433,7 +434,7 @@ export class ClientServerService { return await reply.sendFile('/robots.txt', staticAssets); }); - // OpenSearch XML + /* OpenSearch XML fastify.get('/opensearch.xml', async (request, reply) => { const meta = await this.metaService.fetch(); @@ -450,6 +451,7 @@ export class ClientServerService { reply.header('Content-Type', 'application/opensearchdescription+xml'); return await reply.send(content); }); + */ //#endregion diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index 04b208909..36b3c4521 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -37,7 +37,6 @@ export class UrlPreviewService { @bindThis private wrap(url?: string | null): string | null { if (!url) return null; - if (!RegExp(/^https?:\/\//).exec(url)) return url; return appendQuery( `${this.config.mediaProxy}/preview/${encodeURIComponent(omitHttps(url))}`, diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug index ab3d0d957..40b567169 100644 --- a/packages/backend/src/server/web/views/base.pug +++ b/packages/backend/src/server/web/views/base.pug @@ -73,6 +73,8 @@ html script(src=`/assets/boot.${version}.js`) + | !{extraHead} + body noscript: p | JavaScriptを有効にしてください diff --git a/packages/backend/test/docker-compose.yml b/packages/backend/test/docker-compose.yml index 74659a952..6236409a7 100644 --- a/packages/backend/test/docker-compose.yml +++ b/packages/backend/test/docker-compose.yml @@ -7,18 +7,12 @@ services: memlock: -1 environment: DFLY_version_check: false - DFLY_tcp_backlog: 2048 DFLY_default_lua_flags: allow-undeclared-keys - DFLY_pipeline_squash: 0 - DFLY_multi_exec_squash: false - DFLY_conn_io_threads: 4 - DFLY_epoll_file_threads: 4 - DFLY_proactor_threads: 4 ports: - "127.0.0.1:56312:6379" dbtest: - image: postgres:15 + image: postgres:17 ports: - "127.0.0.1:54312:5432" environment: diff --git a/packages/backend/test/e2e/drive.ts b/packages/backend/test/e2e/drive.ts index 35b28152c..2296924e7 100644 --- a/packages/backend/test/e2e/drive.ts +++ b/packages/backend/test/e2e/drive.ts @@ -25,7 +25,7 @@ describe('Drive', () => { const marker = Math.random().toString(); - const url = 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.jpg'; + const url = 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.jpg'; const catcher = makeStreamCatcher( alice, diff --git a/packages/backend/test/e2e/fetch-resource.ts b/packages/backend/test/e2e/fetch-resource.ts index 3ce816f5f..7a2b69ea7 100644 --- a/packages/backend/test/e2e/fetch-resource.ts +++ b/packages/backend/test/e2e/fetch-resource.ts @@ -104,7 +104,7 @@ describe('Webリソース', () => { { path: '/flush', type: HTML }, { path: '/robots.txt', type: 'text/plain; charset=utf-8' }, { path: '/favicon.ico', type: 'image/vnd.microsoft.icon' }, - { path: '/opensearch.xml', type: 'application/opensearchdescription+xml' }, +// { path: '/opensearch.xml', type: 'application/opensearchdescription+xml' }, { path: '/apple-touch-icon.png', type: 'image/png' }, { path: '/twemoji/2764.svg', type: 'image/svg+xml' }, { path: '/twemoji/2764-fe0f-200d-1f525.svg', type: 'image/svg+xml' }, diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 084b1ad7c..ef4227a1a 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -43,7 +43,7 @@ describe('Note', () => { }); test('ファイルを添付できる', async () => { - const file = await uploadUrl(alice, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.jpg'); + const file = await uploadUrl(alice, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.jpg'); const res = await api('notes/create', { fileIds: [file.id], @@ -55,7 +55,7 @@ describe('Note', () => { }, 1000 * 10); test('他人のファイルで怒られる', async () => { - const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.jpg'); + const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.jpg'); const res = await api('notes/create', { text: 'test', diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts index 29a54afe1..64375f8bd 100644 --- a/packages/backend/test/e2e/timelines.ts +++ b/packages/backend/test/e2e/timelines.ts @@ -354,8 +354,8 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await sleep(1000); const [bobFile, carolFile] = await Promise.all([ - uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'), - uploadUrl(carol, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'), + uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'), + uploadUrl(carol, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'), ]); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { fileIds: [bobFile.id] }); @@ -654,7 +654,7 @@ describe('Timelines', () => { test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => { const [alice, bob] = await Promise.all([signup(), signup()]); - const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'); + const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { fileIds: [file.id] }); @@ -794,7 +794,7 @@ describe('Timelines', () => { test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => { const [alice, bob] = await Promise.all([signup(), signup()]); - const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'); + const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { fileIds: [file.id] }); @@ -1008,7 +1008,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'); + const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { fileIds: [file.id] }); @@ -1167,7 +1167,7 @@ describe('Timelines', () => { test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => { const [alice, bob] = await Promise.all([signup(), signup()]); - const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'); + const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { fileIds: [file.id] }); diff --git a/packages/backend/test/e2e/user-notes.ts b/packages/backend/test/e2e/user-notes.ts index cf0249ea8..effc34607 100644 --- a/packages/backend/test/e2e/user-notes.ts +++ b/packages/backend/test/e2e/user-notes.ts @@ -17,8 +17,8 @@ describe('users/notes', () => { beforeAll(async () => { alice = await signup({ username: 'alice' }); - const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.jpg'); - const png = await uploadUrl(alice, 'https://raw.githubusercontent.com/MisskeyIO/misskey/io/packages/backend/test/resources/Lenna.png'); + const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.jpg'); + const png = await uploadUrl(alice, 'https://raw.githubusercontent.com/MisskeyIO/misskey/main/packages/backend/test/resources/Lenna.png'); jpgNote = await post(alice, { fileIds: [jpg.id], }); diff --git a/packages/backend/test/unit/AnnouncementService.ts b/packages/backend/test/unit/AnnouncementService.ts index ff3219b66..cf2d64696 100644 --- a/packages/backend/test/unit/AnnouncementService.ts +++ b/packages/backend/test/unit/AnnouncementService.ts @@ -6,6 +6,7 @@ process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; +import { IsNull, Not } from 'typeorm'; import { ModuleMocker } from 'jest-mock'; import { Test } from '@nestjs/testing'; import { GlobalModule } from '@/GlobalModule.js'; @@ -103,10 +104,10 @@ describe('AnnouncementService', () => { afterEach(async () => { await Promise.all([ - app.get(DI.metasRepository).delete({}), - usersRepository.delete({}), - announcementsRepository.delete({}), - announcementReadsRepository.delete({}), + app.get(DI.metasRepository).delete({ id: Not(IsNull()) }), + usersRepository.delete({ id: Not(IsNull()) }), + announcementsRepository.delete({ id: Not(IsNull()) }), + announcementReadsRepository.delete({ id: Not(IsNull()) }), ]); await app.close(); diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts index d27211302..6b37f0cfe 100644 --- a/packages/backend/test/unit/RoleService.ts +++ b/packages/backend/test/unit/RoleService.ts @@ -8,6 +8,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; +import { IsNull, Not } from 'typeorm'; import { ModuleMocker } from 'jest-mock'; import { Test } from '@nestjs/testing'; import * as lolex from '@sinonjs/fake-timers'; @@ -132,10 +133,10 @@ describe('RoleService', () => { clock.uninstall(); await Promise.all([ - app.get(DI.metasRepository).delete({}), - usersRepository.delete({}), - rolesRepository.delete({}), - roleAssignmentsRepository.delete({}), + app.get(DI.metasRepository).delete({ id: Not(IsNull()) }), + usersRepository.delete({ id: Not(IsNull()) }), + rolesRepository.delete({ id: Not(IsNull()) }), + roleAssignmentsRepository.delete({ id: Not(IsNull()) }), ]); await app.close(); diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 3014206cf..41987d5b1 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -27,27 +27,27 @@ "@rollup/pluginutils": "5.1.4", "@syuilo/aiscript": "0.19.0", "@tabler/icons-webfont": "3.31.0", - "@twemoji/parser": "15.1.1", - "@vitejs/plugin-vue": "5.2.3", + "@twemoji/parser": "16.0.0", + "@vitejs/plugin-vue": "5.2.4", "@vue/compiler-sfc": "3.5.13", - "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15", + "aiscript-vscode": "managed", "astring": "1.9.0", "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": "3.0.0", "chartjs-plugin-gradient": "0.6.1", "chartjs-plugin-zoom": "2.2.0", - "chromatic": "11.27.0", + "chromatic": "11.28.2", "compare-versions": "6.1.1", "cropperjs": "2.0.0", "date-fns": "4.1.0", "escape-regexp": "0.0.1", "estree-walker": "3.0.3", "eventemitter3": "5.0.1", - "idb-keyval": "6.2.1", + "idb-keyval": "6.2.2", "insert-text-at-cursor": "0.3.0", "is-file-animated": "1.0.2", "json5": "2.2.3", @@ -58,88 +58,88 @@ "misskey-reversi": "workspace:*", "photoswipe": "5.4.4", "punycode.js": "2.3.1", - "rollup": "4.38.0", - "sanitize-html": "2.15.0", - "sass": "1.86.0", - "shiki": "3.2.1", + "rollup": "4.40.2", + "sanitize-html": "2.16.0", + "sass": "1.88.0", + "shiki": "3.4.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.13", + "tsc-alias": "1.8.16", "tsconfig-paths": "4.2.0", - "typescript": "5.8.2", + "typescript": "5.8.3", "uuid": "11.1.0", "v-code-diff": "1.13.1", - "vite": "6.2.4", + "vite": "6.3.5", "vue": "3.5.13", - "vue-gtag": "3.2.0", + "vue-gtag": "3.5.0", "vuedraggable": "next", - "webgl-audiovisualizer": "github:tar-bin/webgl-audiovisualizer" + "webgl-audiovisualizer": "managed" }, "devDependencies": { "@misskey-dev/eslint-plugin": "1.0.0", - "@misskey-dev/summaly": "github:MisskeyIO/summaly#5.1.3", - "@storybook/addon-actions": "8.6.11", - "@storybook/addon-essentials": "8.6.11", - "@storybook/addon-interactions": "8.6.11", - "@storybook/addon-links": "8.6.11", - "@storybook/addon-mdx-gfm": "8.6.11", - "@storybook/addon-storysource": "8.6.11", - "@storybook/blocks": "8.6.11", - "@storybook/components": "8.6.11", - "@storybook/core-events": "8.6.11", - "@storybook/manager-api": "8.6.11", - "@storybook/preview-api": "8.6.11", - "@storybook/react": "8.6.11", - "@storybook/react-vite": "8.6.11", - "@storybook/test": "8.6.11", - "@storybook/theming": "8.6.11", - "@storybook/types": "8.6.11", - "@storybook/vue3": "8.6.11", - "@storybook/vue3-vite": "8.6.11", + "@misskey-dev/summaly": "managed", + "@storybook/addon-actions": "8.6.12", + "@storybook/addon-essentials": "8.6.12", + "@storybook/addon-interactions": "8.6.12", + "@storybook/addon-links": "8.6.12", + "@storybook/addon-mdx-gfm": "8.6.12", + "@storybook/addon-storysource": "8.6.12", + "@storybook/blocks": "8.6.12", + "@storybook/components": "8.6.12", + "@storybook/core-events": "8.6.12", + "@storybook/manager-api": "8.6.12", + "@storybook/preview-api": "8.6.12", + "@storybook/react": "8.6.12", + "@storybook/react-vite": "8.6.12", + "@storybook/test": "8.6.12", + "@storybook/theming": "8.6.12", + "@storybook/types": "8.6.12", + "@storybook/vue3": "8.6.12", + "@storybook/vue3-vite": "8.6.12", "@testing-library/vue": "8.1.0", "@types/canvas-confetti": "^1.6.4", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.7", "@types/matter-js": "0.19.8", "@types/micromatch": "4.0.9", - "@types/node": "22.13.14", - "@types/punycode.js": "npm:@types/punycode@2.1.4", - "@types/sanitize-html": "2.15.0", - "@types/three": "0.175.0", + "@types/node": "22.15.17", + "@types/punycode.js": "managed", + "@types/sanitize-html": "2.16.0", + "@types/three": "0.176.0", "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", - "@types/ws": "8.18.0", + "@types/ws": "8.18.1", "@typescript-eslint/eslint-plugin": "7.10.0", "@typescript-eslint/parser": "7.10.0", - "@vitest/coverage-v8": "3.1.1", + "@vitest/coverage-v8": "3.1.3", "@vue/runtime-core": "3.5.13", "acorn": "8.14.1", "cross-env": "7.0.3", - "cypress": "14.2.1", + "cypress": "14.3.3", "eslint": "8.57.1", "eslint-plugin-import": "2.31.0", "eslint-plugin-vue": "9.32.0", "fast-glob": "3.3.3", - "happy-dom": "17.4.4", + "happy-dom": "17.4.7", "intersection-observer": "0.12.2", "micromatch": "4.0.8", - "msw": "2.7.3", + "msw": "2.8.2", "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", "start-server-and-test": "2.0.11", - "storybook": "8.6.11", - "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", + "storybook": "8.6.12", + "storybook-addon-misskey-theme": "managed", "vite-plugin-turbosnap": "1.0.3", - "vitest": "3.1.1", + "vitest": "3.1.3", "vitest-fetch-mock": "0.3.0", - "vue-component-type-helpers": "2.2.8", + "vue-component-type-helpers": "2.2.10", "vue-eslint-parser": "9.4.3", - "vue-tsc": "2.2.8" + "vue-tsc": "2.2.10" } } diff --git a/packages/frontend/src/components/MkLink.vue b/packages/frontend/src/components/MkLink.vue index 36167e22e..32d2ae35e 100644 --- a/packages/frontend/src/components/MkLink.vue +++ b/packages/frontend/src/components/MkLink.vue @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only ref="el" style="word-break: break-all;" class="_link" - :[attr]="self ? url.substring(local.length) : url" + :[attr]="maybeRelativeUrl" :rel="rel ?? 'nofollow noopener'" :target="target" :behavior="props.navigationBehavior" @@ -28,7 +28,8 @@ import { useTooltip } from '@/scripts/use-tooltip.js'; import { warningExternalWebsite } from '@/scripts/warning-external-website.js'; import * as os from '@/os.js'; import { isEnabledUrlPreview } from '@/instance.js'; -import { MkABehavior } from '@/components/global/MkA.vue'; +import type { MkABehavior } from '@/components/global/MkA.vue'; +import { maybeMakeRelative } from '@/scripts/url.js'; const props = withDefaults(defineProps<{ url: string; @@ -39,7 +40,8 @@ const props = withDefaults(defineProps<{ hideIcon: false, }); -const self = props.url.startsWith(local); +const maybeRelativeUrl = maybeMakeRelative(props.url, local); +const self = maybeRelativeUrl !== props.url; const attr = self ? 'to' : 'href'; const target = self ? null : '_blank'; diff --git a/packages/frontend/src/components/MkRoleBadgeIcon.vue b/packages/frontend/src/components/MkRoleBadgeIcon.vue index b1b6cc51b..078ce2ccb 100644 --- a/packages/frontend/src/components/MkRoleBadgeIcon.vue +++ b/packages/frontend/src/components/MkRoleBadgeIcon.vue @@ -24,7 +24,11 @@ async function fetchSkebStatus() { return; } - userSkebStatus.value = await misskeyApiGet('users/get-skeb-status', { userId: props.userId }); + try { + userSkebStatus.value = await misskeyApiGet('users/get-skeb-status', { userId: props.userId }); + } catch { + userSkebStatus.value = null; + } } if (props.role.behavior === 'skeb') { diff --git a/packages/frontend/src/components/MkTutorial.FollowUsers.UserCard.vue b/packages/frontend/src/components/MkTutorial.FollowUsers.UserCard.vue index bb9af676e..a68db0188 100644 --- a/packages/frontend/src/components/MkTutorial.FollowUsers.UserCard.vue +++ b/packages/frontend/src/components/MkTutorial.FollowUsers.UserCard.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only