diff --git a/CHANGELOG.md b/CHANGELOG.md index 824386e6bc..78233e71a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Fix: プロフィール追加情報で無効なURLに入力された場合に照会エラーを出るのを修正 - Fix: ActivityPubリクエストURLチェック実装は仕様に従っていないのを修正 - Fix: 連合無しモードでも外部から照会可能だった問題を修正 +- Fix: テスト用WebHookのペイロードの`emojis`パラメータが実際のものと異なる問題を修正 ## 2025.3.1 diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 4966007061..5e936da80c 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -1013,6 +1013,7 @@ flip: "اقلب" lastNDays: "آخر {n} أيام" surrender: "ألغِ" postForm: "أنشئ ملاحظة" +information: "عن" _delivery: stop: "مُعلّق" _initialAccountSetting: diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 6aea5a1999..36d142bd0b 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -853,6 +853,7 @@ renotes: "রিনোট" sourceCode: "সোর্স কোড" flip: "উল্টান" postForm: "নোট লিখুন" +information: "আপনার সম্পর্কে" _delivery: stop: "স্থগিত করা হয়েছে" _type: diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 44fb48f5f5..23b958252a 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1334,6 +1334,7 @@ paste: "Pegar" emojiPalette: "Calaix d'emojis" postForm: "Formulari de publicació" textCount: "Nombre de caràcters " +information: "Informació" _emojiPalette: palettes: "Calaixos d'emojis" enableSyncBetweenDevicesForPalettes: "Activa la sincronització dels calaixos d'emojis entre dispositius" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Assegura't que qui distribueix aquest recurs és fiable abans d'instal·lar-ho." _plugin: title: "Vols instal·lar aquest afegit?" - metaTitle: "Informació de l'afegit " _theme: title: "Vols instal·lar aquest tema?" - metaTitle: "Informació del tema" _meta: base: "Paleta de colors base" _vendorInfo: diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index a509280862..11ad97c3a5 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -169,6 +169,9 @@ addAccount: "Přidat účet" reloadAccountsList: "Obnovit list účtů" loginFailed: "Přihlášení se nezdařilo." showOnRemote: "Více na původním profilu" +continueOnRemote: "Pokračujte na původní profil" +chooseServerOnMisskeyHub: "Vyberete si server z Misskey Hubu" +inputHostName: "Zadejte doménu" general: "Obecně" wallpaper: "Obrázek na pozadí" setWallpaper: "Nastavení obrázku na pozadí" @@ -193,6 +196,7 @@ perHour: "za hodinu" perDay: "za den" stopActivityDelivery: "Přestat zasílat aktivitu" blockThisInstance: "Blokovat tuto instanci" +silenceThisInstance: "Utišit tuto instanci" operations: "Operace" software: "Software" version: "Verze" @@ -1099,6 +1103,7 @@ flip: "Otočit" lastNDays: "Posledních {n} dnů" surrender: "Zrušit" postForm: "Formulář pro odeslání" +information: "Informace" _delivery: stop: "Suspendováno" _type: diff --git a/locales/de-DE.yml b/locales/de-DE.yml index db692d65e5..c6cc416638 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1309,6 +1309,7 @@ availableRoles: "Verfügbare Rollen" federationSpecified: "Dieser Server arbeitet mit Whitelist-Föderation. Er kann nicht mit anderen als den vom Administrator angegebenen Servern interagieren." federationDisabled: "Föderation ist auf diesem Server deaktiviert. Es ist nicht möglich, mit Benutzern auf anderen Servern zu interagieren." postForm: "Notizfenster" +information: "Über" _settings: webhook: "Webhook" _accountSettings: @@ -2524,10 +2525,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Überprüfe vor Installation die Vertrauenswürdigkeit des Vertreibers." _plugin: title: "Möchtest du dieses Plugin installieren?" - metaTitle: "Plugininformation" _theme: title: "Möchten du dieses Farbschema installieren?" - metaTitle: "Farbschemainfo" _meta: base: "Farbschemavorlage" _vendorInfo: diff --git a/locales/el-GR.yml b/locales/el-GR.yml index be81a824c7..727565ae21 100644 --- a/locales/el-GR.yml +++ b/locales/el-GR.yml @@ -289,6 +289,7 @@ icon: "Εικονίδιο" replies: "Απάντηση" renotes: "Κοινοποίηση σημειώματος" postForm: "Φόρμα δημοσίευσης" +information: "Πληροφορίες" _email: _follow: title: "Έχετε ένα νέο ακόλουθο" diff --git a/locales/en-US.yml b/locales/en-US.yml index 0d2a29edca..79805e65e1 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1317,7 +1317,7 @@ unmarkAsSensitiveConfirm: "Do you want to remove the sensitive designation for t preferences: "Preferences" accessibility: "Accessibility" preferencesProfile: "Preferences profile" -copyPreferenceId: "Copy the proference ID" +copyPreferenceId: "Copy the preference ID" resetToDefaultValue: "Revert to default" overrideByAccount: "Override by the account" untitled: "Untitled" @@ -1334,6 +1334,7 @@ paste: "Paste" emojiPalette: "Emoji palette" postForm: "Posting form" textCount: "Character count" +information: "About" _emojiPalette: palettes: "Palette" enableSyncBetweenDevicesForPalettes: "Enable palette sync between devices" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Make sure the distributor of this resource is trustworthy before installation." _plugin: title: "Do you want to install this plugin?" - metaTitle: "Plugin information" _theme: title: "Do you want to install this theme?" - metaTitle: "Theme information" _meta: base: "Base color scheme" _vendorInfo: @@ -2877,8 +2876,8 @@ _selfXssPrevention: description2: "If you do not understand exactly what you are trying to paste, %cstop working right now and close this window." description3: "For more information, please refer to this. {link}" _followRequest: - recieved: "Received application" - sent: "Sent application" + recieved: "Received request" + sent: "Sent request" _remoteLookupErrors: _federationNotAllowed: title: "Unable to communicate with this server" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 4933b41ddb..cd96d348c3 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -1300,6 +1300,7 @@ target: "Para" federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador." federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores" postForm: "Formulario" +information: "Información" _settings: webhook: "Webhook" _accountSettings: @@ -2521,10 +2522,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Asegúrate de que el distribuidor de este recurso es de confianza antes de proceder a la instalación." _plugin: title: "¿Quieres instalar este plugin?" - metaTitle: "Información del plugin" _theme: title: "¿Quieres instalar este tema?" - metaTitle: "Información del tema" _meta: base: "Esquema de color base" _vendorInfo: diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 6d3a3bb882..4bdcd89422 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -1278,6 +1278,7 @@ lockdown: "Verrouiller" pleaseSelectAccount: "Sélectionner un compte" availableRoles: "Rôles disponibles" postForm: "Formulaire de publication" +information: "Informations" _abuseUserReport: forward: "Transférer" forwardDescription: "Transférer le signalement vers une instance distante en tant qu'anonyme." @@ -2295,10 +2296,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Veuillez confirmer que le distributeur est fiable avant l'installation." _plugin: title: "Voulez-vous installer cette extension ?" - metaTitle: "Informations sur l'extension" _theme: title: "Voulez-vous installer ce thème ?" - metaTitle: "Informations sur le thème" _meta: base: "Palette de couleurs de base" _vendorInfo: diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 62ddc35cad..9a291ca381 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1262,6 +1262,7 @@ modified: "Diubah" thereAreNChanges: "Ada {n} perubahan" prohibitedWordsForNameOfUser: "Kata yang dilarang untuk nama pengguna" postForm: "Buat catatan" +information: "Informasi" _settings: webhook: "Webhook" _abuseUserReport: @@ -2492,10 +2493,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Pastikan sumber dari sumber daya ini terpercaya sebelum melakukan pemasangan." _plugin: title: "Apakah kamu ingin memasang plugin ini?" - metaTitle: "Informasi plugin" _theme: title: "Apakah kamu ingin memasang tema ini?" - metaTitle: "Informasi tema" _meta: base: "Skema warna dasar" _vendorInfo: diff --git a/locales/index.d.ts b/locales/index.d.ts index 6ff2ac1329..94f5179b41 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -5350,6 +5350,10 @@ export interface Locale extends ILocale { * 文字数 */ "textCount": string; + /** + * 情報 + */ + "information": string; /** * チャット */ @@ -10392,20 +10396,12 @@ export interface Locale extends ILocale { * このプラグインをインストールしますか? */ "title": string; - /** - * プラグイン情報 - */ - "metaTitle": string; }; "_theme": { /** * このテーマをインストールしますか? */ "title": string; - /** - * テーマ情報 - */ - "metaTitle": string; }; "_meta": { /** diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 7a39a8c0e6..4d17d0bf7b 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -1334,6 +1334,7 @@ paste: "Incolla" emojiPalette: "Tavolozza emoji" postForm: "Finestra di pubblicazione" textCount: "Il numero di caratteri" +information: "Informazioni" _emojiPalette: palettes: "Tavolozza" enableSyncBetweenDevicesForPalettes: "Attiva la sincronizzazione tra dispositivi" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Prima di installare, assicurati che la fonte sia affidabile." _plugin: title: "Vuoi davvero installare questo componente aggiuntivo?" - metaTitle: "Informazioni sul componente aggiuntivo" _theme: title: "Vuoi davvero installare questa variazione grafica?" - metaTitle: "Informazioni sulla variazione grafica" _meta: base: "Combinazione base di colori" _vendorInfo: diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 687468c81f..6696d7395d 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1333,6 +1333,7 @@ paste: "ペースト" emojiPalette: "絵文字パレット" postForm: "投稿フォーム" textCount: "文字数" +information: "情報" chat: "チャット" individualChat: "個人チャット" individualChat_description: "特定ユーザーとの一対一のチャットができます。" @@ -2757,10 +2758,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "配布元が信頼できるかを確認した上でインストールしてください。" _plugin: title: "このプラグインをインストールしますか?" - metaTitle: "プラグイン情報" _theme: title: "このテーマをインストールしますか?" - metaTitle: "テーマ情報" _meta: base: "基本のカラースキーム" _vendorInfo: diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index ae45379086..9c0bff4f95 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -1312,6 +1312,7 @@ federationDisabled: "このサーバーは連合が無効化されてるで。 confirmOnReact: "ツッコむときに確認とる" reactAreYouSure: "\" {emoji} \" でツッコむ?" postForm: "投稿フォーム" +information: "情報" _settings: webhook: "Webhook" _accountSettings: @@ -2610,10 +2611,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "配ってるとこが信頼できるか確認した上でインストールしてな。" _plugin: title: "このプラグイン、インストールする?" - metaTitle: "プラグイン情報" _theme: title: "このテーマインストールする?" - metaTitle: "テーマ情報" _meta: base: "" _vendorInfo: diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml index ce83ef0e07..8ff11d35d9 100644 --- a/locales/ko-GS.yml +++ b/locales/ko-GS.yml @@ -655,6 +655,7 @@ replies: "답하기" renotes: "리노트" attach: "옇기" surrender: "아이예" +information: "정보" _delivery: stop: "고만 보내예" _type: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 798c371bc2..4a02b0c64a 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1330,6 +1330,7 @@ preferenceSyncConflictChoiceDevice: "장치 설정값" paste: "붙여넣기" emojiPalette: "이모지 팔레트" postForm: "글 입력란" +information: "정보" _emojiPalette: palettes: "팔레트" paletteForMain: "메인으로 사용할 팔레트" @@ -2650,10 +2651,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "제공자를 신뢰할 수 있는 경우에만 설치하십시오." _plugin: title: "이 플러그인을 설치하시겠습니까?" - metaTitle: "플러그인 정보" _theme: title: "이 테마를 설치하시겠습니까?" - metaTitle: "테마 정보" _meta: base: "기본 컬러 스키마" _vendorInfo: diff --git a/locales/lo-LA.yml b/locales/lo-LA.yml index 06acda44be..52b5a28fb2 100644 --- a/locales/lo-LA.yml +++ b/locales/lo-LA.yml @@ -394,6 +394,7 @@ searchByGoogle: "ຄົ້ນຫາ" file: "ໄຟລ໌" replies: "ຕອບ​ກັບ" renotes: "Renote" +information: "ກ່ຽວກັບ" _delivery: stop: "ໂຈະ" _type: diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index 320b9d62ba..e2f6017f20 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -462,6 +462,7 @@ loggedInAsBot: "Momenteel als bot ingelogd" icon: "Avatar" replies: "Antwoord" renotes: "Herdelen" +information: "Over" _delivery: stop: "Opgeschort" _type: diff --git a/locales/no-NO.yml b/locales/no-NO.yml index c1b145cab4..7981360c41 100644 --- a/locales/no-NO.yml +++ b/locales/no-NO.yml @@ -463,6 +463,7 @@ icon: "Avatar" replies: "Svar" renotes: "Renote" surrender: "Avbryt" +information: "Informasjon" _delivery: stop: "Suspendert" _initialAccountSetting: diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index a4538ee7b2..21b715714d 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -1045,6 +1045,7 @@ lastNDays: "W ciągu ostatnich {n} dni" surrender: "Odrzuć" gameRetry: "Spróbuj ponownie" postForm: "Formularz tworzenia wpisu" +information: "Informacje" _delivery: stop: "Zawieszono" _type: diff --git a/locales/pt-PT.yml b/locales/pt-PT.yml index 4511ce662f..2f46eda784 100644 --- a/locales/pt-PT.yml +++ b/locales/pt-PT.yml @@ -1302,6 +1302,7 @@ pleaseSelectAccount: "Selecione uma conta" availableRoles: "Cargos disponíveis" acknowledgeNotesAndEnable: "Ative após compreender as precauções." postForm: "Campo de postagem" +information: "Informações" _settings: webhook: "Webhook" _accountSettings: @@ -2598,10 +2599,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Tenha certeza de que o distribuidor desse recurso é confiável antes da instalação." _plugin: title: "Deseja instalar esse plugin?" - metaTitle: "Informações do plugin" _theme: title: "Deseja instalar esse tema?" - metaTitle: "Informações do tema" _meta: base: "Paleta de cores base" _vendorInfo: diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index 0d43e174a7..5d1459480d 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -646,6 +646,7 @@ show: "Arată" icon: "Avatar" replies: "Răspunde" renotes: "Re-notează" +information: "Despre" _delivery: stop: "Suspendat" _type: diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 2a200deac0..33a09d198a 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -1182,6 +1182,7 @@ alwaysConfirmFollow: "Всегда подтверждать подписку" inquiry: "Связаться" messageToFollower: "Сообщение подписчикам" postForm: "Форма отправки" +information: "Описание" _settings: webhook: "Вебхук" _delivery: diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index 7ae264081f..cc8ef9298a 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -918,6 +918,7 @@ sourceCode: "Zdrojový kód" flip: "Preklopiť" lastNDays: "Posledných {n} dní" postForm: "Napísať poznámku" +information: "Informácie" _delivery: stop: "Zmrazené" _type: diff --git a/locales/sv-SE.yml b/locales/sv-SE.yml index 91413e3bc7..c740ab1c0c 100644 --- a/locales/sv-SE.yml +++ b/locales/sv-SE.yml @@ -562,6 +562,7 @@ inquiry: "Kontakt" tryAgain: "Försök igen senare" signinWithPasskey: "Logga in med nyckel" unknownWebAuthnKey: "Okänd nyckel" +information: "Om" _delivery: stop: "Suspenderad" _type: diff --git a/locales/th-TH.yml b/locales/th-TH.yml index 939b0d7269..784e9049dd 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -1293,6 +1293,7 @@ prohibitedWordsForNameOfUserDescription: "หากมีสตริงใด yourNameContainsProhibitedWords: "ชื่อของคุณนั้นมีคำที่ต้องห้าม" yourNameContainsProhibitedWordsDescription: "ถ้าหากคุณต้องการใช้ชื่อนี้ กรุณาติดต่อผู้ดูแลระบบของเซิร์ฟเวอร์นะค่ะ" postForm: "แบบฟอร์มการโพสต์" +information: "เกี่ยวกับ" _settings: webhook: "Webhook" _abuseUserReport: @@ -2572,10 +2573,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "โปรดตรวจสอบให้แน่ใจว่าแหล่งแจกหน่ายมีความน่าเชื่อถือก่อนทำการติดตั้ง" _plugin: title: "ต้องการติดตั้งปลั๊กอินนี้ใช่ไหม?" - metaTitle: "ข้อมูลส่วนเสริม" _theme: title: "ต้องการติดตั้งธีมนี้ใช่ไหม?" - metaTitle: "ข้อมูลธีม" _meta: base: "โทนสีพื้นฐาน" _vendorInfo: diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 3e068127f5..a63e39eff4 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -910,6 +910,7 @@ sourceCode: "Вихідний код" flip: "Перевернути" lastNDays: "Останні {n} днів" postForm: "Створення нотатки" +information: "Інформація" _delivery: stop: "Призупинено" _type: diff --git a/locales/uz-UZ.yml b/locales/uz-UZ.yml index c70802e417..d5b7d4b770 100644 --- a/locales/uz-UZ.yml +++ b/locales/uz-UZ.yml @@ -841,6 +841,7 @@ icon: "Avatar" replies: "Javob berish" renotes: "Qayta qayd etish" flip: "Teskari" +information: "Haqida" _delivery: stop: "To'xtatilgan" _type: diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index d2107eaba4..8edcebcd08 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -1120,6 +1120,7 @@ cwNotationRequired: "Nếu \"Ẩn nội dung\" được bật thì cần phải lastNDays: "{n} ngày trước" surrender: "Từ chối" postForm: "Mẫu đăng" +information: "Giới thiệu" _delivery: stop: "Đã vô hiệu hóa" _type: diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 444ba8bc52..ad3eebfebd 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -1334,6 +1334,7 @@ paste: "粘贴" emojiPalette: "表情符号调色板" postForm: "投稿窗口" textCount: "字数" +information: "关于" _emojiPalette: palettes: "调色板" enableSyncBetweenDevicesForPalettes: "启用调色板的设备间同步" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "请在安装前确保来源可靠" _plugin: title: "要安装此插件吗?" - metaTitle: "插件信息" _theme: title: "要安装此主题吗?" - metaTitle: "主题信息" _meta: base: "基本配色方案" _vendorInfo: diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 2ea4ae8168..0de267688c 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1334,6 +1334,7 @@ paste: "貼上" emojiPalette: "表情符號調色盤" postForm: "發文視窗" textCount: "字數" +information: "關於" _emojiPalette: palettes: "調色盤" enableSyncBetweenDevicesForPalettes: "啟用裝置與裝置之間的調色盤同步化" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "安裝前請確認提供者是可信賴的。" _plugin: title: "要安裝此外掛嘛?" - metaTitle: "外掛資訊" _theme: title: "要安裝此佈景主題嗎?" - metaTitle: "佈景主題資訊" _meta: base: "基本配色方案" _vendorInfo: diff --git a/package.json b/package.json index f43c8fc391..51422b3638 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2025.3.2-beta.4", + "version": "2025.3.2-beta.6", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/backend/src/core/WebhookTestService.ts b/packages/backend/src/core/WebhookTestService.ts index f83dec67bf..e1a7801bb1 100644 --- a/packages/backend/src/core/WebhookTestService.ts +++ b/packages/backend/src/core/WebhookTestService.ts @@ -7,42 +7,16 @@ import { Injectable } from '@nestjs/common'; import { MiAbuseUserReport, MiNote, MiUser, MiWebhook } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWebhook.js'; -import { AbuseReportPayload, SystemWebhookPayload, SystemWebhookService } from '@/core/SystemWebhookService.js'; -import { Packed } from '@/misc/json-schema.js'; +import { type AbuseReportPayload, SystemWebhookPayload, SystemWebhookService } from '@/core/SystemWebhookService.js'; +import { type Packed } from '@/misc/json-schema.js'; import { type WebhookEventTypes } from '@/models/Webhook.js'; +import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js'; import { QueueService } from '@/core/QueueService.js'; import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js'; const oneDayMillis = 24 * 60 * 60 * 1000; -function generateAbuseReport(override?: Partial): AbuseReportPayload { - const result: MiAbuseUserReport = { - id: 'dummy-abuse-report1', - targetUserId: 'dummy-target-user', - targetUser: null, - reporterId: 'dummy-reporter-user', - reporter: null, - assigneeId: null, - assignee: null, - resolved: false, - forwarded: false, - comment: 'This is a dummy report for testing purposes.', - targetUserHost: null, - reporterHost: null, - resolvedAs: null, - moderationNote: 'foo', - ...override, - }; - - return { - ...result, - targetUser: result.targetUser ? toPackedUserLite(result.targetUser) : null, - reporter: result.reporter ? toPackedUserLite(result.reporter) : null, - assignee: result.assignee ? toPackedUserLite(result.assignee) : null, - }; -} - function generateDummyUser(override?: Partial): MiUser { return { id: 'dummy-user-1', @@ -134,124 +108,6 @@ function generateDummyNote(override?: Partial): MiNote { }; } -function toPackedNote(note: MiNote, detail = true, override?: Packed<'Note'>): Packed<'Note'> { - return { - id: note.id, - createdAt: new Date().toISOString(), - deletedAt: null, - text: note.text, - cw: note.cw, - userId: note.userId, - user: toPackedUserLite(note.user ?? generateDummyUser()), - replyId: note.replyId, - renoteId: note.renoteId, - isHidden: false, - visibility: note.visibility, - mentions: note.mentions, - visibleUserIds: note.visibleUserIds, - fileIds: note.fileIds, - files: [], - tags: note.tags, - poll: null, - emojis: note.emojis, - channelId: note.channelId, - channel: note.channel, - localOnly: note.localOnly, - reactionAcceptance: note.reactionAcceptance, - reactionEmojis: {}, - reactions: {}, - reactionCount: 0, - renoteCount: note.renoteCount, - repliesCount: note.repliesCount, - uri: note.uri ?? undefined, - url: note.url ?? undefined, - reactionAndUserPairCache: note.reactionAndUserPairCache, - ...(detail ? { - clippedCount: note.clippedCount, - reply: note.reply ? toPackedNote(note.reply, false) : null, - renote: note.renote ? toPackedNote(note.renote, true) : null, - myReaction: null, - } : {}), - ...override, - }; -} - -function toPackedUserLite(user: MiUser, override?: Packed<'UserLite'>): Packed<'UserLite'> { - return { - id: user.id, - name: user.name, - username: user.username, - host: user.host, - avatarUrl: user.avatarUrl, - avatarBlurhash: user.avatarBlurhash, - avatarDecorations: user.avatarDecorations.map(it => ({ - id: it.id, - angle: it.angle, - flipH: it.flipH, - url: 'https://example.com/dummy-image001.png', - offsetX: it.offsetX, - offsetY: it.offsetY, - })), - isBot: user.isBot, - isCat: user.isCat, - emojis: user.emojis, - onlineStatus: 'active', - badgeRoles: [], - ...override, - }; -} - -function toPackedUserDetailedNotMe(user: MiUser, override?: Packed<'UserDetailedNotMe'>): Packed<'UserDetailedNotMe'> { - return { - ...toPackedUserLite(user), - url: null, - uri: null, - movedTo: null, - alsoKnownAs: [], - createdAt: new Date().toISOString(), - updatedAt: user.updatedAt?.toISOString() ?? null, - lastFetchedAt: user.lastFetchedAt?.toISOString() ?? null, - bannerUrl: user.bannerUrl, - bannerBlurhash: user.bannerBlurhash, - isLocked: user.isLocked, - isSilenced: false, - isSuspended: user.isSuspended, - description: null, - location: null, - birthday: null, - lang: null, - fields: [], - verifiedLinks: [], - followersCount: user.followersCount, - followingCount: user.followingCount, - notesCount: user.notesCount, - pinnedNoteIds: [], - pinnedNotes: [], - pinnedPageId: null, - pinnedPage: null, - publicReactions: true, - followersVisibility: 'public', - followingVisibility: 'public', - twoFactorEnabled: false, - usePasswordLessLogin: false, - securityKeys: false, - roles: [], - memo: null, - moderationNote: undefined, - isFollowing: false, - isFollowed: false, - hasPendingFollowRequestFromYou: false, - hasPendingFollowRequestToYou: false, - isBlocking: false, - isBlocked: false, - isMuted: false, - isRenoteMuted: false, - notify: 'none', - withReplies: true, - ...override, - }; -} - const dummyUser1 = generateDummyUser(); const dummyUser2 = generateDummyUser({ id: 'dummy-user-2', @@ -284,6 +140,7 @@ export class WebhookTestService { }; constructor( + private customEmojiService: CustomEmojiService, private userWebhookService: UserWebhookService, private systemWebhookService: SystemWebhookService, private queueService: QueueService, @@ -354,31 +211,31 @@ export class WebhookTestService { switch (params.type) { case 'note': { - send('note', { note: toPackedNote(dummyNote1) }); + send('note', { note: await this.toPackedNote(dummyNote1) }); break; } case 'reply': { - send('reply', { note: toPackedNote(dummyReply1) }); + send('reply', { note: await this.toPackedNote(dummyReply1) }); break; } case 'renote': { - send('renote', { note: toPackedNote(dummyRenote1) }); + send('renote', { note: await this.toPackedNote(dummyRenote1) }); break; } case 'mention': { - send('mention', { note: toPackedNote(dummyMention1) }); + send('mention', { note: await this.toPackedNote(dummyMention1) }); break; } case 'follow': { - send('follow', { user: toPackedUserDetailedNotMe(dummyUser1) }); + send('follow', { user: await this.toPackedUserDetailedNotMe(dummyUser1) }); break; } case 'followed': { - send('followed', { user: toPackedUserLite(dummyUser2) }); + send('followed', { user: await this.toPackedUserLite(dummyUser2) }); break; } case 'unfollow': { - send('unfollow', { user: toPackedUserDetailedNotMe(dummyUser3) }); + send('unfollow', { user: await this.toPackedUserDetailedNotMe(dummyUser3) }); break; } // まだ実装されていない (#9485) @@ -427,7 +284,7 @@ export class WebhookTestService { switch (params.type) { case 'abuseReport': { - send('abuseReport', generateAbuseReport({ + send('abuseReport', await this.generateAbuseReport({ targetUserId: dummyUser1.id, targetUser: dummyUser1, reporterId: dummyUser2.id, @@ -436,7 +293,7 @@ export class WebhookTestService { break; } case 'abuseReportResolved': { - send('abuseReportResolved', generateAbuseReport({ + send('abuseReportResolved', await this.generateAbuseReport({ targetUserId: dummyUser1.id, targetUser: dummyUser1, reporterId: dummyUser2.id, @@ -448,7 +305,7 @@ export class WebhookTestService { break; } case 'userCreated': { - send('userCreated', toPackedUserLite(dummyUser1)); + send('userCreated', await this.toPackedUserLite(dummyUser1)); break; } case 'inactiveModeratorsWarning': { @@ -474,4 +331,153 @@ export class WebhookTestService { } } } + + @bindThis + private async generateAbuseReport(override?: Partial): Promise { + const result: MiAbuseUserReport = { + id: 'dummy-abuse-report1', + targetUserId: 'dummy-target-user', + targetUser: null, + reporterId: 'dummy-reporter-user', + reporter: null, + assigneeId: null, + assignee: null, + resolved: false, + forwarded: false, + comment: 'This is a dummy report for testing purposes.', + targetUserHost: null, + reporterHost: null, + resolvedAs: null, + moderationNote: 'foo', + ...override, + }; + + return { + ...result, + targetUser: result.targetUser ? await this.toPackedUserLite(result.targetUser) : null, + reporter: result.reporter ? await this.toPackedUserLite(result.reporter) : null, + assignee: result.assignee ? await this.toPackedUserLite(result.assignee) : null, + }; + } + + @bindThis + private async toPackedNote(note: MiNote, detail = true, override?: Packed<'Note'>): Promise> { + return { + id: note.id, + createdAt: new Date().toISOString(), + deletedAt: null, + text: note.text, + cw: note.cw, + userId: note.userId, + user: await this.toPackedUserLite(note.user ?? generateDummyUser()), + replyId: note.replyId, + renoteId: note.renoteId, + isHidden: false, + visibility: note.visibility, + mentions: note.mentions, + visibleUserIds: note.visibleUserIds, + fileIds: note.fileIds, + files: [], + tags: note.tags, + poll: null, + emojis: await this.customEmojiService.populateEmojis(note.emojis, note.userHost), + channelId: note.channelId, + channel: note.channel, + localOnly: note.localOnly, + reactionAcceptance: note.reactionAcceptance, + reactionEmojis: {}, + reactions: {}, + reactionCount: 0, + renoteCount: note.renoteCount, + repliesCount: note.repliesCount, + uri: note.uri ?? undefined, + url: note.url ?? undefined, + reactionAndUserPairCache: note.reactionAndUserPairCache, + ...(detail ? { + clippedCount: note.clippedCount, + reply: note.reply ? await this.toPackedNote(note.reply, false) : null, + renote: note.renote ? await this.toPackedNote(note.renote, true) : null, + myReaction: null, + } : {}), + ...override, + }; + } + + @bindThis + private async toPackedUserLite(user: MiUser, override?: Packed<'UserLite'>): Promise> { + return { + id: user.id, + name: user.name, + username: user.username, + host: user.host, + avatarUrl: user.avatarUrl, + avatarBlurhash: user.avatarBlurhash, + avatarDecorations: user.avatarDecorations.map(it => ({ + id: it.id, + angle: it.angle, + flipH: it.flipH, + url: 'https://example.com/dummy-image001.png', + offsetX: it.offsetX, + offsetY: it.offsetY, + })), + isBot: user.isBot, + isCat: user.isCat, + emojis: await this.customEmojiService.populateEmojis(user.emojis, user.host), + onlineStatus: 'active', + badgeRoles: [], + ...override, + }; + } + + @bindThis + private async toPackedUserDetailedNotMe(user: MiUser, override?: Packed<'UserDetailedNotMe'>): Promise> { + return { + ...await this.toPackedUserLite(user), + url: null, + uri: null, + movedTo: null, + alsoKnownAs: [], + createdAt: new Date().toISOString(), + updatedAt: user.updatedAt?.toISOString() ?? null, + lastFetchedAt: user.lastFetchedAt?.toISOString() ?? null, + bannerUrl: user.bannerUrl, + bannerBlurhash: user.bannerBlurhash, + isLocked: user.isLocked, + isSilenced: false, + isSuspended: user.isSuspended, + description: null, + location: null, + birthday: null, + lang: null, + fields: [], + verifiedLinks: [], + followersCount: user.followersCount, + followingCount: user.followingCount, + notesCount: user.notesCount, + pinnedNoteIds: [], + pinnedNotes: [], + pinnedPageId: null, + pinnedPage: null, + publicReactions: true, + followersVisibility: 'public', + followingVisibility: 'public', + twoFactorEnabled: false, + usePasswordLessLogin: false, + securityKeys: false, + roles: [], + memo: null, + moderationNote: undefined, + isFollowing: false, + isFollowed: false, + hasPendingFollowRequestFromYou: false, + hasPendingFollowRequestToYou: false, + isBlocking: false, + isBlocked: false, + isMuted: false, + isRenoteMuted: false, + notify: 'none', + withReplies: true, + ...override, + }; + } } diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index 541badd46c..9440cf8f52 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -171,6 +171,7 @@ export interface Schema extends OfSchema { readonly maximum?: number; readonly minimum?: number; readonly pattern?: string; + readonly additionalProperties?: Schema | boolean; } type RequiredPropertyNames = { @@ -222,7 +223,14 @@ type ObjectSchemaTypeDef

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

