1
1
mirror of https://github.com/kokonect-link/cherrypick synced 2024-11-27 22:38:34 +09:00

Merge remote-branch 'misskey/develop'

This commit is contained in:
NoriDev 2023-12-18 17:41:33 +09:00
commit 88a2966c3b
130 changed files with 2094 additions and 1065 deletions

View File

@ -54,7 +54,7 @@ jobs:
- name: Copy API.json - name: Copy API.json
run: cp packages/backend/built/api.json ${{ matrix.api-json-name }} run: cp packages/backend/built/api.json ${{ matrix.api-json-name }}
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: api-artifact name: api-artifact
path: ${{ matrix.api-json-name }} path: ${{ matrix.api-json-name }}
@ -67,7 +67,7 @@ jobs:
PR_NUMBER: ${{ github.event.number }} PR_NUMBER: ${{ github.event.number }}
run: | run: |
echo "$PR_NUMBER" > ./pr_number echo "$PR_NUMBER" > ./pr_number
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
with: with:
name: api-artifact name: api-artifact
path: pr_number path: pr_number

View File

@ -56,7 +56,7 @@ jobs:
- name: Echo full diff - name: Echo full diff
run: cat ./api-full.json.diff run: cat ./api-full.json.diff
- name: Upload full diff to Artifact - name: Upload full diff to Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: api-artifact name: api-artifact
path: | path: |

View File

