From 053e7626e41a7001a49287b2d51933151efaf4c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 4 May 2024 13:21:40 +0900 Subject: [PATCH 1/5] =?UTF-8?q?enhance(frontend=5Fais):=20PostForm?= =?UTF-8?q?=E7=B3=BB=E3=81=AE=E8=A8=AD=E5=AE=9A=E9=A0=85=E7=9B=AE=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=20(#13788)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend_ais): PostForm系の設定項目を追加 * Update Changelog --- CHANGELOG.md | 1 + packages/frontend/src/components/MkAsUi.vue | 4 ++ packages/frontend/src/scripts/aiscript/ui.ts | 62 ++++++++++---------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f3ae412effb..c54fa6ed78c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ - Enhance: フォローするかどうかの確認ダイアログを出せるように - Enhance: Playを手動でリロードできるように - Enhance: 通報のコメント内のリンクをクリックした際、ウィンドウで開くように +- Enhance: `Ui:C:postForm` および `Ui:C:postFormButton` に `localOnly` と `visibility` を設定できるように - Chore: AiScriptを0.18.0にバージョンアップ - Fix: 一部のページ内リンクが正しく動作しない問題を修正 - Fix: 周年の実績が閏年を考慮しない問題を修正 diff --git a/packages/frontend/src/components/MkAsUi.vue b/packages/frontend/src/components/MkAsUi.vue index 5eb77740be15..18e8e7542e3f 100644 --- a/packages/frontend/src/components/MkAsUi.vue +++ b/packages/frontend/src/components/MkAsUi.vue @@ -44,6 +44,8 @@ SPDX-License-Identifier: AGPL-3.0-only :instant="true" :initialText="c.form?.text" :initialCw="c.form?.cw" + :initialVisibility="c.form?.visibility" + :initialLocalOnly="c.form?.localOnly" /> @@ -111,6 +113,8 @@ function openPostForm() { os.post({ initialText: form.text, initialCw: form.cw, + initialVisibility: form.visibility, + initialLocalOnly: form.localOnly, instant: true, }); } diff --git a/packages/frontend/src/scripts/aiscript/ui.ts b/packages/frontend/src/scripts/aiscript/ui.ts index f2493264d37a..fa3fcac2e79a 100644 --- a/packages/frontend/src/scripts/aiscript/ui.ts +++ b/packages/frontend/src/scripts/aiscript/ui.ts @@ -6,6 +6,7 @@ import { utils, values } from '@syuilo/aiscript'; import { v4 as uuid } from 'uuid'; import { ref, Ref } from 'vue'; +import * as Misskey from 'misskey-js'; export type AsUiComponentBase = { id: string; @@ -115,23 +116,24 @@ export type AsUiFolder = AsUiComponentBase & { opened?: boolean; }; +type PostFormPropsForAsUi = { + text: string; + cw?: string; + visibility?: (typeof Misskey.noteVisibilities)[number]; + localOnly?: boolean; +}; + export type AsUiPostFormButton = AsUiComponentBase & { type: 'postFormButton'; text?: string; primary?: boolean; rounded?: boolean; - form?: { - text: string; - cw?: string; - }; + form?: PostFormPropsForAsUi; }; export type AsUiPostForm = AsUiComponentBase & { type: 'postForm'; - form?: { - text: string; - cw?: string; - }; + form?: PostFormPropsForAsUi; }; export type AsUiComponent = AsUiRoot | AsUiContainer | AsUiText | AsUiMfm | AsUiButton | AsUiButtons | AsUiSwitch | AsUiTextarea | AsUiTextInput | AsUiNumberInput | AsUiSelect | AsUiFolder | AsUiPostFormButton | AsUiPostForm; @@ -447,6 +449,24 @@ function getFolderOptions(def: values.Value | undefined): Omit Promise): Omit { utils.assertObject(def); @@ -459,22 +479,11 @@ function getPostFormButtonOptions(def: values.Value | undefined, call: (fn: valu const form = def.value.get('form'); if (form) utils.assertObject(form); - const getForm = () => { - const text = form!.value.get('text'); - utils.assertString(text); - const cw = form!.value.get('cw'); - if (cw) utils.assertString(cw); - return { - text: text.value, - cw: cw?.value, - }; - }; - return { text: text?.value, primary: primary?.value, rounded: rounded?.value, - form: form ? getForm() : { + form: form ? getPostFormProps(form) : { text: '', }, }; @@ -486,19 +495,8 @@ function getPostFormOptions(def: values.Value | undefined, call: (fn: values.VFn const form = def.value.get('form'); if (form) utils.assertObject(form); - const getForm = () => { - const text = form!.value.get('text'); - utils.assertString(text); - const cw = form!.value.get('cw'); - if (cw) utils.assertString(cw); - return { - text: text.value, - cw: cw?.value, - }; - }; - return { - form: form ? getForm() : { + form: form ? getPostFormProps(form) : { text: '', }, }; From eef7fcdd45b12556c07c0cff31ee7c37a0e9d12f Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sat, 4 May 2024 19:40:17 +0900 Subject: [PATCH 2/5] chore(frontend): ui tweak --- packages/frontend/src/pages/admin-user.vue | 2 +- packages/frontend/src/pages/admin/roles.role.vue | 2 +- packages/frontend/src/scripts/get-user-menu.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/admin-user.vue b/packages/frontend/src/pages/admin-user.vue index 2cef55df6c9e..f57aa51b5b54 100644 --- a/packages/frontend/src/pages/admin-user.vue +++ b/packages/frontend/src/pages/admin-user.vue @@ -416,7 +416,7 @@ async function assignRole() { if (canceled) return; const { canceled: canceled2, result: period } = await os.select({ - title: i18n.ts.period, + title: i18n.ts.period + ': ' + roles.find(r => r.id === roleId)!.name, items: [{ value: 'indefinitely', text: i18n.ts.indefinitely, }, { diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue index ab8005045bdd..8b3c906d8a6e 100644 --- a/packages/frontend/src/pages/admin/roles.role.vue +++ b/packages/frontend/src/pages/admin/roles.role.vue @@ -119,7 +119,7 @@ async function assign() { const user = await os.selectUser({ includeSelf: true }); const { canceled: canceled2, result: period } = await os.select({ - title: i18n.ts.period, + title: i18n.ts.period + ': ' + role.name, items: [{ value: 'indefinitely', text: i18n.ts.indefinitely, }, { diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts index c14f75f38275..3e031d232ff9 100644 --- a/packages/frontend/src/scripts/get-user-menu.ts +++ b/packages/frontend/src/scripts/get-user-menu.ts @@ -272,7 +272,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: IRouter text: r.name, action: async () => { const { canceled, result: period } = await os.select({ - title: i18n.ts.period, + title: i18n.ts.period + ': ' + r.name, items: [{ value: 'indefinitely', text: i18n.ts.indefinitely, }, { From 2b21c1936212b6e1288d545b71544888e84ce8ab Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sat, 4 May 2024 20:56:14 +0900 Subject: [PATCH 3/5] update deps (#13624) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update deps * Update package.json * update deps * build: pass --strip-leading-paths to restore 0.2.x behavior (#13684) * :v: * :v: * pureimageの代わりに@napi-rs/canvasを使う (#13748) * pureimageの代わりに@napi-rs/canvasを使う * remove writestream * remove createtemp * wip * Update ClientServerService.ts * update pnpm to 9.x * update deps * re: update pnpm to 9.x * update node * :v: --------- Co-authored-by: anatawa12 Co-authored-by: tamaina --- .devcontainer/devcontainer.json | 2 +- .../workflows/check-misskey-js-autogen.yml | 2 +- .github/workflows/get-api-diff.yml | 4 +- .github/workflows/lint.yml | 6 +- .github/workflows/on-release-created.yml | 4 +- .github/workflows/storybook.yml | 2 +- .github/workflows/test-backend.yml | 8 +- .github/workflows/test-frontend.yml | 8 +- .github/workflows/test-misskey-js.yml | 2 +- .github/workflows/test-production.yml | 4 +- .github/workflows/validate-api-json.yml | 4 +- .node-version | 2 +- Dockerfile | 2 +- package.json | 24 +- packages/backend/package.json | 114 +- packages/backend/src/core/WebAuthnService.ts | 22 +- packages/backend/src/misc/gen-identicon.ts | 9 +- packages/backend/src/server/ServerService.ts | 5 +- .../server/api/endpoints/i/2fa/key-done.ts | 6 +- .../src/server/web/ClientServerService.ts | 5 + .../backend/src/server/web/views/base.pug | 2 +- .../frontend/.storybook/preview-head.html | 2 +- packages/frontend/package.json | 64 +- packages/frontend/src/_dev_boot_.ts | 2 +- packages/misskey-js/package.json | 14 +- packages/sw/package.json | 6 +- pnpm-lock.yaml | 24340 +++++++++------- scripts/build-assets.mjs | 2 +- 28 files changed, 14056 insertions(+), 10611 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f8d9905ecdf6..182ee2fbb2cc 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,7 @@ "version": "8.9.2" }, "ghcr.io/devcontainers/features/node:1": { - "version": "20.10.0" + "version": "20.12.2" } }, "forwardPorts": [3000], diff --git a/.github/workflows/check-misskey-js-autogen.yml b/.github/workflows/check-misskey-js-autogen.yml index 4aa0646b7b89..9052b2e3722e 100644 --- a/.github/workflows/check-misskey-js-autogen.yml +++ b/.github/workflows/check-misskey-js-autogen.yml @@ -26,7 +26,7 @@ jobs: - name: setup pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 - name: setup node id: setup-node diff --git a/.github/workflows/get-api-diff.yml b/.github/workflows/get-api-diff.yml index e737b89b42e5..146e0686e584 100644 --- a/.github/workflows/get-api-diff.yml +++ b/.github/workflows/get-api-diff.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] api-json-name: [api-base.json, api-head.json] include: - api-json-name: api-base.json @@ -34,7 +34,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9b3f85fe1db9..9a269014ab82 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -29,7 +29,7 @@ jobs: submodules: true - uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - uses: actions/setup-node@v4.0.2 with: @@ -56,7 +56,7 @@ jobs: submodules: true - uses: pnpm/action-setup@v3 with: - version: 7 + version: 9 run_install: false - uses: actions/setup-node@v4.0.2 with: @@ -82,7 +82,7 @@ jobs: submodules: true - uses: pnpm/action-setup@v3 with: - version: 7 + version: 9 run_install: false - uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/on-release-created.yml b/.github/workflows/on-release-created.yml index 069534bd53c5..52463d7542f9 100644 --- a/.github/workflows/on-release-created.yml +++ b/.github/workflows/on-release-created.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] steps: - uses: actions/checkout@v4.1.1 @@ -26,7 +26,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index ca82f4bcf3de..3bc354b331c7 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -36,7 +36,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js 20.x uses: actions/setup-node@v4.0.2 diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml index a803db4508a5..525cd0916b0f 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] services: postgres: @@ -43,7 +43,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Install FFmpeg uses: FedericoCarboni/setup-ffmpeg@v3 @@ -73,7 +73,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] services: postgres: @@ -95,7 +95,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index 1e020b73680b..9df3c983935a 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] steps: - uses: actions/checkout@v4.1.1 @@ -35,7 +35,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 @@ -64,7 +64,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [20.10.0] + node-version: [20.12.2] browser: [chrome] services: @@ -93,7 +93,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 7 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 diff --git a/.github/workflows/test-misskey-js.yml b/.github/workflows/test-misskey-js.yml index f73bd0b08f7c..2589d908b8d4 100644 --- a/.github/workflows/test-misskey-js.yml +++ b/.github/workflows/test-misskey-js.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml index 77af08b6fe0f..24a530e07370 100644 --- a/.github/workflows/test-production.yml +++ b/.github/workflows/test-production.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] steps: - uses: actions/checkout@v4.1.1 @@ -25,7 +25,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 diff --git a/.github/workflows/validate-api-json.yml b/.github/workflows/validate-api-json.yml index 36ed8d273f65..229c447893bc 100644 --- a/.github/workflows/validate-api-json.yml +++ b/.github/workflows/validate-api-json.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: - node-version: [20.10.0] + node-version: [20.12.2] steps: - uses: actions/checkout@v4.1.1 @@ -26,7 +26,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v3 with: - version: 8 + version: 9 run_install: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.0.2 diff --git a/.node-version b/.node-version index d5a159609d09..87834047a6fa 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -20.10.0 +20.12.2 diff --git a/Dockerfile b/Dockerfile index ee3a30a3c17d..9fc2d611cd82 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax = docker/dockerfile:1.4 -ARG NODE_VERSION=20.10.0-bullseye +ARG NODE_VERSION=20.12.2-bullseye # build assets & compile TypeScript diff --git a/package.json b/package.json index 84d6db5124a3..23e0ea0ee5b9 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@8.15.4", + "packageManager": "pnpm@9.0.6", "workspaces": [ "packages/frontend", "packages/backend", @@ -48,24 +48,24 @@ "lodash": "4.17.21" }, "dependencies": { - "cssnano": "6.0.5", + "cssnano": "6.1.2", "execa": "8.0.1", "fast-glob": "3.3.2", "ignore-walk": "6.0.4", "js-yaml": "4.1.0", - "postcss": "8.4.35", - "tar": "6.2.0", - "terser": "5.28.1", - "typescript": "5.3.3", - "esbuild": "0.19.11", - "glob": "10.3.10" + "postcss": "8.4.38", + "tar": "6.2.1", + "terser": "5.30.3", + "typescript": "5.4.5", + "esbuild": "0.20.2", + "glob": "10.3.12" }, "devDependencies": { - "@types/node": "^20.11.28", - "@typescript-eslint/eslint-plugin": "7.1.0", - "@typescript-eslint/parser": "7.1.0", + "@types/node": "20.12.7", + "@typescript-eslint/eslint-plugin": "7.7.1", + "@typescript-eslint/parser": "7.7.1", "cross-env": "7.0.3", - "cypress": "13.6.6", + "cypress": "13.7.3", "eslint": "8.57.0", "ncp": "2.0.0", "start-server-and-test": "2.0.3" diff --git a/packages/backend/package.json b/packages/backend/package.json index 7f70ae0c975a..23b3bfdb8bfe 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -12,9 +12,9 @@ "migrate": "pnpm typeorm migration:run -d ormconfig.js", "revert": "pnpm typeorm migration:revert -d ormconfig.js", "check:connect": "node ./scripts/check_connect.js", - "build": "swc src -d built -D", - "build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc", - "watch:swc": "swc src -d built -D -w", + "build": "swc src -d built -D --strip-leading-paths", + "build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths", + "watch:swc": "swc src -d built -D -w --strip-leading-paths", "build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json", "watch": "node ./scripts/watch.mjs", "restart": "pnpm build && pnpm start", @@ -67,38 +67,39 @@ "dependencies": { "@aws-sdk/client-s3": "3.412.0", "@aws-sdk/lib-storage": "3.412.0", - "@bull-board/api": "5.14.2", - "@bull-board/fastify": "5.14.2", - "@bull-board/ui": "5.14.2", - "@discordapp/twemoji": "15.0.2", + "@bull-board/api": "5.17.0", + "@bull-board/fastify": "5.17.0", + "@bull-board/ui": "5.17.0", + "@discordapp/twemoji": "15.0.3", "@fastify/accepts": "4.3.0", "@fastify/cookie": "9.3.1", - "@fastify/cors": "8.5.0", - "@fastify/express": "2.3.0", - "@fastify/http-proxy": "9.3.0", - "@fastify/multipart": "8.1.0", - "@fastify/static": "6.12.0", - "@fastify/view": "8.2.0", + "@fastify/cors": "9.0.1", + "@fastify/express": "3.0.0", + "@fastify/http-proxy": "9.5.0", + "@fastify/multipart": "8.2.0", + "@fastify/static": "7.0.3", + "@fastify/view": "9.1.0", "@misskey-dev/sharp-read-bmp": "1.2.0", "@misskey-dev/summaly": "5.1.0", - "@nestjs/common": "10.3.3", - "@nestjs/core": "10.3.3", - "@nestjs/testing": "10.3.3", + "@napi-rs/canvas": "^0.1.52", + "@nestjs/common": "10.3.8", + "@nestjs/core": "10.3.8", + "@nestjs/testing": "10.3.8", "@peertube/http-signature": "1.7.0", - "@simplewebauthn/server": "9.0.3", + "@simplewebauthn/server": "10.0.0", "@sinonjs/fake-timers": "11.2.2", - "@smithy/node-http-handler": "2.1.10", - "@swc/cli": "0.1.63", - "@swc/core": "1.3.107", - "@twemoji/parser": "15.0.0", + "@smithy/node-http-handler": "2.5.0", + "@swc/cli": "0.3.12", + "@swc/core": "1.4.17", + "@twemoji/parser": "15.1.1", "accepts": "1.3.8", - "ajv": "8.12.0", - "archiver": "6.0.1", - "async-mutex": "0.4.1", + "ajv": "8.13.0", + "archiver": "7.0.1", + "async-mutex": "0.5.0", "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.2", - "bullmq": "5.4.0", + "bullmq": "5.7.8", "cacheable-lookup": "7.0.0", "cbor": "9.0.2", "chalk": "5.3.0", @@ -109,85 +110,84 @@ "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "fastify": "4.25.2", + "fastify": "4.26.2", "fastify-raw-body": "4.3.0", "feed": "4.2.2", "file-type": "19.0.0", "fluent-ffmpeg": "2.1.2", "form-data": "4.0.0", - "got": "14.2.0", - "happy-dom": "10.0.3", + "got": "14.2.1", + "happy-dom": "14.7.1", "hpagent": "1.2.0", "htmlescape": "1.1.1", - "http-link-header": "1.1.2", - "ioredis": "5.3.2", + "http-link-header": "1.1.3", + "ioredis": "5.4.1", "ip-cidr": "3.1.0", - "ipaddr.js": "2.1.0", + "ipaddr.js": "2.2.0", "is-svg": "5.0.0", "js-yaml": "4.1.0", - "jsdom": "23.2.0", + "jsdom": "24.0.0", "json5": "2.2.3", "jsonld": "8.3.2", "jsrsasign": "11.1.0", - "meilisearch": "0.37.0", + "meilisearch": "0.38.0", "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.6", + "nanoid": "5.0.7", "nested-property": "4.0.0", "node-fetch": "3.3.2", - "nodemailer": "6.9.10", + "nodemailer": "6.9.13", "nsfwjs": "2.4.2", "oauth": "0.10.0", "oauth2orize": "1.12.0", "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", - "otpauth": "9.2.2", + "otpauth": "9.2.3", "parse5": "7.1.2", - "pg": "8.11.3", + "pg": "8.11.5", "pkce-challenge": "4.1.0", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", "pug": "3.0.2", "punycode": "2.3.1", - "pureimage": "0.3.17", "qrcode": "1.5.3", "random-seed": "0.3.0", "ratelimiter": "3.4.1", - "re2": "1.20.9", + "re2": "1.20.10", "redis-lock": "0.1.4", - "reflect-metadata": "0.2.1", + "reflect-metadata": "0.2.2", "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.1", - "sanitize-html": "2.12.1", + "sanitize-html": "2.13.0", "secure-json-parse": "2.7.0", - "sharp": "0.33.2", + "sharp": "0.33.3", "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", - "systeminformation": "5.22.0", + "systeminformation": "5.22.7", "tinycolor2": "1.6.0", - "tmp": "0.2.2", + "tmp": "0.2.3", "tsc-alias": "1.8.8", "tsconfig-paths": "4.2.0", "typeorm": "0.3.20", - "typescript": "5.3.3", + "typescript": "5.4.5", "ulid": "2.3.0", "vary": "1.1.2", "web-push": "3.6.7", - "ws": "8.16.0", + "ws": "8.17.0", "xev": "3.0.2" }, "devDependencies": { "@jest/globals": "29.7.0", "@misskey-dev/eslint-plugin": "1.0.0", - "@nestjs/platform-express": "10.3.3", - "@simplewebauthn/types": "9.0.1", - "@swc/jest": "0.2.31", + "@nestjs/platform-express": "10.3.8", + "@simplewebauthn/types": "10.0.0", + "@swc/jest": "0.2.36", "@types/accepts": "1.3.7", "@types/archiver": "6.0.2", "@types/bcryptjs": "2.4.6", @@ -197,20 +197,20 @@ "@types/fluent-ffmpeg": "2.1.24", "@types/htmlescape": "^1.1.3", "@types/http-link-header": "1.0.5", - "@types/jest": "29.5.11", + "@types/jest": "29.5.12", "@types/js-yaml": "4.0.9", "@types/jsdom": "21.1.6", "@types/jsonld": "1.5.13", - "@types/jsrsasign": "10.5.12", + "@types/jsrsasign": "10.5.14", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "20.11.22", + "@types/node": "20.12.7", "@types/node-fetch": "3.0.3", - "@types/nodemailer": "6.4.14", + "@types/nodemailer": "6.4.15", "@types/oauth": "0.9.4", - "@types/oauth2orize": "1.11.3", + "@types/oauth2orize": "1.11.5", "@types/oauth2orize-pkce": "0.1.2", - "@types/pg": "8.11.2", + "@types/pg": "8.11.5", "@types/pug": "2.0.10", "@types/punycode": "2.1.4", "@types/qrcode": "1.5.5", @@ -226,8 +226,8 @@ "@types/vary": "1.1.3", "@types/web-push": "3.6.3", "@types/ws": "8.5.10", - "@typescript-eslint/eslint-plugin": "7.1.0", - "@typescript-eslint/parser": "7.1.0", + "@typescript-eslint/eslint-plugin": "7.7.1", + "@typescript-eslint/parser": "7.7.1", "aws-sdk-client-mock": "3.0.1", "cross-env": "7.0.3", "eslint": "8.57.0", diff --git a/packages/backend/src/core/WebAuthnService.ts b/packages/backend/src/core/WebAuthnService.ts index 42fbed21107a..ec9f4484a4c0 100644 --- a/packages/backend/src/core/WebAuthnService.ts +++ b/packages/backend/src/core/WebAuthnService.ts @@ -10,7 +10,7 @@ import { generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse, } from '@simplewebauthn/server'; -import { AttestationFormat, isoCBOR } from '@simplewebauthn/server/helpers'; +import { AttestationFormat, isoCBOR, isoUint8Array } from '@simplewebauthn/server/helpers'; import { DI } from '@/di-symbols.js'; import type { UserSecurityKeysRepository } from '@/models/_.js'; import type { Config } from '@/config.js'; @@ -49,7 +49,7 @@ export class WebAuthnService { const instance = await this.metaService.fetch(); return { origin: this.config.url, - rpId: this.config.host, + rpId: this.config.hostname, rpName: instance.name ?? this.config.host, rpIcon: instance.iconUrl ?? undefined, }; @@ -65,13 +65,12 @@ export class WebAuthnService { const registrationOptions = await generateRegistrationOptions({ rpName: relyingParty.rpName, rpID: relyingParty.rpId, - userID: userId, + userID: isoUint8Array.fromUTF8String(userId), userName: userName, userDisplayName: userDisplayName, attestationType: 'indirect', - excludeCredentials: keys.map(key => ({ - id: Buffer.from(key.id, 'base64url'), - type: 'public-key', + excludeCredentials: keys.map(key => (<{ id: string; transports?: AuthenticatorTransportFuture[]; }>{ + id: key.id, transports: key.transports ?? undefined, })), authenticatorSelection: { @@ -87,7 +86,7 @@ export class WebAuthnService { @bindThis public async verifyRegistration(userId: MiUser['id'], response: RegistrationResponseJSON): Promise<{ - credentialID: Uint8Array; + credentialID: string; credentialPublicKey: Uint8Array; attestationObject: Uint8Array; fmt: AttestationFormat; @@ -144,6 +143,7 @@ export class WebAuthnService { @bindThis public async initiateAuthentication(userId: MiUser['id']): Promise { + const relyingParty = await this.getRelyingParty(); const keys = await this.userSecurityKeysRepository.findBy({ userId: userId, }); @@ -153,9 +153,9 @@ export class WebAuthnService { } const authenticationOptions = await generateAuthenticationOptions({ - allowCredentials: keys.map(key => ({ - id: Buffer.from(key.id, 'base64url'), - type: 'public-key', + rpID: relyingParty.rpId, + allowCredentials: keys.map(key => (<{ id: string; transports?: AuthenticatorTransportFuture[]; }>{ + id: key.id, transports: key.transports ?? undefined, })), userVerification: 'preferred', @@ -219,7 +219,7 @@ export class WebAuthnService { expectedOrigin: relyingParty.origin, expectedRPID: relyingParty.rpId, authenticator: { - credentialID: Buffer.from(key.id, 'base64url'), + credentialID: key.id, credentialPublicKey: Buffer.from(key.publicKey, 'base64url'), counter: key.counter, transports: key.transports ? key.transports as AuthenticatorTransportFuture[] : undefined, diff --git a/packages/backend/src/misc/gen-identicon.ts b/packages/backend/src/misc/gen-identicon.ts index 62a8ab8ace45..342e0f8602c6 100644 --- a/packages/backend/src/misc/gen-identicon.ts +++ b/packages/backend/src/misc/gen-identicon.ts @@ -8,9 +8,8 @@ * https://en.wikipedia.org/wiki/Identicon */ -import * as p from 'pureimage'; +import { createCanvas } from '@napi-rs/canvas'; import gen from 'random-seed'; -import type { WriteStream } from 'node:fs'; const size = 128; // px const n = 5; // resolution @@ -45,9 +44,9 @@ const sideN = Math.floor(n / 2); /** * Generate buffer of an identicon by seed */ -export function genIdenticon(seed: string, stream: WriteStream): Promise { +export async function genIdenticon(seed: string): Promise { const rand = gen.create(seed); - const canvas = p.make(size, size, undefined); + const canvas = createCanvas(size, size); const ctx = canvas.getContext('2d'); const bgColors = colors[rand(colors.length)]; @@ -101,5 +100,5 @@ export function genIdenticon(seed: string, stream: WriteStream): Promise { } } - return p.encodePNGToStream(canvas, stream); + return await canvas.encode('png'); } diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 1324cd1361e5..da17a88e0351 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -18,7 +18,6 @@ import { DI } from '@/di-symbols.js'; import type Logger from '@/logger.js'; import * as Acct from '@/misc/acct.js'; import { genIdenticon } from '@/misc/gen-identicon.js'; -import { createTemp } from '@/misc/create-temp.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { LoggerService } from '@/core/LoggerService.js'; import { bindThis } from '@/decorators.js'; @@ -192,9 +191,7 @@ export class ServerService implements OnApplicationShutdown { reply.header('Cache-Control', 'public, max-age=86400'); if ((await this.metaService.fetch()).enableIdenticonGeneration) { - const [temp, cleanup] = await createTemp(); - await genIdenticon(request.params.x, fs.createWriteStream(temp)); - return fs.createReadStream(temp).on('close', () => cleanup()); + return await genIdenticon(request.params.x); } else { return reply.redirect('/static-assets/avatar.png'); } diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts index 5f738420f2eb..65eece5b9705 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts @@ -96,10 +96,10 @@ export default class extends Endpoint { } const keyInfo = await this.webAuthnService.verifyRegistration(me.id, ps.credential); + const keyId = keyInfo.credentialID; - const credentialId = Buffer.from(keyInfo.credentialID).toString('base64url'); await this.userSecurityKeysRepository.insert({ - id: credentialId, + id: keyId, userId: me.id, name: ps.name, publicKey: Buffer.from(keyInfo.credentialPublicKey).toString('base64url'), @@ -116,7 +116,7 @@ export default class extends Endpoint { })); return { - id: credentialId, + id: keyId, name: ps.name, }; }); diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index ba2f8b432409..1394616752bb 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -199,6 +199,11 @@ export class ClientServerService { // Authenticate fastify.addHook('onRequest', async (request, reply) => { + if (request.routeOptions.url == null) { + reply.code(404).send('Not found'); + return; + } + // %71ueueとかでリクエストされたら困るため const url = decodeURI(request.routeOptions.url); if (url === bullBoardPath || url.startsWith(bullBoardPath + '/')) { diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug index 123336809be0..1d9146e22a37 100644 --- a/packages/backend/src/server/web/views/base.pug +++ b/packages/backend/src/server/web/views/base.pug @@ -36,7 +36,7 @@ html link(rel='prefetch' href=infoImageUrl) link(rel='prefetch' href=notFoundImageUrl) //- https://github.com/misskey-dev/misskey/issues/9842 - link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v2.44.0') + link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v3.3.0') link(rel='modulepreload' href=`/vite/${clientEntry.file}`) if !config.clientManifestExists diff --git a/packages/frontend/.storybook/preview-head.html b/packages/frontend/.storybook/preview-head.html index e50c48824332..4722fe7f5f46 100644 --- a/packages/frontend/.storybook/preview-head.html +++ b/packages/frontend/.storybook/preview-head.html @@ -5,7 +5,7 @@ - +