= NullOrUndefined>; diff --git a/packages/backend/test/unit/WebhookTestService.ts b/packages/backend/test/unit/WebhookTestService.ts index 45bc932469..736aac40b4 100644 --- a/packages/backend/test/unit/WebhookTestService.ts +++ b/packages/backend/test/unit/WebhookTestService.ts @@ -14,6 +14,7 @@ import { MiSystemWebhook, MiUser, MiWebhook, UserProfilesRepository, UsersReposi import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; import { QueueService } from '@/core/QueueService.js'; +import { CustomEmojiService } from '@/core/CustomEmojiService.js'; describe('WebhookTestService', () => { let app: TestingModule; @@ -56,6 +57,11 @@ describe('WebhookTestService', () => { providers: [ WebhookTestService, IdService, + { + provide: CustomEmojiService, useFactory: () => ({ + populateEmojis: jest.fn(), + }), + }, { provide: QueueService, useFactory: () => ({ systemWebhookDeliver: jest.fn(), diff --git a/packages/frontend-embed/src/components/EmImgWithBlurhash.vue b/packages/frontend-embed/src/components/EmImgWithBlurhash.vue index bf976c71ae..0bff048ce4 100644 --- a/packages/frontend-embed/src/components/EmImgWithBlurhash.vue +++ b/packages/frontend-embed/src/components/EmImgWithBlurhash.vue @@ -33,13 +33,11 @@ const canvasPromise = new Promise(resol Math.min(navigator.hardwareConcurrency - 1, 4), ); resolve(workers); - if (_DEV_) console.log('WebGL2 in worker is supported!'); } else { const canvas = document.createElement('canvas'); canvas.width = 64; canvas.height = 64; resolve(canvas); - if (_DEV_) console.log('WebGL2 in worker is not supported...'); } testWorker.terminate(); }); diff --git a/packages/frontend/eslint.config.js b/packages/frontend/eslint.config.js index 8aa70c66a2..e3fba65197 100644 --- a/packages/frontend/eslint.config.js +++ b/packages/frontend/eslint.config.js @@ -50,9 +50,40 @@ export default [ // defineExposeが誤検知されてしまう '@typescript-eslint/no-unused-expressions': 'off', 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], - // window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため - // e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため - 'id-denylist': ['error', 'window', 'e'], + // window ... グローバルスコープと衝突し、予期せぬ結果を招くため + // e ... error や event など、複数のキーワードの頭文字であり分かりにくいため + // close ... window.closeと衝突 or 紛らわしい + // open ... window.openと衝突 or 紛らわしい + // fetch ... window.fetchと衝突 or 紛らわしい + // location ... window.locationと衝突 or 紛らわしい + 'id-denylist': ['warn', 'window', 'e', 'close', 'open', 'fetch', 'location'], + 'no-restricted-globals': [ + 'error', + { + 'name': 'open', + 'message': 'Use `window.open`.', + }, + { + 'name': 'close', + 'message': 'Use `window.close`.', + }, + { + 'name': 'fetch', + 'message': 'Use `window.fetch`.', + }, + { + 'name': 'location', + 'message': 'Use `window.location`.', + }, + { + 'name': 'history', + 'message': 'Use `window.history`.', + }, + { + 'name': 'name', + 'message': 'Use `window.name`. もしくは name という変数名を定義し忘れている', + }, + ], 'no-shadow': ['warn'], 'vue/attributes-order': ['error', { alphabetical: false, diff --git a/packages/frontend/src/_boot_.ts b/packages/frontend/src/_boot_.ts index c90cc6bdd0..3241f2dc92 100644 --- a/packages/frontend/src/_boot_.ts +++ b/packages/frontend/src/_boot_.ts @@ -12,9 +12,9 @@ import '@/style.scss'; import { mainBoot } from '@/boot/main-boot.js'; import { subBoot } from '@/boot/sub-boot.js'; -const subBootPaths = ['/share', '/auth', '/miauth', '/oauth', '/signup-complete']; +const subBootPaths = ['/share', '/auth', '/miauth', '/oauth', '/signup-complete', '/install-extensions']; -if (subBootPaths.some(i => location.pathname === i || location.pathname.startsWith(i + '/'))) { +if (subBootPaths.some(i => window.location.pathname === i || window.location.pathname.startsWith(i + '/'))) { subBoot(); } else { mainBoot(); diff --git a/packages/frontend/src/accounts.ts b/packages/frontend/src/accounts.ts index dbeb13eb63..a25f3c51d1 100644 --- a/packages/frontend/src/accounts.ts +++ b/packages/frontend/src/accounts.ts @@ -191,7 +191,7 @@ export async function login(token: AccountWithToken['token'], redirect?: string) // 他のタブは再読み込みするだけ reloadChannel.postMessage(null); // このページはredirectで指定された先に移動 - location.href = redirect; + window.location.href = redirect; return; } diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index a520be9f8a..75b74b41f8 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -98,14 +98,14 @@ export async function common(createVue: () => App) { document.addEventListener('touchend', () => {}, { passive: true }); // URLに#pswpを含む場合は取り除く - if (location.hash === '#pswp') { - history.replaceState(null, '', location.href.replace('#pswp', '')); + if (window.location.hash === '#pswp') { + window.history.replaceState(null, '', window.location.href.replace('#pswp', '')); } // 一斉リロード reloadChannel.addEventListener('message', path => { - if (path !== null) location.href = path; - else location.reload(); + if (path !== null) window.location.href = path; + else window.location.reload(); }); // If mobile, insert the viewport meta tag @@ -130,11 +130,11 @@ export async function common(createVue: () => App) { }); //#region loginId - const params = new URLSearchParams(location.search); + const params = new URLSearchParams(window.location.search); const loginId = params.get('loginId'); if (loginId) { - const target = getUrlWithoutLoginId(location.href); + const target = getUrlWithoutLoginId(window.location.href); if (!$i || $i.id !== loginId) { const account = await getAccountFromId(loginId); @@ -143,7 +143,7 @@ export async function common(createVue: () => App) { } } - history.replaceState({ misskey: 'loginId' }, '', target); + window.history.replaceState({ misskey: 'loginId' }, '', target); } //#endregion @@ -300,24 +300,26 @@ export async function common(createVue: () => App) { removeSplash(); //#region Self-XSS 対策メッセージ - console.log( - `%c${i18n.ts._selfXssPrevention.warning}`, - 'color: #f00; background-color: #ff0; font-size: 36px; padding: 4px;', - ); - console.log( - `%c${i18n.ts._selfXssPrevention.title}`, - 'color: #f00; font-weight: 900; font-family: "Hiragino Sans W9", "Hiragino Kaku Gothic ProN", sans-serif; font-size: 24px;', - ); - console.log( - `%c${i18n.ts._selfXssPrevention.description1}`, - 'font-size: 16px; font-weight: 700;', - ); - console.log( - `%c${i18n.ts._selfXssPrevention.description2}`, - 'font-size: 16px;', - 'font-size: 20px; font-weight: 700; color: #f00;', - ); - console.log(i18n.tsx._selfXssPrevention.description3({ link: 'https://misskey-hub.net/docs/for-users/resources/self-xss/' })); + if (!_DEV_) { + console.log( + `%c${i18n.ts._selfXssPrevention.warning}`, + 'color: #f00; background-color: #ff0; font-size: 36px; padding: 4px;', + ); + console.log( + `%c${i18n.ts._selfXssPrevention.title}`, + 'color: #f00; font-weight: 900; font-family: "Hiragino Sans W9", "Hiragino Kaku Gothic ProN", sans-serif; font-size: 24px;', + ); + console.log( + `%c${i18n.ts._selfXssPrevention.description1}`, + 'font-size: 16px; font-weight: 700;', + ); + console.log( + `%c${i18n.ts._selfXssPrevention.description2}`, + 'font-size: 16px;', + 'font-size: 20px; font-weight: 700; color: #f00;', + ); + console.log(i18n.tsx._selfXssPrevention.description3({ link: 'https://misskey-hub.net/docs/for-users/resources/self-xss/' })); + } //#endregion return { diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index 62ee0c5d72..f7360a7340 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -43,7 +43,7 @@ export async function mainBoot() { if (!$i) uiStyle = 'visitor'; if (searchParams.has('zen')) uiStyle = 'zen'; - if (uiStyle === 'deck' && prefer.s['deck.useSimpleUiForNonRootPages'] && location.pathname !== '/') uiStyle = 'zen'; + if (uiStyle === 'deck' && prefer.s['deck.useSimpleUiForNonRootPages'] && window.location.pathname !== '/') uiStyle = 'zen'; if (searchParams.has('ui')) uiStyle = searchParams.get('ui'); @@ -216,7 +216,7 @@ export async function mainBoot() { let reloadDialogShowing = false; stream.on('_disconnected_', async () => { if (prefer.s.serverDisconnectedBehavior === 'reload') { - location.reload(); + window.location.reload(); } else if (prefer.s.serverDisconnectedBehavior === 'dialog') { if (reloadDialogShowing) return; reloadDialogShowing = true; @@ -227,7 +227,7 @@ export async function mainBoot() { }); reloadDialogShowing = false; if (!canceled) { - location.reload(); + window.location.reload(); } } }); @@ -458,7 +458,7 @@ export async function mainBoot() { const latestDonationInfoShownAt = miLocalStorage.getItem('latestDonationInfoShownAt'); const neverShowDonationInfo = miLocalStorage.getItem('neverShowDonationInfo'); - if (neverShowDonationInfo !== 'true' && (createdAt.getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !location.pathname.startsWith('/miauth')) { + if (neverShowDonationInfo !== 'true' && (createdAt.getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !window.location.pathname.startsWith('/miauth')) { if (latestDonationInfoShownAt == null || (new Date(latestDonationInfoShownAt).getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 30)))) { const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDonation.vue')), {}, { closed: () => dispose(), diff --git a/packages/frontend/src/components/MkAnimBg.vue b/packages/frontend/src/components/MkAnimBg.vue index 2938645557..e57fbcdee3 100644 --- a/packages/frontend/src/components/MkAnimBg.vue +++ b/packages/frontend/src/components/MkAnimBg.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> @@ -112,13 +150,13 @@ const emits = defineEmits<{ .extInstallerRoot { border-radius: var(--MI-radius); background: var(--MI_THEME-panel); - padding: 1.5rem; + padding: 20px; } .extInstallerIconWrapper { width: 48px; height: 48px; - font-size: 24px; + font-size: 20px; line-height: 48px; text-align: center; border-radius: 50%; @@ -135,10 +173,6 @@ const emits = defineEmits<{ margin: 0; } -.extInstallerNormDesc { - text-align: center; -} - .extInstallerKVList { margin-top: 0; margin-bottom: 0; diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue index b86aca19fd..420e5e392f 100644 --- a/packages/frontend/src/components/MkImgWithBlurhash.vue +++ b/packages/frontend/src/components/MkImgWithBlurhash.vue @@ -69,13 +69,11 @@ const canvasPromise = new Promise(resol Math.min(navigator.hardwareConcurrency - 1, 4), ); resolve(workers); - if (_DEV_) console.log('WebGL2 in worker is supported!'); } else { const canvas = document.createElement('canvas'); canvas.width = 64; canvas.height = 64; resolve(canvas); - if (_DEV_) console.log('WebGL2 in worker is not supported...'); } testWorker.terminate(); }); diff --git a/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts b/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts index b9d203ee80..bd69fb2f82 100644 --- a/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts +++ b/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts @@ -3,13 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -/* eslint-disable @typescript-eslint/explicit-function-return-type */ -import type { StoryObj } from '@storybook/vue3'; import { HttpResponse, http } from 'msw'; import { federationInstance } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import { getChartResolver } from '../../.storybook/charts.js'; import MkInstanceCardMini from './MkInstanceCardMini.vue'; +import type { StoryObj } from '@storybook/vue3'; export const Default = { render(args) { @@ -48,7 +47,7 @@ export const Default = { const url = new URL(urlStr); if (url.href.startsWith('https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/')) { - const image = await (await fetch(`client-assets/${url.pathname.split('/').pop()}`)).blob(); + const image = await (await window.fetch(`client-assets/${url.pathname.split('/').pop()}`)).blob(); return new HttpResponse(image, { headers: { 'Content-Type': 'image/jpeg', diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 3c066650d9..44a9d14a46 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -183,14 +183,14 @@ onMounted(() => { lightbox?.pswp?.element?.focus({ preventScroll: true, }); - history.pushState(null, '', '#pswp'); + window.history.pushState(null, '', '#pswp'); }); lightbox.on('destroy', () => { focusParent(activeEl, true, false); activeEl = null; if (window.location.hash === '#pswp') { - history.back(); + window.history.back(); } }); diff --git a/packages/frontend/src/components/MkMenu.vue b/packages/frontend/src/components/MkMenu.vue index d16c7465d0..43302f606b 100644 --- a/packages/frontend/src/components/MkMenu.vue +++ b/packages/frontend/src/components/MkMenu.vue @@ -214,7 +214,7 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/components/MkSignupDialog.form.vue b/packages/frontend/src/components/MkSignupDialog.form.vue index 78b6722c1e..65b879235f 100644 --- a/packages/frontend/src/components/MkSignupDialog.form.vue +++ b/packages/frontend/src/components/MkSignupDialog.form.vue @@ -267,7 +267,7 @@ async function onSubmit(): Promise { 'testcaptcha-response': testcaptchaResponse.value, }; - const res = await fetch(`${config.apiUrl}/signup`, { + const res = await window.fetch(`${config.apiUrl}/signup`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/packages/frontend/src/components/global/MkA.vue b/packages/frontend/src/components/global/MkA.vue index 336160ec17..4004db5b12 100644 --- a/packages/frontend/src/components/global/MkA.vue +++ b/packages/frontend/src/components/global/MkA.vue @@ -87,7 +87,7 @@ function openWindow() { function nav(ev: MouseEvent) { if (behavior === 'browser') { - location.href = props.to; + window.location.href = props.to; return; } diff --git a/packages/frontend/src/lib/nirax.ts b/packages/frontend/src/lib/nirax.ts index 8783874bc2..a97803e879 100644 --- a/packages/frontend/src/lib/nirax.ts +++ b/packages/frontend/src/lib/nirax.ts @@ -320,7 +320,7 @@ export class Nirax extends EventEmitter { } const res = this.navigate(fullPath); if (res.route.path === '/:(*)') { - location.href = fullPath; + window.location.href = fullPath; } else { this.emit('push', { beforeFullPath, diff --git a/packages/frontend/src/navbar.ts b/packages/frontend/src/navbar.ts index 7e82eee3b8..d3a8560403 100644 --- a/packages/frontend/src/navbar.ts +++ b/packages/frontend/src/navbar.ts @@ -172,7 +172,7 @@ export const navbarItemDef = reactive({ title: i18n.ts.reload, icon: 'ti ti-refresh', action: (ev) => { - location.reload(); + window.location.reload(); }, }, profile: { diff --git a/packages/frontend/src/pages/auth.vue b/packages/frontend/src/pages/auth.vue index e4699379f0..0dcdc5e9cb 100644 --- a/packages/frontend/src/pages/auth.vue +++ b/packages/frontend/src/pages/auth.vue @@ -64,7 +64,7 @@ function accepted() { if (session.value && session.value.app.callbackUrl) { const url = new URL(session.value.app.callbackUrl); if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:', 'vbscript:'].includes(url.protocol)) throw new Error('invalid url'); - location.href = `${session.value.app.callbackUrl}?token=${session.value.token}`; + window.location.href = `${session.value.app.callbackUrl}?token=${session.value.token}`; } } diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index baae888a94..3b1a845f5b 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -632,7 +632,7 @@ function loadMonoTextures() { src = URL.createObjectURL(monoTextures[mono.img]); monoTextureUrls[mono.img] = src; } else { - const res = await fetch(mono.img); + const res = await window.fetch(mono.img); const blob = await res.blob(); monoTextures[mono.img] = blob; src = URL.createObjectURL(blob); diff --git a/packages/frontend/src/pages/install-extensions.vue b/packages/frontend/src/pages/install-extensions.vue index 95f8c878c9..5963745d87 100644 --- a/packages/frontend/src/pages/install-extensions.vue +++ b/packages/frontend/src/pages/install-extensions.vue @@ -4,14 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only -->