@ -108,12 +108,12 @@ jobs:
wait-on: 'http://localhost:61812' wait-on: 'http://localhost:61812'
headed: true headed: true
browser: ${{ matrix.browser }} browser: ${{ matrix.browser }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: ${{ matrix.browser }}-cypress-screenshots name: ${{ matrix.browser }}-cypress-screenshots
path: cypress/screenshots path: cypress/screenshots
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: ${{ matrix.browser }}-cypress-videos name: ${{ matrix.browser }}-cypress-videos

24
.vscode/settings.json vendored
View File

@ -1,11 +1,15 @@
{ {
"search.exclude": { "search.exclude": {
"**/node_modules": true "**/node_modules": true
}, },
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"files.associations": { "files.associations": {
"*.test.ts": "typescript" "*.test.ts": "typescript"
}, },
"jest.jestCommandLine": "pnpm run jest", "jest.jestCommandLine": "pnpm run jest",
"jest.autoRun": "off" "jest.autoRun": "off",
} "editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"editor.formatOnSave": false
}

View File

@ -16,6 +16,7 @@
## 2023.x.x (unreleased) ## 2023.x.x (unreleased)
### Note ### Note
- Node.js 20.10.0が最小要件になりました
- 絵文字ピッカーにピン留め表示する絵文字設定が「リアクション用」と「絵文字入力用」に分かれました。以前の設定は「リアクション用」として使用されます。 - 絵文字ピッカーにピン留め表示する絵文字設定が「リアクション用」と「絵文字入力用」に分かれました。以前の設定は「リアクション用」として使用されます。
**影響:** **影響:**
@ -36,8 +37,10 @@
### Client ### Client
- Feat: 今日誕生日のフォロー中のユーザーを一覧表示できるウィジェットを追加 - Feat: 今日誕生日のフォロー中のユーザーを一覧表示できるウィジェットを追加
- Feat: データセーバーでコードハイライトの読み込みを削減できるように - Feat: 画面に雪を降らせられるように
- Feat: MFMのアニメーション要素`tada`, `jelly`, `twitch`, `shake`, `spin`, `jump`, `bounce`, `rainbow`)に `delay` オプションを追加 - Enhance: MFMのアニメーション要素`tada`, `jelly`, `twitch`, `shake`, `spin`, `jump`, `bounce`, `rainbow`)に `delay` オプションを追加
- Enhance: センシティブと判断されたウェブサイトのサムネイルを非表示に
- ウェブサイトをセンシティブと判断する仕組みが動いていないため、summalyProxyを使用しないと機能しません。
- Enhance: 投稿フォームの絵文字ピッカーをリアクション時に使用するものと同じのを使用するように #12336 #12560 - Enhance: 投稿フォームの絵文字ピッカーをリアクション時に使用するものと同じのを使用するように #12336 #12560
- Enhance: リアクション用ピン留め絵文字と投稿時の絵文字入力用ピン留め絵文字を分けて設定できるように #12560 - Enhance: リアクション用ピン留め絵文字と投稿時の絵文字入力用ピン留め絵文字を分けて設定できるように #12560
- Enhance: 絵文字のオートコンプリート機能強化 #12364 - Enhance: 絵文字のオートコンプリート機能強化 #12364
@ -48,16 +51,21 @@
- Enhance: Shareページで投稿を完了すると、親ウィンドウ親フレームにpostMessageするように - Enhance: Shareページで投稿を完了すると、親ウィンドウ親フレームにpostMessageするように
- Enhance: チャンネル、クリップ、ページ、Play、ギャラリーにURLのコピーボタンを設置 #11305 - Enhance: チャンネル、クリップ、ページ、Play、ギャラリーにURLのコピーボタンを設置 #11305
- Enhance: ノートプレビューに「内容を隠す」が反映されるように - Enhance: ノートプレビューに「内容を隠す」が反映されるように
- Enhance: データセーバーでコードハイライトの読み込みを削減できるように
- Enhance: データセーバーの適用範囲を個別で設定できるように - Enhance: データセーバーの適用範囲を個別で設定できるように
- 従来のデータセーバーの設定はリセットされます - 従来のデータセーバーの設定はリセットされます
- Enhance: タイムライン上のタブからリスト、アンテナ、チャンネルの管理ページにジャンプできるように - Enhance: タイムライン上のタブからリスト、アンテナ、チャンネルの管理ページにジャンプできるように
- Enhance: ユーザー名、プロフィール、お知らせ、ページの編集画面でMFMや絵文字のオートコンプリートが使用できるように - Enhance: ユーザー名、プロフィール、お知らせ、ページの編集画面でMFMや絵文字のオートコンプリートが使用できるように
- Enhance: プロフィール、お知らせの編集画面でMFMのプレビューを表示できるように - Enhance: プロフィール、お知らせの編集画面でMFMのプレビューを表示できるように
- Feat: センシティブと判断されたウェブサイトのサムネイルをぼかすように
- ウェブサイトをセンシティブと判断する仕組みが動いていないため、summalyProxyを使用しないと機能しません。
- fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
- Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
- Enhance: 絵文字の詳細ページに記載される情報を追加 - Enhance: 絵文字の詳細ページに記載される情報を追加
- Enhance: Unicode 15.0のサポート
- Enhance: コードブロックのハイライト機能を利用するには言語を明示的に指定させるように
- MFMでコードブロックを利用する際に意図しないハイライトが起こらないようになりました
- 逆に、MFMでコードハイライトを利用したい際は言語を明示的に指定する必要があります
(例: ` ```js ` → Javascript, ` ```ais ` → AiScript
- Enhance: 絵文字などのオートコンプリートでShift+Tabを押すと前の候補を選択できるように
- Fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
- Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
- Fix: コードエディタが正しく表示されない問題を修正 - Fix: コードエディタが正しく表示されない問題を修正
- Fix: プロフィールの「ファイル」にセンシティブな画像がある際のデザインを修正 - Fix: プロフィールの「ファイル」にセンシティブな画像がある際のデザインを修正
- Fix: 一度に大量の通知が入った際に通知音が音割れする問題を修正 - Fix: 一度に大量の通知が入った際に通知音が音割れする問題を修正
@ -67,6 +75,7 @@
- Fix: セキュリティ向上のためAiScriptの`Mk:apiExternal`を無効化 - Fix: セキュリティ向上のためAiScriptの`Mk:apiExternal`を無効化
- Fix: ノート中の絵文字をタップして「リアクションする」からリアクションした際にリアクションサウンドが鳴らない不具合を修正 - Fix: ノート中の絵文字をタップして「リアクションする」からリアクションした際にリアクションサウンドが鳴らない不具合を修正
- Fix: ノート中のリアクションの表示を微調整 #12650 - Fix: ノート中のリアクションの表示を微調整 #12650
- Fix: AiScriptの`readline`が不正な値を返すことがある問題を修正
### Server ### Server
- Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように - Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように
@ -85,6 +94,8 @@
- Fix: 「みつける」が年越し時に壊れる問題を修正 - Fix: 「みつける」が年越し時に壊れる問題を修正
- Fix: アカウントをブロックした際に、自身のユーザーのページでノートが相手に表示される問題を修正 - Fix: アカウントをブロックした際に、自身のユーザーのページでノートが相手に表示される問題を修正
- Fix: モデレーションログがモデレーターは閲覧できないように修正 - Fix: モデレーションログがモデレーターは閲覧できないように修正
- Fix: HTTP Digestヘッダのアルゴリズム部分に大文字の"SHA-256"しか使えない
- Fix: 管理者用APIのアクセス権限が適切に設定されていない問題を修正
## 2023.11.1 ## 2023.11.1

6
locales/index.d.ts vendored
View File

@ -197,8 +197,8 @@ export interface Locale {
"pinnedEmojisForReactionSettingDescription": string; "pinnedEmojisForReactionSettingDescription": string;
"pinnedEmojisSettingDescription": string; "pinnedEmojisSettingDescription": string;
"emojiPickerDisplay": string; "emojiPickerDisplay": string;
"copyFromPinnedEmojisForReaction": string; "overwriteFromPinnedEmojisForReaction": string;
"copyFromPinnedEmojis": string; "overwriteFromPinnedEmojis": string;
"reactionSettingDescription2": string; "reactionSettingDescription2": string;
"rememberNoteVisibility": string; "rememberNoteVisibility": string;
"attachCancel": string; "attachCancel": string;
@ -1283,6 +1283,8 @@ export interface Locale {
"reloadRequiredToApplySettings": string; "reloadRequiredToApplySettings": string;
"remainingN": string; "remainingN": string;
"overwriteContentConfirm": string; "overwriteContentConfirm": string;
"seasonalScreenEffect": string;
"decorate": string;
"showUnreadNotificationsCount": string; "showUnreadNotificationsCount": string;
"showCatOnly": string; "showCatOnly": string;
"additionalPermissionsForFlash": string; "additionalPermissionsForFlash": string;

View File

@ -194,8 +194,8 @@ emojiPicker: "絵文字ピッカー"
pinnedEmojisForReactionSettingDescription: "リアクション時にピン留め表示する絵文字を設定できます" pinnedEmojisForReactionSettingDescription: "リアクション時にピン留め表示する絵文字を設定できます"
pinnedEmojisSettingDescription: "絵文字入力時にピン留め表示する絵文字を設定できます" pinnedEmojisSettingDescription: "絵文字入力時にピン留め表示する絵文字を設定できます"
emojiPickerDisplay: "ピッカーの表示" emojiPickerDisplay: "ピッカーの表示"
copyFromPinnedEmojisForReaction: "リアクション設定からコピーする" overwriteFromPinnedEmojisForReaction: "リアクション設定から上書きする"
copyFromPinnedEmojis: "絵文字設定からコピーする" overwriteFromPinnedEmojis: "全般設定から上書きする"
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。" reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。"
rememberNoteVisibility: "公開範囲を記憶する" rememberNoteVisibility: "公開範囲を記憶する"
attachCancel: "添付取り消し" attachCancel: "添付取り消し"
@ -1280,6 +1280,8 @@ code: "コード"
reloadRequiredToApplySettings: "設定の反映にはリロードが必要です。" reloadRequiredToApplySettings: "設定の反映にはリロードが必要です。"
remainingN: "残り: {n}" remainingN: "残り: {n}"
overwriteContentConfirm: "現在の内容に上書きされますがよろしいですか?" overwriteContentConfirm: "現在の内容に上書きされますがよろしいですか?"
seasonalScreenEffect: "季節に応じた画面の演出"
decorate: "デコる"
showUnreadNotificationsCount: "未読の通知の数を表示する" showUnreadNotificationsCount: "未読の通知の数を表示する"
showCatOnly: "キャット付きのみ" showCatOnly: "キャット付きのみ"
additionalPermissionsForFlash: "Playへの追加許可" additionalPermissionsForFlash: "Playへの追加許可"

View File

@ -1,13 +1,13 @@
{ {
"name": "cherrypick", "name": "cherrypick",
"version": "4.6.0-beta.4", "version": "4.6.0-beta.4",
"basedMisskeyVersion": "2023.12.0-beta.4", "basedMisskeyVersion": "2023.12.0-beta.5",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/kokonect-link/cherrypick.git" "url": "https://github.com/kokonect-link/cherrypick.git"
}, },
"packageManager": "pnpm@8.10.5", "packageManager": "pnpm@8.12.1",
"workspaces": [ "workspaces": [
"packages/frontend", "packages/frontend",
"packages/backend", "packages/backend",
@ -50,10 +50,10 @@
}, },
"dependencies": { "dependencies": {
"execa": "8.0.1", "execa": "8.0.1",
"cssnano": "6.0.1", "cssnano": "6.0.2",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"postcss": "8.4.32", "postcss": "8.4.32",
"terser": "5.24.0", "terser": "5.26.0",
"typescript": "5.3.3" "typescript": "5.3.3"
}, },
"devDependencies": { "devDependencies": {
@ -61,7 +61,7 @@
"@typescript-eslint/parser": "6.14.0", "@typescript-eslint/parser": "6.14.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"cypress": "13.6.1", "cypress": "13.6.1",
"eslint": "8.55.0", "eslint": "8.56.0",
"start-server-and-test": "2.0.3", "start-server-and-test": "2.0.3",
"ncp": "2.0.0" "ncp": "2.0.0"
}, },

View File

@ -4,7 +4,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"engines": { "engines": {
"node": ">=18.16.0" "node": ">=20.10.0"
}, },
"scripts": { "scripts": {
"start": "node ./built/boot/entry.js", "start": "node ./built/boot/entry.js",
@ -66,7 +66,7 @@
"@bull-board/api": "5.10.2", "@bull-board/api": "5.10.2",
"@bull-board/fastify": "5.10.2", "@bull-board/fastify": "5.10.2",
"@bull-board/ui": "5.10.2", "@bull-board/ui": "5.10.2",
"@discordapp/twemoji": "14.1.2", "@discordapp/twemoji": "15.0.2",
"@fastify/accepts": "4.3.0", "@fastify/accepts": "4.3.0",
"@fastify/cookie": "9.2.0", "@fastify/cookie": "9.2.0",
"@fastify/cors": "8.4.2", "@fastify/cors": "8.4.2",
@ -86,6 +86,7 @@
"@smithy/node-http-handler": "2.1.10", "@smithy/node-http-handler": "2.1.10",
"@swc/cli": "0.1.63", "@swc/cli": "0.1.63",
"@swc/core": "1.3.100", "@swc/core": "1.3.100",
"@twemoji/parser": "15.0.0",
"@vitalets/google-translate-api": "9.2.0", "@vitalets/google-translate-api": "9.2.0",
"accepts": "1.3.8", "accepts": "1.3.8",
"ajv": "8.12.0", "ajv": "8.12.0",
@ -94,7 +95,7 @@
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"blurhash": "2.0.5", "blurhash": "2.0.5",
"body-parser": "1.20.2", "body-parser": "1.20.2",
"bullmq": "4.15.3", "bullmq": "4.15.4",
"cacheable-lookup": "7.0.0", "cacheable-lookup": "7.0.0",
"cbor": "9.0.1", "cbor": "9.0.1",
"chalk": "5.3.0", "chalk": "5.3.0",
@ -113,7 +114,7 @@
"file-type": "18.7.0", "file-type": "18.7.0",
"fluent-ffmpeg": "2.1.2", "fluent-ffmpeg": "2.1.2",
"form-data": "4.0.0", "form-data": "4.0.0",
"got": "13.0.0", "got": "14.0.0",
"happy-dom": "10.0.3", "happy-dom": "10.0.3",
"hpagent": "1.2.0", "hpagent": "1.2.0",
"http-link-header": "1.1.1", "http-link-header": "1.1.1",
@ -127,7 +128,7 @@
"jsonld": "8.3.2", "jsonld": "8.3.2",
"jsrsasign": "10.9.0", "jsrsasign": "10.9.0",
"meilisearch": "0.36.0", "meilisearch": "0.36.0",
"microformats-parser": "1.5.2", "microformats-parser": "2.0.2",
"mime-types": "2.1.35", "mime-types": "2.1.35",
"ms": "3.0.0-canary.1", "ms": "3.0.0-canary.1",
"nanoid": "5.0.4", "nanoid": "5.0.4",
@ -171,7 +172,6 @@
"tmp": "0.2.1", "tmp": "0.2.1",
"tsc-alias": "1.8.8", "tsc-alias": "1.8.8",
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.17", "typeorm": "0.3.17",
"typescript": "5.3.3", "typescript": "5.3.3",
"ulid": "2.3.0", "ulid": "2.3.0",
@ -200,7 +200,7 @@
"@types/jsrsasign": "10.5.12", "@types/jsrsasign": "10.5.12",
"@types/mime-types": "2.1.4", "@types/mime-types": "2.1.4",
"@types/ms": "0.7.34", "@types/ms": "0.7.34",
"@types/node": "20.10.4", "@types/node": "20.10.5",
"@types/node-fetch": "3.0.3", "@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.14", "@types/nodemailer": "6.4.14",
"@types/oauth": "0.9.4", "@types/oauth": "0.9.4",
@ -227,8 +227,8 @@
"@typescript-eslint/parser": "6.14.0", "@typescript-eslint/parser": "6.14.0",
"aws-sdk-client-mock": "3.0.0", "aws-sdk-client-mock": "3.0.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"eslint": "8.55.0", "eslint": "8.56.0",
"eslint-plugin-import": "2.29.0", "eslint-plugin-import": "2.29.1",
"execa": "8.0.1", "execa": "8.0.1",
"jest": "29.7.0", "jest": "29.7.0",
"jest-mock": "29.7.0", "jest-mock": "29.7.0",

File diff suppressed because one or more lines are too long

View File

@ -138,7 +138,7 @@ export class ActivityPubServerService {
return; return;
} }
const algo = match[1]; const algo = match[1].toUpperCase();
const digestValue = match[2]; const digestValue = match[2];
if (algo !== 'SHA-256') { if (algo !== 'SHA-256') {
@ -493,8 +493,7 @@ export class ActivityPubServerService {
@bindThis @bindThis
public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) { public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
// addConstraintStrategy の型定義がおかしいため fastify.addConstraintStrategy({
(fastify.addConstraintStrategy as any)({
name: 'apOrHtml', name: 'apOrHtml',
storage() { storage() {
const store = {} as any; const store = {} as any;

View File

@ -61,6 +61,9 @@ export class FileServerService {
public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) { public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
fastify.addHook('onRequest', (request, reply, done) => { fastify.addHook('onRequest', (request, reply, done) => {
reply.header('Content-Security-Policy', 'default-src \'none\'; img-src \'self\'; media-src \'self\'; style-src \'unsafe-inline\''); reply.header('Content-Security-Policy', 'default-src \'none\'; img-src \'self\'; media-src \'self\'; style-src \'unsafe-inline\'');
if (process.env.NODE_ENV === 'development') {
reply.header('Access-Control-Allow-Origin', '*');
}
done(); done();
}); });

View File

@ -13,6 +13,8 @@ import { AbuseUserReportEntityService } from '@/core/entities/AbuseUserReportEnt
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -15,6 +15,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
res: { res: {
type: 'object', type: 'object',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -14,6 +14,8 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '@/server/api/error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -13,6 +13,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { AnnouncementService } from '@/core/AnnouncementService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -14,6 +14,8 @@ import { IdService } from '@/core/IdService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',
errors: { errors: {

View File

@ -15,6 +15,8 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',

View File

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations', requireRolePolicy: 'canManageAvatarDecorations',

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.j
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -14,6 +14,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -15,6 +15,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -8,7 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueueService } from '@/core/QueueService.js'; import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
secure: true, kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -15,6 +15,8 @@ import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -15,6 +15,8 @@ import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',
} as const; } as const;

View File

@ -17,6 +17,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis', requireRolePolicy: 'canManageCustomEmojis',

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
kind: 'read:admin',
tags: ['admin'], tags: ['admin'],
} as const; } as const;

View File

@ -12,6 +12,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
kind: 'read:admin',
tags: ['admin'], tags: ['admin'],
res: { res: {

View File

@ -12,6 +12,8 @@ import { IdService } from '@/core/IdService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DEFAULT_POLICIES } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['meta'], tags: ['meta'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ApiLoggerService } from '@/server/api/ApiLoggerService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { ApiLoggerService } from '@/server/api/ApiLoggerService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -10,6 +10,8 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, Obj
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { RelayService } from '@/core/RelayService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -10,6 +10,8 @@ import { RelayService } from '@/core/RelayService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -15,6 +15,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -12,6 +12,8 @@ import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'read:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,

View File

@ -11,6 +11,8 @@ import { MetaService } from '@/core/MetaService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = { export const meta = {
tags: ['admin', 'role'], tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,

View File

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
tags: ['admin', 'role', 'users'], tags: ['admin', 'role', 'users'],
kind: 'read:admin',
requireCredential: false, requireCredential: false,
requireAdmin: true, requireAdmin: true,

View File

@ -10,6 +10,8 @@ import { EmailService } from '@/core/EmailService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -17,6 +17,8 @@ export const meta = {
tags: ['admin', 'meta'], tags: ['admin', 'meta'],
kind: 'read:admin',
res: { res: {
type: 'object', type: 'object',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -16,6 +16,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
kind: 'read:admin',
res: { res: {
type: 'array', type: 'array',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -17,6 +17,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
kind: 'read:admin',
res: { res: {
type: 'object', type: 'object',
nullable: false, optional: false, nullable: false, optional: false,

View File

@ -17,6 +17,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
kind: 'read:admin',
res: { res: {
type: 'array', type: 'array',
nullable: false, optional: false, nullable: false, optional: false,

View File

@ -19,6 +19,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -14,6 +14,8 @@ import { ServerStatsService } from '@/daemons/ServerStatsService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireAdmin: true, requireAdmin: true,
} as const; } as const;

View File

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
kind: 'write:admin',
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
} as const; } as const;

View File

@ -51,6 +51,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private cacheService: CacheService, private cacheService: CacheService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const userIdsWhoBlockingMe = me ? await this.cacheService.userBlockedCache.fetch(me.id) : new Set<string>();
// early return if me is blocked by requesting user
if (userIdsWhoBlockingMe.has(ps.userId)) {
return [];
}
let noteIds = await this.featuredService.getPerUserNotesRanking(ps.userId, 50); let noteIds = await this.featuredService.getPerUserNotesRanking(ps.userId, 50);
noteIds.sort((a, b) => a > b ? -1 : 1); noteIds.sort((a, b) => a > b ? -1 : 1);
@ -65,11 +72,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const [ const [
userIdsWhoMeMuting, userIdsWhoMeMuting,
userIdsWhoBlockingMe,
] = me ? await Promise.all([ ] = me ? await Promise.all([
this.cacheService.userMutingsCache.fetch(me.id), this.cacheService.userMutingsCache.fetch(me.id),
this.cacheService.userBlockedCache.fetch(me.id), ]) : [new Set<string>()];
]) : [new Set<string>(), new Set<string>()];
const query = this.notesRepository.createQueryBuilder('note') const query = this.notesRepository.createQueryBuilder('note')
.where('note.id IN (:...noteIds)', { noteIds: noteIds }) .where('note.id IN (:...noteIds)', { noteIds: noteIds })

View File

@ -87,6 +87,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles); if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles);
// early return if me is blocked by requesting user
if (me != null) {
const userIdsWhoBlockingMe = await this.cacheService.userBlockedCache.fetch(me.id);
if (userIdsWhoBlockingMe.has(ps.userId)) {
return [];
}
}
if (!serverSettings.enableFanoutTimeline) { if (!serverSettings.enableFanoutTimeline) {
const timeline = await this.getFromDb({ const timeline = await this.getFromDb({
untilId, untilId,

View File

@ -25,17 +25,17 @@
"@microsoft/api-extractor": "7.38.5", "@microsoft/api-extractor": "7.38.5",
"@swc/jest": "0.2.29", "@swc/jest": "0.2.29",
"@types/jest": "29.5.11", "@types/jest": "29.5.11",
"@types/node": "20.10.4", "@types/node": "20.10.5",
"@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/eslint-plugin": "6.14.0",
"@typescript-eslint/parser": "6.14.0", "@typescript-eslint/parser": "6.14.0",
"eslint": "8.55.0", "eslint": "8.56.0",
"jest": "29.7.0", "jest": "29.7.0",
"jest-fetch-mock": "3.0.3", "jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0", "jest-websocket-mock": "2.5.0",
"mock-socket": "9.3.1", "mock-socket": "9.3.1",
"ncp": "2.0.0", "ncp": "2.0.0",
"nodemon": "3.0.2", "nodemon": "3.0.2",
"tsd": "0.29.0", "tsd": "0.30.0",
"typescript": "5.3.3" "typescript": "5.3.3"
}, },
"files": [ "files": [

View File

@ -25,7 +25,7 @@ export const commonHandlers = [
}), }),
rest.get('/twemoji/:codepoints.svg', async (req, res, ctx) => { rest.get('/twemoji/:codepoints.svg', async (req, res, ctx) => {
const { codepoints } = req.params; const { codepoints } = req.params;
const value = await fetch(`https://unpkg.com/@discordapp/twemoji@14.1.2/dist/svg/${codepoints}.svg`).then((response) => response.blob()); const value = await fetch(`https://unpkg.com/@discordapp/twemoji@15.0.2/dist/svg/${codepoints}.svg`).then((response) => response.blob());
return res(ctx.set('Content-Type', 'image/svg+xml'), ctx.body(value)); return res(ctx.set('Content-Type', 'image/svg+xml'), ctx.body(value));
}), }),
]; ];

View File

@ -17,7 +17,7 @@
"lint": "pnpm typecheck && pnpm eslint" "lint": "pnpm typecheck && pnpm eslint"
}, },
"dependencies": { "dependencies": {
"@discordapp/twemoji": "14.1.2", "@discordapp/twemoji": "15.0.2",
"@fontsource/jetbrains-mono": "^5.0.12", "@fontsource/jetbrains-mono": "^5.0.12",
"@github/webauthn-json": "2.1.1", "@github/webauthn-json": "2.1.1",
"@rollup/plugin-json": "6.1.0", "@rollup/plugin-json": "6.1.0",
@ -25,12 +25,13 @@
"@rollup/pluginutils": "5.1.0", "@rollup/pluginutils": "5.1.0",
"@syuilo/aiscript": "0.16.0", "@syuilo/aiscript": "0.16.0",
"@tabler/icons-webfont": "2.44.0", "@tabler/icons-webfont": "2.44.0",
"@twemoji/parser": "15.0.0",
"@vitejs/plugin-vue": "4.5.2", "@vitejs/plugin-vue": "4.5.2",
"@vue/compiler-sfc": "3.3.11", "@vue/compiler-sfc": "3.3.12",
"astring": "1.8.6",
"autosize": "6.0.1", "autosize": "6.0.1",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6",
"broadcast-channel": "6.0.0", "astring": "1.8.6",
"broadcast-channel": "7.0.0",
"browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3", "browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3",
"buraha": "0.0.1", "buraha": "0.0.1",
"canvas-confetti": "1.6.1", "canvas-confetti": "1.6.1",
@ -48,7 +49,7 @@
"escape-regexp": "0.0.1", "escape-regexp": "0.0.1",
"estree-walker": "3.0.3", "estree-walker": "3.0.3",
"eventemitter3": "5.0.1", "eventemitter3": "5.0.1",
"gsap": "3.12.3", "gsap": "3.12.4",
"idb-keyval": "6.2.1", "idb-keyval": "6.2.1",
"insert-text-at-cursor": "0.3.0", "insert-text-at-cursor": "0.3.0",
"is-file-animated": "1.0.2", "is-file-animated": "1.0.2",
@ -59,10 +60,10 @@
"pretendard-jp": "^1.3.8", "pretendard-jp": "^1.3.8",
"prismjs": "1.29.0", "prismjs": "1.29.0",
"punycode": "2.3.1", "punycode": "2.3.1",
"rollup": "4.9.0", "rollup": "4.9.1",
"sanitize-html": "2.11.0", "sanitize-html": "2.11.0",
"shiki": "0.14.6",
"sass": "1.69.5", "sass": "1.69.5",
"shiki": "0.14.7",
"strict-event-emitter-types": "2.0.0", "strict-event-emitter-types": "2.0.0",
"temml": "0.10.13", "temml": "0.10.13",
"textarea-caret": "3.1.0", "textarea-caret": "3.1.0",
@ -72,41 +73,40 @@
"tinyld": "^1.3.4", "tinyld": "^1.3.4",
"tsc-alias": "1.8.8", "tsc-alias": "1.8.8",
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"twemoji-parser": "14.0.0",
"typescript": "5.3.3", "typescript": "5.3.3",
"uuid": "9.0.1", "uuid": "9.0.1",
"v-code-diff": "1.7.2", "v-code-diff": "1.7.2",
"vite": "5.0.8", "vite": "5.0.10",
"vue": "3.3.11", "vue": "3.3.12",
"vue-prism-editor": "2.0.0-alpha.2", "vue-prism-editor": "2.0.0-alpha.2",
"vuedraggable": "next" "vuedraggable": "next"
}, },
"devDependencies": { "devDependencies": {
"@storybook/addon-actions": "7.6.4", "@storybook/addon-actions": "7.6.5",
"@storybook/addon-essentials": "7.6.4", "@storybook/addon-essentials": "7.6.5",
"@storybook/addon-interactions": "7.6.4", "@storybook/addon-interactions": "7.6.5",
"@storybook/addon-links": "7.6.4", "@storybook/addon-links": "7.6.5",
"@storybook/addon-storysource": "7.6.4", "@storybook/addon-storysource": "7.6.5",
"@storybook/addons": "7.6.4", "@storybook/addons": "7.6.5",
"@storybook/blocks": "7.6.4", "@storybook/blocks": "7.6.5",
"@storybook/core-events": "7.6.4", "@storybook/core-events": "7.6.5",
"@storybook/jest": "0.2.3", "@storybook/jest": "0.2.3",
"@storybook/manager-api": "7.6.4", "@storybook/manager-api": "7.6.5",
"@storybook/preview-api": "7.6.4", "@storybook/preview-api": "7.6.5",
"@storybook/react": "7.6.4", "@storybook/react": "7.6.5",
"@storybook/react-vite": "7.6.4", "@storybook/react-vite": "7.6.5",
"@storybook/testing-library": "0.2.2", "@storybook/testing-library": "0.2.2",
"@storybook/theming": "7.6.4", "@storybook/theming": "7.6.5",
"@storybook/types": "7.6.4", "@storybook/types": "7.6.5",
"@storybook/vue3": "7.6.4", "@storybook/vue3": "7.6.5",
"@storybook/vue3-vite": "7.6.4", "@storybook/vue3-vite": "7.6.5",
"@testing-library/vue": "8.0.1", "@testing-library/vue": "8.0.1",
"@types/autosize": "^4.0.1", "@types/autosize": "^4.0.1",
"@types/escape-regexp": "0.0.3", "@types/escape-regexp": "0.0.3",
"@types/estree": "1.0.5", "@types/estree": "1.0.5",
"@types/matter-js": "0.19.5", "@types/matter-js": "0.19.5",
"@types/micromatch": "4.0.6", "@types/micromatch": "4.0.6",
"@types/node": "20.10.4", "@types/node": "20.10.5",
"@types/prismjs": "^1.26.0", "@types/prismjs": "^1.26.0",
"@types/punycode": "2.1.3", "@types/punycode": "2.1.3",
"@types/sanitize-html": "2.9.5", "@types/sanitize-html": "2.9.5",
@ -117,16 +117,17 @@
"@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/eslint-plugin": "6.14.0",
"@typescript-eslint/parser": "6.14.0", "@typescript-eslint/parser": "6.14.0",
"@vitest/coverage-v8": "0.34.6", "@vitest/coverage-v8": "0.34.6",
"@vue/runtime-core": "3.3.11", "@vue/runtime-core": "3.3.12",
"acorn": "8.11.2", "acorn": "8.11.2",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"cypress": "13.6.1", "cypress": "13.6.1",
"eslint": "8.55.0", "eslint": "8.56.0",
"eslint-plugin-import": "2.29.0", "eslint-plugin-import": "2.29.1",
"eslint-plugin-storybook": "^0.6.13", "eslint-plugin-storybook": "^0.6.13",
"eslint-plugin-vue": "9.19.2", "eslint-plugin-vue": "9.19.2",
"fast-glob": "3.3.2", "fast-glob": "3.3.2",
"happy-dom": "10.0.3", "happy-dom": "10.0.3",
"intersection-observer": "0.12.2",
"micromatch": "4.0.5", "micromatch": "4.0.5",
"msw": "1.3.2", "msw": "1.3.2",
"msw-storybook-addon": "1.10.0", "msw-storybook-addon": "1.10.0",
@ -135,7 +136,7 @@
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"start-server-and-test": "2.0.3", "start-server-and-test": "2.0.3",
"storybook": "7.6.4", "storybook": "7.6.5",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"summaly": "github:misskey-dev/summaly", "summaly": "github:misskey-dev/summaly",
"vite-plugin-turbosnap": "1.0.3", "vite-plugin-turbosnap": "1.0.3",

View File

@ -12,19 +12,16 @@ import { version, basedMisskeyVersion, ui, lang, updateLocale, locale } from '@/
import { applyTheme } from '@/scripts/theme.js'; import { applyTheme } from '@/scripts/theme.js';
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js'; import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js';
import { i18n, updateI18n } from '@/i18n.js'; import { i18n, updateI18n } from '@/i18n.js';
import { confirm, alert, post, popup, toast } from '@/os.js';
import { $i, refreshAccount, login, updateAccount, signout } from '@/account.js'; import { $i, refreshAccount, login, updateAccount, signout } from '@/account.js';
import { defaultStore, ColdDeviceStorage } from '@/store.js'; import { defaultStore, ColdDeviceStorage } from '@/store.js';
import { fetchInstance, instance } from '@/instance.js'; import { fetchInstance, instance } from '@/instance.js';
import { deviceKind } from '@/scripts/device-kind.js'; import { deviceKind } from '@/scripts/device-kind.js';
import { reloadChannel } from '@/scripts/unison-reload.js'; import { reloadChannel } from '@/scripts/unison-reload.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
import { getUrlWithoutLoginId } from '@/scripts/login-id.js'; import { getUrlWithoutLoginId } from '@/scripts/login-id.js';
import { getAccountFromId } from '@/scripts/get-account-from-id.js'; import { getAccountFromId } from '@/scripts/get-account-from-id.js';
import { deckStore } from '@/ui/deck/deck-store.js'; import { deckStore } from '@/ui/deck/deck-store.js';
import { miLocalStorage } from '@/local-storage.js'; import { miLocalStorage } from '@/local-storage.js';
import { fetchCustomEmojis } from '@/custom-emojis.js'; import { fetchCustomEmojis } from '@/custom-emojis.js';
import { mainRouter } from '@/router.js';
export async function common(createVue: () => App<Element>) { export async function common(createVue: () => App<Element>) {
console.info(`CherryPick v${version}`); console.info(`CherryPick v${version}`);

View File

@ -20,6 +20,7 @@ import { mainRouter } from '@/router.js';
import { initializeSw } from '@/scripts/initialize-sw.js'; import { initializeSw } from '@/scripts/initialize-sw.js';
import { deckStore } from '@/ui/deck/deck-store.js'; import { deckStore } from '@/ui/deck/deck-store.js';
import { emojiPicker } from '@/scripts/emoji-picker.js'; import { emojiPicker } from '@/scripts/emoji-picker.js';
import { SnowfallEffect } from '@/scripts/snowfall-effect.js';
import { userName } from '@/filters/user.js'; import { userName } from '@/filters/user.js';
import { vibrate } from '@/scripts/vibrate.js'; import { vibrate } from '@/scripts/vibrate.js';
@ -78,6 +79,13 @@ export async function mainBoot() {
}, },
}; };
if (defaultStore.state.enableSeasonalScreenEffect) {
const month = new Date().getMonth() + 1;
if (month === 12 || month === 1) {
new SnowfallEffect().render();
}
}
if ($i) { if ($i) {
// only add post shortcuts if logged in // only add post shortcuts if logged in
hotkeys['p|n'] = post; hotkeys['p|n'] = post;

View File

@ -360,12 +360,25 @@ function onKeydown(event: KeyboardEvent) {
} }
break; break;
case 'Tab':
case 'ArrowDown': case 'ArrowDown':
cancel(); cancel();
selectNext(); selectNext();
break; break;
case 'Tab':
if (event.shiftKey) {
if (select.value !== -1) {
cancel();
selectPrev();
} else {
props.close();
}
} else {
cancel();
selectNext();
}
break;
default: default:
event.stopPropagation(); event.stopPropagation();
props.textarea.focus(); props.textarea.focus();

View File

@ -9,7 +9,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkLoading v-if="!inline ?? true"/> <MkLoading v-if="!inline ?? true"/>
</template> </template>
<code v-if="inline" :class="$style.codeInlineRoot">{{ code }}</code> <code v-if="inline" :class="$style.codeInlineRoot">{{ code }}</code>
<XCode v-else-if="show" :code="code" :lang="lang"/> <XCode v-else-if="show && lang" :code="code" :lang="lang"/>
<pre v-else-if="show" :class="$style.codeBlockFallbackRoot"><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
<button v-else :class="$style.codePlaceholderRoot" @click="show = true"> <button v-else :class="$style.codePlaceholderRoot" @click="show = true">
<div :class="$style.codePlaceholderContainer"> <div :class="$style.codePlaceholderContainer">
<div><i class="ti ti-code"></i> {{ i18n.ts.code }}</div> <div><i class="ti ti-code"></i> {{ i18n.ts.code }}</div>
@ -47,6 +48,21 @@ const XCode = defineAsyncComponent(() => import('@/components/MkCode.core.vue'))
border-radius: .3em; border-radius: .3em;
} }
.codeBlockFallbackRoot {
display: block;
overflow-wrap: anywhere;
color: #D4D4D4;
background: #1E1E1E;
padding: 1em;
margin: .5em 0;
overflow: auto;
border-radius: 8px;
}
.codeBlockFallbackCode {
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
}
.codePlaceholderRoot { .codePlaceholderRoot {
display: block; display: block;
width: 100%; width: 100%;

Some files were not shown because too many files have changed in this diff Show More