Merge pull request MisskeyIO#246 from MisskeyIO/merge-upstream

Merge misskey-dev/develop
This commit is contained in:
まっちゃとーにゅ 2023-11-22 07:45:36 +09:00 committed by GitHub
commit 9fb84a2254
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 903 additions and 325 deletions

View file

@ -5,19 +5,34 @@
- -
### Client ### Client
- - Fix: ページ一覧ページの表示がモバイル環境において崩れているのを修正
### Server ### Server
- -
--> -->
## 2023.x.x (unreleased)
### General
- Feat: メールアドレスの認証にverifymail.ioを使えるように (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/971ba07a44550f68d2ba31c62066db2d43a0caed)
- Feat: モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能を追加 (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/e0eb5a752f6e5616d6312bb7c9790302f9dbff83)
### Client
- fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
- Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
### Server
- Fix: 時間経過により無効化されたアンテナを再有効化したとき、サーバ再起動までその状況が反映されないのを修正 #12303
- Fix: ロールタイムラインが保存されない問題を修正
## 2023.11.1 ## 2023.11.1
### General ### General
- Feat: 管理者がコントロールパネルからメールアドレスの照会を行えるようになりました - Feat: 管理者がコントロールパネルからメールアドレスの照会を行えるようになりました
- Enhance: ローカリゼーションの更新 - Enhance: ローカリゼーションの更新
- Enhance: 依存関係の更新 - Enhance: 依存関係の更新
- Enhance: json-schema(OpenAPIの戻り値として使用されるスキーマ定義)を出来る限り最新化 #12311
### Client ### Client
- Enhance: MFMでルビを振れるように - Enhance: MFMでルビを振れるように

View file

@ -566,10 +566,10 @@ output: "Output"
script: "Script" script: "Script"
disablePagesScript: "Disable AiScript on Pages" disablePagesScript: "Disable AiScript on Pages"
updateRemoteUser: "Update remote user information" updateRemoteUser: "Update remote user information"
deleteUserAvatar: "Delete user icon" unsetUserAvatar: "Unset user icon"
deleteUserAvatarConfirm: "Are you sure that you want to delete this user's icon?" unsetUserAvatarConfirm: "Are you sure that you want to unset this user's icon?"
deleteUserBanner: "Delete user banner" unsetUserBanner: "Unset user banner"
deleteUserBannerConfirm: "Are you sure that you want to delete this user's banner?" unsetUserBannerConfirm: "Are you sure that you want to unset this user's banner?"
deleteAllFiles: "Delete all files" deleteAllFiles: "Delete all files"
deleteAllFilesConfirm: "Are you sure that you want to delete all files?" deleteAllFilesConfirm: "Are you sure that you want to delete all files?"
removeAllFollowing: "Unfollow all followed users" removeAllFollowing: "Unfollow all followed users"

10
locales/index.d.ts vendored
View file

@ -569,10 +569,10 @@ export interface Locale {
"script": string; "script": string;
"disablePagesScript": string; "disablePagesScript": string;
"updateRemoteUser": string; "updateRemoteUser": string;
"deleteUserAvatar": string; "unsetUserAvatar": string;
"deleteUserAvatarConfirm": string; "unsetUserAvatarConfirm": string;
"deleteUserBanner": string; "unsetUserBanner": string;
"deleteUserBannerConfirm": string; "unsetUserBannerConfirm": string;
"deleteAllFiles": string; "deleteAllFiles": string;
"deleteAllFilesConfirm": string; "deleteAllFilesConfirm": string;
"removeAllFollowing": string; "removeAllFollowing": string;
@ -2447,6 +2447,8 @@ export interface Locale {
"createAvatarDecoration": string; "createAvatarDecoration": string;
"updateAvatarDecoration": string; "updateAvatarDecoration": string;
"deleteAvatarDecoration": string; "deleteAvatarDecoration": string;
"unsetUserAvatar": string;
"unsetUserBanner": string;
}; };
"_fileViewer": { "_fileViewer": {
"title": string; "title": string;

View file

@ -566,10 +566,10 @@ output: "出力"
script: "スクリプト" script: "スクリプト"
disablePagesScript: "Pagesのスクリプトを無効にする" disablePagesScript: "Pagesのスクリプトを無効にする"
updateRemoteUser: "リモートユーザー情報の更新" updateRemoteUser: "リモートユーザー情報の更新"
deleteUserAvatar: "アイコンを削除" unsetUserAvatar: "アイコンを解除"
deleteUserAvatarConfirm: "アイコンを削除しますか?" unsetUserAvatarConfirm: "アイコンを解除しますか?"
deleteUserBanner: "バナーを削除" unsetUserBanner: "バナーを解除"
deleteUserBannerConfirm: "バナーを削除しますか?" unsetUserBannerConfirm: "バナーを解除しますか?"
deleteAllFiles: "すべてのファイルを削除" deleteAllFiles: "すべてのファイルを削除"
deleteAllFilesConfirm: "すべてのファイルを削除しますか?" deleteAllFilesConfirm: "すべてのファイルを削除しますか?"
removeAllFollowing: "フォローを全解除" removeAllFollowing: "フォローを全解除"
@ -2347,6 +2347,8 @@ _moderationLogTypes:
createAvatarDecoration: "アイコンデコレーションを作成" createAvatarDecoration: "アイコンデコレーションを作成"
updateAvatarDecoration: "アイコンデコレーションを更新" updateAvatarDecoration: "アイコンデコレーションを更新"
deleteAvatarDecoration: "アイコンデコレーションを削除" deleteAvatarDecoration: "アイコンデコレーションを削除"
unsetUserAvatar: "ユーザーのアイコンを解除"
unsetUserBanner: "ユーザーのバナーを解除"
_fileViewer: _fileViewer:
title: "ファイルの詳細" title: "ファイルの詳細"

View file

@ -51,7 +51,7 @@
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"postcss": "8.4.31", "postcss": "8.4.31",
"terser": "5.24.0", "terser": "5.24.0",
"typescript": "5.2.2" "typescript": "5.3.2"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "6.11.0", "@typescript-eslint/eslint-plugin": "6.11.0",

View file

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class SupportVerifyMailApi1700303245007 {
name = 'SupportVerifyMailApi1700303245007'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "verifymailAuthKey" character varying(1024)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "enableVerifymailApi" boolean NOT NULL DEFAULT false`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableVerifymailApi"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "verifymailAuthKey"`);
}
}

View file

@ -7,8 +7,8 @@
"node": ">=18.16.0" "node": ">=18.16.0"
}, },
"scripts": { "scripts": {
"start": "node ./built/index.js", "start": "node ./built/boot/entry.js",
"start:test": "NODE_ENV=test node ./built/index.js", "start:test": "NODE_ENV=test node ./built/boot/entry.js",
"migrate": "pnpm typeorm migration:run -d ormconfig.js", "migrate": "pnpm typeorm migration:run -d ormconfig.js",
"revert": "pnpm typeorm migration:revert -d ormconfig.js", "revert": "pnpm typeorm migration:revert -d ormconfig.js",
"check:connect": "node ./check_connect.js", "check:connect": "node ./check_connect.js",
@ -165,7 +165,7 @@
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"twemoji-parser": "14.0.0", "twemoji-parser": "14.0.0",
"typeorm": "0.3.17", "typeorm": "0.3.17",
"typescript": "5.2.2", "typescript": "5.3.2",
"ulid": "2.3.0", "ulid": "2.3.0",
"vary": "1.1.2", "vary": "1.1.2",
"web-push": "3.6.6", "web-push": "3.6.6",

View file

@ -61,12 +61,23 @@ export class AntennaService implements OnApplicationShutdown {
lastUsedAt: new Date(body.lastUsedAt), lastUsedAt: new Date(body.lastUsedAt),
}); });
break; break;
case 'antennaUpdated': case 'antennaUpdated': {
this.antennas[this.antennas.findIndex(a => a.id === body.id)] = { const idx = this.antennas.findIndex(a => a.id === body.id);
...body, if (idx >= 0) {
createdAt: new Date(body.createdAt), this.antennas[idx] = {
lastUsedAt: new Date(body.lastUsedAt), ...body,
}; createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
};
} else {
// サーバ起動時にactiveじゃなかった場合、リストに持っていないので追加する必要あり
this.antennas.push({
...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
});
}
}
break; break;
case 'antennaDeleted': case 'antennaDeleted':
this.antennas = this.antennas.filter(a => a.id !== body.id); this.antennas = this.antennas.filter(a => a.id !== body.id);

View file

@ -3,9 +3,11 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { URLSearchParams } from 'node:url';
import * as nodemailer from 'nodemailer'; import * as nodemailer from 'nodemailer';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { validate as validateEmail } from 'deep-email-validator'; import { validate as validateEmail } from 'deep-email-validator';
import { SubOutputFormat } from 'deep-email-validator/dist/output/output.js';
import { MetaService } from '@/core/MetaService.js'; import { MetaService } from '@/core/MetaService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
@ -13,6 +15,7 @@ import type Logger from '@/logger.js';
import type { UserProfilesRepository } from '@/models/_.js'; import type { UserProfilesRepository } from '@/models/_.js';
import { LoggerService } from '@/core/LoggerService.js'; import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
@Injectable() @Injectable()
export class EmailService { export class EmailService {
@ -27,6 +30,7 @@ export class EmailService {
private metaService: MetaService, private metaService: MetaService,
private loggerService: LoggerService, private loggerService: LoggerService,
private httpRequestService: HttpRequestService,
) { ) {
this.logger = this.loggerService.getLogger('email'); this.logger = this.loggerService.getLogger('email');
} }
@ -160,14 +164,25 @@ export class EmailService {
email: emailAddress, email: emailAddress,
}); });
const validated = meta.enableActiveEmailValidation ? await validateEmail({ const verifymailApi = meta.enableVerifymailApi && meta.verifymailAuthKey != null;
email: emailAddress, let validated;
validateRegex: true,
validateMx: true, if (meta.enableActiveEmailValidation && meta.verifymailAuthKey) {
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので if (verifymailApi) {
validateDisposable: true, // 捨てアドかどうかチェック validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey);
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので } else {
}) : { valid: true, reason: null }; validated = meta.enableActiveEmailValidation ? await validateEmail({
email: emailAddress,
validateRegex: true,
validateMx: true,
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
validateDisposable: true, // 捨てアドかどうかチェック
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
}) : { valid: true, reason: null };
}
} else {
validated = { valid: true, reason: null };
}
const available = exist === 0 && validated.valid; const available = exist === 0 && validated.valid;
@ -182,4 +197,65 @@ export class EmailService {
null, null,
}; };
} }
private async verifyMail(emailAddress: string, verifymailAuthKey: string): Promise<{
valid: boolean;
reason: 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | null;
}> {
const endpoint = 'https://verifymail.io/api/' + emailAddress + '?key=' + verifymailAuthKey;
const res = await this.httpRequestService.send(endpoint, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json, */*',
},
});
const json = (await res.json()) as {
block: boolean;
catch_all: boolean;
deliverable_email: boolean;
disposable: boolean;
domain: string;
email_address: string;
email_provider: string;
mx: boolean;
mx_fallback: boolean;
mx_host: string[];
mx_ip: string[];
mx_priority: { [key: string]: number };
privacy: boolean;
related_domains: string[];
};
if (json.email_address === undefined) {
return {
valid: false,
reason: 'format',
};
}
if (json.deliverable_email !== undefined && !json.deliverable_email) {
return {
valid: false,
reason: 'smtp',
};
}
if (json.disposable) {
return {
valid: false,
reason: 'disposable',
};
}
if (json.mx !== undefined && !json.mx) {
return {
valid: false,
reason: 'mx',
};
}
return {
valid: true,
reason: null,
};
}
} }

View file

@ -177,7 +177,7 @@ export class NotificationEntityService implements OnModuleInit {
) : undefined; ) : undefined;
if (notification.type === 'reaction:grouped') { if (notification.type === 'reaction:grouped') {
const reactions = await Promise.all(notification.reactions.map(async reaction => { const reactions = await Promise.allSettled(notification.reactions.map(async reaction => {
const user = hint?.packedUsers != null const user = hint?.packedUsers != null
? hint.packedUsers.get(reaction.userId)! ? hint.packedUsers.get(reaction.userId)!
: await this.userEntityService.pack(reaction.userId, { id: meId }, { : await this.userEntityService.pack(reaction.userId, { id: meId }, {
@ -193,23 +193,27 @@ export class NotificationEntityService implements OnModuleInit {
createdAt: new Date(notification.createdAt).toISOString(), createdAt: new Date(notification.createdAt).toISOString(),
type: notification.type, type: notification.type,
note: noteIfNeed, note: noteIfNeed,
reactions, reactions: reactions.filter(result => result.status === 'fulfilled')
.map(result => (result as PromiseFulfilledResult<{ user: Packed<'User'>; reaction: string; }>).value),
}); });
} else if (notification.type === 'renote:grouped') { } else if (notification.type === 'renote:grouped') {
const users = await Promise.all(notification.userIds.map(userId => { const users = await Promise.allSettled(notification.userIds.map(userId => {
const user = hint?.packedUsers != null const packedUser = hint?.packedUsers != null ? hint.packedUsers.get(userId) : null;
? hint.packedUsers.get(userId) if (packedUser) {
: this.userEntityService.pack(userId!, { id: meId }, { return packedUser;
detail: false, }
});
return user; return this.userEntityService.pack(userId, { id: meId }, {
detail: false,
});
})); }));
return await awaitAll({ return await awaitAll({
id: notification.id, id: notification.id,
createdAt: new Date(notification.createdAt).toISOString(), createdAt: new Date(notification.createdAt).toISOString(),
type: notification.type, type: notification.type,
note: noteIfNeed, note: noteIfNeed,
users, users: users.filter(result => result.status === 'fulfilled')
.map(result => (result as PromiseFulfilledResult<Packed<'User'>>).value),
}); });
} }
@ -278,9 +282,11 @@ export class NotificationEntityService implements OnModuleInit {
validNotifications = validNotifications.filter(x => (x.type !== 'receiveFollowRequest') || reqs.some(r => r.followerId === x.notifierId)); validNotifications = validNotifications.filter(x => (x.type !== 'receiveFollowRequest') || reqs.some(r => r.followerId === x.notifierId));
} }
return await Promise.all(validNotifications.map(x => this.packGrouped(x, meId, {}, { return (await Promise.allSettled(validNotifications.map(x => this.packGrouped(x, meId, {}, {
packedNotes, packedNotes,
packedUsers, packedUsers,
}))); }))))
.filter(result => result.status === 'fulfilled')
.map(result => (result as PromiseFulfilledResult<Packed<'Notification'>>).value);
} }
} }

View file

@ -446,6 +446,17 @@ export class MiMeta {
}) })
public enableActiveEmailValidation: boolean; public enableActiveEmailValidation: boolean;
@Column('boolean', {
default: false,
})
public enableVerifymailApi: boolean;
@Column('varchar', {
length: 1024,
nullable: true,
})
public verifymailAuthKey: string | null;
@Column('boolean', { @Column('boolean', {
default: true, default: true,
}) })

View file

@ -42,11 +42,11 @@ export const packedAnnouncementSchema = {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
}, },
forYou: { needConfirmationToRead: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
needConfirmationToRead: { forYou: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },

View file

@ -19,7 +19,7 @@ export const packedChannelSchema = {
}, },
lastNotedAt: { lastNotedAt: {
type: 'string', type: 'string',
optional: false, nullable: true, nullable: true, optional: false,
format: 'date-time', format: 'date-time',
}, },
name: { name: {
@ -28,38 +28,18 @@ export const packedChannelSchema = {
}, },
description: { description: {
type: 'string', type: 'string',
nullable: true, optional: false, optional: false, nullable: true,
},
bannerUrl: {
type: 'string',
format: 'url',
nullable: true, optional: false,
},
isArchived: {
type: 'boolean',
optional: false, nullable: false,
},
notesCount: {
type: 'number',
nullable: false, optional: false,
},
usersCount: {
type: 'number',
nullable: false, optional: false,
},
isFollowing: {
type: 'boolean',
optional: true, nullable: false,
},
isFavorited: {
type: 'boolean',
optional: true, nullable: false,
}, },
userId: { userId: {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true, optional: false,
format: 'id', format: 'id',
}, },
bannerUrl: {
type: 'string',
format: 'url',
nullable: true, optional: false,
},
pinnedNoteIds: { pinnedNoteIds: {
type: 'array', type: 'array',
nullable: false, optional: false, nullable: false, optional: false,
@ -72,6 +52,18 @@ export const packedChannelSchema = {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
}, },
isArchived: {
type: 'boolean',
optional: false, nullable: false,
},
usersCount: {
type: 'number',
nullable: false, optional: false,
},
notesCount: {
type: 'number',
nullable: false, optional: false,
},
isSensitive: { isSensitive: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
@ -80,5 +72,22 @@ export const packedChannelSchema = {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
isFollowing: {
type: 'boolean',
optional: true, nullable: false,
},
isFavorited: {
type: 'boolean',
optional: true, nullable: false,
},
pinnedNotes: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'Note',
},
},
}, },
} as const; } as const;

View file

@ -44,13 +44,13 @@ export const packedClipSchema = {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
isFavorited: {
type: 'boolean',
optional: true, nullable: false,
},
favoritedCount: { favoritedCount: {
type: 'number', type: 'number',
optional: false, nullable: false, optional: false, nullable: false,
}, },
isFavorited: {
type: 'boolean',
optional: true, nullable: false,
},
}, },
} as const; } as const;

View file

@ -74,7 +74,7 @@ export const packedDriveFileSchema = {
}, },
url: { url: {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: false,
format: 'url', format: 'url',
}, },
thumbnailUrl: { thumbnailUrl: {

View file

@ -21,6 +21,12 @@ export const packedDriveFolderSchema = {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
}, },
parentId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
foldersCount: { foldersCount: {
type: 'number', type: 'number',
optional: true, nullable: false, optional: true, nullable: false,
@ -29,12 +35,6 @@ export const packedDriveFolderSchema = {
type: 'number', type: 'number',
optional: true, nullable: false, optional: true, nullable: false,
}, },
parentId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
parent: { parent: {
type: 'object', type: 'object',
optional: true, nullable: true, optional: true, nullable: true,

View file

@ -79,6 +79,10 @@ export const packedFederationInstanceSchema = {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
}, },
isSilenced: {
type: 'boolean',
optional: false, nullable: false,
},
iconUrl: { iconUrl: {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
@ -93,11 +97,6 @@ export const packedFederationInstanceSchema = {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
}, },
isSilenced: {
type: "boolean",
optional: false,
nullable: false,
},
infoUpdatedAt: { infoUpdatedAt: {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,

View file

@ -22,6 +22,16 @@ export const packedFlashSchema = {
optional: false, nullable: false, optional: false, nullable: false,
format: 'date-time', format: 'date-time',
}, },
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
title: { title: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
@ -34,16 +44,6 @@ export const packedFlashSchema = {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
}, },
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
likedCount: { likedCount: {
type: 'number', type: 'number',
optional: false, nullable: true, optional: false, nullable: true,

View file

@ -22,16 +22,16 @@ export const packedFollowingSchema = {
optional: false, nullable: false, optional: false, nullable: false,
format: 'id', format: 'id',
}, },
followee: {
type: 'object',
optional: true, nullable: false,
ref: 'UserDetailed',
},
followerId: { followerId: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
format: 'id', format: 'id',
}, },
followee: {
type: 'object',
optional: true, nullable: false,
ref: 'UserDetailed',
},
follower: { follower: {
type: 'object', type: 'object',
optional: true, nullable: false, optional: true, nullable: false,

View file

@ -22,14 +22,6 @@ export const packedGalleryPostSchema = {
optional: false, nullable: false, optional: false, nullable: false,
format: 'date-time', format: 'date-time',
}, },
title: {
type: 'string',
optional: false, nullable: false,
},
description: {
type: 'string',
optional: false, nullable: true,
},
userId: { userId: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
@ -40,6 +32,14 @@ export const packedGalleryPostSchema = {
ref: 'UserLite', ref: 'UserLite',
optional: false, nullable: false, optional: false, nullable: false,
}, },
title: {
type: 'string',
optional: false, nullable: false,
},
description: {
type: 'string',
optional: false, nullable: true,
},
fileIds: { fileIds: {
type: 'array', type: 'array',
optional: true, nullable: false, optional: true, nullable: false,
@ -70,6 +70,14 @@ export const packedGalleryPostSchema = {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
likedCount: {
type: 'number',
optional: false, nullable: false,
},
isLiked: {
type: 'boolean',
optional: true, nullable: false,
},
}, },
} as const; } as const;

View file

@ -127,22 +127,26 @@ export const packedNoteSchema = {
channel: { channel: {
type: 'object', type: 'object',
optional: true, nullable: true, optional: true, nullable: true,
items: { properties: {
type: 'object', id: {
optional: false, nullable: false, type: 'string',
properties: { optional: false, nullable: false,
id: { },
type: 'string', name: {
optional: false, nullable: false, type: 'string',
}, optional: false, nullable: false,
name: { },
type: 'string', color: {
optional: false, nullable: true, type: 'string',
}, optional: false, nullable: false,
isSensitive: { },
type: 'boolean', isSensitive: {
optional: true, nullable: false, type: 'boolean',
}, optional: false, nullable: false,
},
allowRenoteToExternal: {
type: 'boolean',
optional: false, nullable: false,
}, },
}, },
}, },

View file

@ -42,13 +42,9 @@ export const packedNotificationSchema = {
type: 'string', type: 'string',
optional: true, nullable: true, optional: true, nullable: true,
}, },
choice: { achievement: {
type: 'number', type: 'string',
optional: true, nullable: true, optional: true, nullable: false,
},
invitation: {
type: 'object',
optional: true, nullable: true,
}, },
body: { body: {
type: 'string', type: 'string',
@ -81,14 +77,14 @@ export const packedNotificationSchema = {
required: ['user', 'reaction'], required: ['user', 'reaction'],
}, },
}, },
}, users: {
users: { type: 'array',
type: 'array', optional: true, nullable: true,
optional: true, nullable: true, items: {
items: { type: 'object',
type: 'object', ref: 'UserLite',
ref: 'UserLite', optional: false, nullable: false,
optional: false, nullable: false, },
}, },
}, },
} as const; } as const;

View file

@ -22,6 +22,32 @@ export const packedPageSchema = {
optional: false, nullable: false, optional: false, nullable: false,
format: 'date-time', format: 'date-time',
}, },
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
content: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
},
},
variables: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
},
},
title: { title: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
@ -34,24 +60,48 @@ export const packedPageSchema = {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
}, },
content: { hideTitleWhenPinned: {
type: 'array', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
variables: { alignCenter: {
type: 'array', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
userId: { font: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
format: 'id',
}, },
user: { script: {
type: 'object', type: 'string',
ref: 'UserLite',
optional: false, nullable: false, optional: false, nullable: false,
}, },
eyeCatchingImageId: {
type: 'string',
optional: false, nullable: true,
},
eyeCatchingImage: {
type: 'object',
optional: false, nullable: true,
ref: 'DriveFile',
},
attachedFiles: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFile',
},
},
likedCount: {
type: 'number',
optional: false, nullable: false,
},
isLiked: {
type: 'boolean',
optional: true, nullable: false,
},
}, },
} as const; } as const;

View file

@ -49,11 +49,6 @@ export const packedUserLiteSchema = {
nullable: false, optional: false, nullable: false, optional: false,
format: 'id', format: 'id',
}, },
url: {
type: 'string',
format: 'url',
nullable: false, optional: false,
},
angle: { angle: {
type: 'number', type: 'number',
nullable: false, optional: true, nullable: false, optional: true,
@ -62,19 +57,14 @@ export const packedUserLiteSchema = {
type: 'boolean', type: 'boolean',
nullable: false, optional: true, nullable: false, optional: true,
}, },
url: {
type: 'string',
format: 'url',
nullable: false, optional: false,
},
}, },
}, },
}, },
isAdmin: {
type: 'boolean',
nullable: false, optional: true,
default: false,
},
isModerator: {
type: 'boolean',
nullable: false, optional: true,
default: false,
},
isBot: { isBot: {
type: 'boolean', type: 'boolean',
nullable: false, optional: true, nullable: false, optional: true,
@ -83,12 +73,67 @@ export const packedUserLiteSchema = {
type: 'boolean', type: 'boolean',
nullable: false, optional: true, nullable: false, optional: true,
}, },
instance: {
type: 'object',
nullable: false, optional: true,
properties: {
name: {
type: 'string',
nullable: true, optional: false,
},
softwareName: {
type: 'string',
nullable: true, optional: false,
},
softwareVersion: {
type: 'string',
nullable: true, optional: false,
},
iconUrl: {
type: 'string',
nullable: true, optional: false,
},
faviconUrl: {
type: 'string',
nullable: true, optional: false,
},
themeColor: {
type: 'string',
nullable: true, optional: false,
},
},
},
emojis: {
type: 'object',
nullable: false, optional: false,
},
onlineStatus: { onlineStatus: {
type: 'string', type: 'string',
format: 'url', nullable: false, optional: false,
nullable: true, optional: false,
enum: ['unknown', 'online', 'active', 'offline'], enum: ['unknown', 'online', 'active', 'offline'],
}, },
badgeRoles: {
type: 'array',
nullable: false, optional: true,
items: {
type: 'object',
nullable: false, optional: false,
properties: {
name: {
type: 'string',
nullable: false, optional: false,
},
iconUrl: {
type: 'string',
nullable: true, optional: false,
},
displayOrder: {
type: 'number',
nullable: false, optional: false,
},
},
},
},
}, },
} as const; } as const;
@ -105,21 +150,18 @@ export const packedUserDetailedNotMeOnlySchema = {
format: 'uri', format: 'uri',
nullable: true, optional: false, nullable: true, optional: false,
}, },
movedToUri: { movedTo: {
type: 'string', type: 'string',
format: 'uri', format: 'uri',
nullable: true, nullable: true, optional: false,
optional: false,
}, },
alsoKnownAs: { alsoKnownAs: {
type: 'array', type: 'array',
nullable: true, nullable: true, optional: false,
optional: false,
items: { items: {
type: 'string', type: 'string',
format: 'id', format: 'id',
nullable: false, nullable: false, optional: false,
optional: false,
}, },
}, },
createdAt: { createdAt: {
@ -253,6 +295,11 @@ export const packedUserDetailedNotMeOnlySchema = {
type: 'boolean', type: 'boolean',
nullable: false, optional: false, nullable: false, optional: false,
}, },
ffVisibility: {
type: 'string',
nullable: false, optional: false,
enum: ['public', 'followers', 'private'],
},
twoFactorEnabled: { twoFactorEnabled: {
type: 'boolean', type: 'boolean',
nullable: false, optional: false, nullable: false, optional: false,
@ -268,6 +315,57 @@ export const packedUserDetailedNotMeOnlySchema = {
nullable: false, optional: false, nullable: false, optional: false,
default: false, default: false,
}, },
roles: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'object',
nullable: false, optional: false,
properties: {
id: {
type: 'string',
nullable: false, optional: false,
format: 'id',
},
name: {
type: 'string',
nullable: false, optional: false,
},
color: {
type: 'string',
nullable: true, optional: false,
},
iconUrl: {
type: 'string',
nullable: true, optional: false,
},
description: {
type: 'string',
nullable: false, optional: false,
},
isModerator: {
type: 'boolean',
nullable: false, optional: false,
},
isAdministrator: {
type: 'boolean',
nullable: false, optional: false,
},
displayOrder: {
type: 'number',
nullable: false, optional: false,
},
},
},
},
memo: {
type: 'string',
nullable: true, optional: false,
},
moderationNote: {
type: 'string',
nullable: false, optional: true,
},
//#region relations //#region relations
isFollowing: { isFollowing: {
type: 'boolean', type: 'boolean',
@ -301,10 +399,6 @@ export const packedUserDetailedNotMeOnlySchema = {
type: 'boolean', type: 'boolean',
nullable: false, optional: true, nullable: false, optional: true,
}, },
memo: {
type: 'string',
nullable: false, optional: true,
},
notify: { notify: {
type: 'string', type: 'string',
nullable: false, optional: true, nullable: false, optional: true,
@ -330,29 +424,37 @@ export const packedMeDetailedOnlySchema = {
nullable: true, optional: false, nullable: true, optional: false,
format: 'id', format: 'id',
}, },
injectFeaturedNote: { isModerator: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: true, optional: false,
}, },
isAdmin: {
type: 'boolean',
nullable: true, optional: false,
},
injectFeaturedNote: {
type: 'boolean',
nullable: false, optional: false,
},
receiveAnnouncementEmail: { receiveAnnouncementEmail: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
alwaysMarkNsfw: { alwaysMarkNsfw: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
autoSensitive: { autoSensitive: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
carefulBot: { carefulBot: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
autoAcceptFollowed: { autoAcceptFollowed: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
noCrawle: { noCrawle: {
type: 'boolean', type: 'boolean',
@ -391,10 +493,23 @@ export const packedMeDetailedOnlySchema = {
type: 'boolean', type: 'boolean',
nullable: false, optional: false, nullable: false, optional: false,
}, },
unreadAnnouncements: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'object',
nullable: false, optional: false,
ref: 'Announcement',
},
},
hasUnreadAntenna: { hasUnreadAntenna: {
type: 'boolean', type: 'boolean',
nullable: false, optional: false, nullable: false, optional: false,
}, },
hasUnreadChannel: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadNotification: { hasUnreadNotification: {
type: 'boolean', type: 'boolean',
nullable: false, optional: false, nullable: false, optional: false,
@ -433,12 +548,132 @@ export const packedMeDetailedOnlySchema = {
}, },
emailNotificationTypes: { emailNotificationTypes: {
type: 'array', type: 'array',
nullable: true, optional: false, nullable: false, optional: false,
items: { items: {
type: 'string', type: 'string',
nullable: false, optional: false, nullable: false, optional: false,
}, },
}, },
achievements: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'object',
nullable: false, optional: false,
properties: {
name: {
type: 'string',
nullable: false, optional: false,
},
unlockedAt: {
type: 'number',
nullable: false, optional: false,
},
},
},
},
loggedInDays: {
type: 'number',
nullable: false, optional: false,
},
policies: {
type: 'object',
nullable: false, optional: false,
properties: {
gtlAvailable: {
type: 'boolean',
nullable: false, optional: false,
},
ltlAvailable: {
type: 'boolean',
nullable: false, optional: false,
},
canPublicNote: {
type: 'boolean',
nullable: false, optional: false,
},
canInvite: {
type: 'boolean',
nullable: false, optional: false,
},
inviteLimit: {
type: 'number',
nullable: false, optional: false,
},
inviteLimitCycle: {
type: 'number',
nullable: false, optional: false,
},
inviteExpirationTime: {
type: 'number',
nullable: false, optional: false,
},
canManageCustomEmojis: {
type: 'boolean',
nullable: false, optional: false,
},
canManageAvatarDecorations: {
type: 'boolean',
nullable: false, optional: false,
},
canSearchNotes: {
type: 'boolean',
nullable: false, optional: false,
},
canUseTranslator: {
type: 'boolean',
nullable: false, optional: false,
},
canHideAds: {
type: 'boolean',
nullable: false, optional: false,
},
driveCapacityMb: {
type: 'number',
nullable: false, optional: false,
},
alwaysMarkNsfw: {
type: 'boolean',
nullable: false, optional: false,
},
pinLimit: {
type: 'number',
nullable: false, optional: false,
},
antennaLimit: {
type: 'number',
nullable: false, optional: false,
},
wordMuteLimit: {
type: 'number',
nullable: false, optional: false,
},
webhookLimit: {
type: 'number',
nullable: false, optional: false,
},
clipLimit: {
type: 'number',
nullable: false, optional: false,
},
noteEachClipsLimit: {
type: 'number',
nullable: false, optional: false,
},
userListLimit: {
type: 'number',
nullable: false, optional: false,
},
userEachUserListsLimit: {
type: 'number',
nullable: false, optional: false,
},
rateLimitFactor: {
type: 'number',
nullable: false, optional: false,
},
},
},
//#region secrets //#region secrets
email: { email: {
type: 'string', type: 'string',
@ -515,5 +750,13 @@ export const packedUserSchema = {
type: 'object', type: 'object',
ref: 'UserDetailed', ref: 'UserDetailed',
}, },
{
type: 'object',
ref: 'UserDetailedNotMe',
},
{
type: 'object',
ref: 'MeDetailed',
},
], ],
} as const; } as const;

View file

@ -28,8 +28,8 @@ import * as ep___admin_avatarDecorations_delete from './endpoints/admin/avatar-d
import * as ep___admin_avatarDecorations_list from './endpoints/admin/avatar-decorations/list.js'; import * as ep___admin_avatarDecorations_list from './endpoints/admin/avatar-decorations/list.js';
import * as ep___admin_avatarDecorations_update from './endpoints/admin/avatar-decorations/update.js'; import * as ep___admin_avatarDecorations_update from './endpoints/admin/avatar-decorations/update.js';
import * as ep___admin_deleteAllFilesOfAUser from './endpoints/admin/delete-all-files-of-a-user.js'; import * as ep___admin_deleteAllFilesOfAUser from './endpoints/admin/delete-all-files-of-a-user.js';
import * as ep___admin_deleteUserAvatar from './endpoints/admin/delete-user-avatar.js'; import * as ep___admin_unsetUserAvatar from './endpoints/admin/unset-user-avatar.js';
import * as ep___admin_deleteUserBanner from './endpoints/admin/delete-user-banner.js'; import * as ep___admin_unsetUserBanner from './endpoints/admin/unset-user-banner.js';
import * as ep___admin_drive_cleanRemoteFiles from './endpoints/admin/drive/clean-remote-files.js'; import * as ep___admin_drive_cleanRemoteFiles from './endpoints/admin/drive/clean-remote-files.js';
import * as ep___admin_drive_cleanup from './endpoints/admin/drive/cleanup.js'; import * as ep___admin_drive_cleanup from './endpoints/admin/drive/cleanup.js';
import * as ep___admin_drive_files from './endpoints/admin/drive/files.js'; import * as ep___admin_drive_files from './endpoints/admin/drive/files.js';
@ -393,8 +393,8 @@ const $admin_avatarDecorations_delete: Provider = { provide: 'ep:admin/avatar-de
const $admin_avatarDecorations_list: Provider = { provide: 'ep:admin/avatar-decorations/list', useClass: ep___admin_avatarDecorations_list.default }; const $admin_avatarDecorations_list: Provider = { provide: 'ep:admin/avatar-decorations/list', useClass: ep___admin_avatarDecorations_list.default };
const $admin_avatarDecorations_update: Provider = { provide: 'ep:admin/avatar-decorations/update', useClass: ep___admin_avatarDecorations_update.default }; const $admin_avatarDecorations_update: Provider = { provide: 'ep:admin/avatar-decorations/update', useClass: ep___admin_avatarDecorations_update.default };
const $admin_deleteAllFilesOfAUser: Provider = { provide: 'ep:admin/delete-all-files-of-a-user', useClass: ep___admin_deleteAllFilesOfAUser.default }; const $admin_deleteAllFilesOfAUser: Provider = { provide: 'ep:admin/delete-all-files-of-a-user', useClass: ep___admin_deleteAllFilesOfAUser.default };
const $admin_deleteUserAvatar: Provider = { provide: 'ep:admin/delete-user-avatar', useClass: ep___admin_deleteUserAvatar.default }; const $admin_unsetUserAvatar: Provider = { provide: 'ep:admin/unset-user-avatar', useClass: ep___admin_unsetUserAvatar.default };
const $admin_deleteUserBanner: Provider = { provide: 'ep:admin/delete-user-banner', useClass: ep___admin_deleteUserBanner.default }; const $admin_unsetUserBanner: Provider = { provide: 'ep:admin/unset-user-banner', useClass: ep___admin_unsetUserBanner.default };
const $admin_drive_cleanRemoteFiles: Provider = { provide: 'ep:admin/drive/clean-remote-files', useClass: ep___admin_drive_cleanRemoteFiles.default }; const $admin_drive_cleanRemoteFiles: Provider = { provide: 'ep:admin/drive/clean-remote-files', useClass: ep___admin_drive_cleanRemoteFiles.default };
const $admin_drive_cleanup: Provider = { provide: 'ep:admin/drive/cleanup', useClass: ep___admin_drive_cleanup.default }; const $admin_drive_cleanup: Provider = { provide: 'ep:admin/drive/cleanup', useClass: ep___admin_drive_cleanup.default };
const $admin_drive_files: Provider = { provide: 'ep:admin/drive/files', useClass: ep___admin_drive_files.default }; const $admin_drive_files: Provider = { provide: 'ep:admin/drive/files', useClass: ep___admin_drive_files.default };
@ -762,8 +762,8 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$admin_avatarDecorations_list, $admin_avatarDecorations_list,
$admin_avatarDecorations_update, $admin_avatarDecorations_update,
$admin_deleteAllFilesOfAUser, $admin_deleteAllFilesOfAUser,
$admin_deleteUserAvatar, $admin_unsetUserAvatar,
$admin_deleteUserBanner, $admin_unsetUserBanner,
$admin_drive_cleanRemoteFiles, $admin_drive_cleanRemoteFiles,
$admin_drive_cleanup, $admin_drive_cleanup,
$admin_drive_files, $admin_drive_files,
@ -1125,8 +1125,8 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$admin_avatarDecorations_list, $admin_avatarDecorations_list,
$admin_avatarDecorations_update, $admin_avatarDecorations_update,
$admin_deleteAllFilesOfAUser, $admin_deleteAllFilesOfAUser,
$admin_deleteUserAvatar, $admin_unsetUserAvatar,
$admin_deleteUserBanner, $admin_unsetUserBanner,
$admin_drive_cleanRemoteFiles, $admin_drive_cleanRemoteFiles,
$admin_drive_cleanup, $admin_drive_cleanup,
$admin_drive_files, $admin_drive_files,

View file

@ -28,8 +28,8 @@ import * as ep___admin_avatarDecorations_delete from './endpoints/admin/avatar-d
import * as ep___admin_avatarDecorations_list from './endpoints/admin/avatar-decorations/list.js'; import * as ep___admin_avatarDecorations_list from './endpoints/admin/avatar-decorations/list.js';
import * as ep___admin_avatarDecorations_update from './endpoints/admin/avatar-decorations/update.js'; import * as ep___admin_avatarDecorations_update from './endpoints/admin/avatar-decorations/update.js';
import * as ep___admin_deleteAllFilesOfAUser from './endpoints/admin/delete-all-files-of-a-user.js'; import * as ep___admin_deleteAllFilesOfAUser from './endpoints/admin/delete-all-files-of-a-user.js';
import * as ep___admin_deleteUserAvatar from './endpoints/admin/delete-user-avatar.js'; import * as ep___admin_unsetUserAvatar from './endpoints/admin/unset-user-avatar.js';
import * as ep___admin_deleteUserBanner from './endpoints/admin/delete-user-banner.js'; import * as ep___admin_unsetUserBanner from './endpoints/admin/unset-user-banner.js';
import * as ep___admin_drive_cleanRemoteFiles from './endpoints/admin/drive/clean-remote-files.js'; import * as ep___admin_drive_cleanRemoteFiles from './endpoints/admin/drive/clean-remote-files.js';
import * as ep___admin_drive_cleanup from './endpoints/admin/drive/cleanup.js'; import * as ep___admin_drive_cleanup from './endpoints/admin/drive/cleanup.js';
import * as ep___admin_drive_files from './endpoints/admin/drive/files.js'; import * as ep___admin_drive_files from './endpoints/admin/drive/files.js';
@ -391,8 +391,8 @@ const eps = [
['admin/avatar-decorations/list', ep___admin_avatarDecorations_list], ['admin/avatar-decorations/list', ep___admin_avatarDecorations_list],
['admin/avatar-decorations/update', ep___admin_avatarDecorations_update], ['admin/avatar-decorations/update', ep___admin_avatarDecorations_update],
['admin/delete-all-files-of-a-user', ep___admin_deleteAllFilesOfAUser], ['admin/delete-all-files-of-a-user', ep___admin_deleteAllFilesOfAUser],
['admin/delete-user-avatar', ep___admin_deleteUserAvatar], ['admin/unset-user-avatar', ep___admin_unsetUserAvatar],
['admin/delete-user-banner', ep___admin_deleteUserBanner], ['admin/unset-user-banner', ep___admin_unsetUserBanner],
['admin/drive/clean-remote-files', ep___admin_drive_cleanRemoteFiles], ['admin/drive/clean-remote-files', ep___admin_drive_cleanRemoteFiles],
['admin/drive/cleanup', ep___admin_drive_cleanup], ['admin/drive/cleanup', ep___admin_drive_cleanup],
['admin/drive/files', ep___admin_drive_files], ['admin/drive/files', ep___admin_drive_files],

View file

@ -7,6 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository } from '@/models/_.js'; import type { UsersRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -29,6 +30,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor( constructor(
@Inject(DI.usersRepository) @Inject(DI.usersRepository)
private usersRepository: UsersRepository, private usersRepository: UsersRepository,
private moderationLogService: ModerationLogService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId }); const user = await this.usersRepository.findOneBy({ id: ps.userId });
@ -37,12 +40,21 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
throw new Error('user not found'); throw new Error('user not found');
} }
if (user.avatarId == null) return;
await this.usersRepository.update(user.id, { await this.usersRepository.update(user.id, {
avatar: null, avatar: null,
avatarId: null, avatarId: null,
avatarUrl: null, avatarUrl: null,
avatarBlurhash: null, avatarBlurhash: null,
}); });
this.moderationLogService.log(me, 'unsetUserAvatar', {
userId: user.id,
userUsername: user.username,
userHost: user.host,
fileId: user.avatarId,
});
}); });
} }
} }

View file

@ -7,6 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository } from '@/models/_.js'; import type { UsersRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -29,6 +30,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor( constructor(
@Inject(DI.usersRepository) @Inject(DI.usersRepository)
private usersRepository: UsersRepository, private usersRepository: UsersRepository,
private moderationLogService: ModerationLogService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId }); const user = await this.usersRepository.findOneBy({ id: ps.userId });
@ -37,12 +40,21 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
throw new Error('user not found'); throw new Error('user not found');
} }
if (user.bannerId == null) return;
await this.usersRepository.update(user.id, { await this.usersRepository.update(user.id, {
banner: null, banner: null,
bannerId: null, bannerId: null,
bannerUrl: null, bannerUrl: null,
bannerBlurhash: null, bannerBlurhash: null,
}); });
this.moderationLogService.log(me, 'unsetUserBanner', {
userId: user.id,
userUsername: user.username,
userHost: user.host,
fileId: user.bannerId,
});
}); });
} }
} }

View file

@ -113,6 +113,8 @@ export const paramDef = {
objectStorageS3ForcePathStyle: { type: 'boolean' }, objectStorageS3ForcePathStyle: { type: 'boolean' },
enableIpLogging: { type: 'boolean' }, enableIpLogging: { type: 'boolean' },
enableActiveEmailValidation: { type: 'boolean' }, enableActiveEmailValidation: { type: 'boolean' },
enableVerifymailApi: { type: 'boolean' },
verifymailAuthKey: { type: 'string', nullable: true },
enableChartsForRemoteUser: { type: 'boolean' }, enableChartsForRemoteUser: { type: 'boolean' },
enableChartsForFederatedInstances: { type: 'boolean' }, enableChartsForFederatedInstances: { type: 'boolean' },
enableServerMachineStats: { type: 'boolean' }, enableServerMachineStats: { type: 'boolean' },
@ -462,6 +464,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.enableActiveEmailValidation = ps.enableActiveEmailValidation; set.enableActiveEmailValidation = ps.enableActiveEmailValidation;
} }
if (ps.enableVerifymailApi !== undefined) {
set.enableVerifymailApi = ps.enableVerifymailApi;
}
if (ps.verifymailAuthKey !== undefined) {
if (ps.verifymailAuthKey === '') {
set.verifymailAuthKey = null;
} else {
set.verifymailAuthKey = ps.verifymailAuthKey;
}
}
if (ps.enableChartsForRemoteUser !== undefined) { if (ps.enableChartsForRemoteUser !== undefined) {
set.enableChartsForRemoteUser = ps.enableChartsForRemoteUser; set.enableChartsForRemoteUser = ps.enableChartsForRemoteUser;
} }

View file

@ -13,6 +13,7 @@ import { DI } from '@/di-symbols.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { IdService } from '@/core/IdService.js'; import { IdService } from '@/core/IdService.js';
import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { FunoutTimelineService } from '@/core/FunoutTimelineService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { ApiError } from '../../error.js'; import { ApiError } from '../../error.js';
export const meta = { export const meta = {
@ -71,6 +72,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private queryService: QueryService, private queryService: QueryService,
private noteReadService: NoteReadService, private noteReadService: NoteReadService,
private funoutTimelineService: FunoutTimelineService, private funoutTimelineService: FunoutTimelineService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
@ -85,10 +87,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.noSuchAntenna); throw new ApiError(meta.errors.noSuchAntenna);
} }
this.antennasRepository.update(antenna.id, { // falseだった場合はアンテナの配信先が増えたことを通知したい
isActive: true, const needPublishEvent = !antenna.isActive;
lastUsedAt: new Date(),
}); antenna.isActive = true;
antenna.lastUsedAt = new Date();
this.antennasRepository.update(antenna.id, antenna);
if (needPublishEvent) {
this.globalEventService.publishInternalEvent('antennaUpdated', antenna);
}
let noteIds = await this.funoutTimelineService.get(`antennaTimeline:${antenna.id}`, untilId, sinceId); let noteIds = await this.funoutTimelineService.get(`antennaTimeline:${antenna.id}`, untilId, sinceId);
noteIds = noteIds.slice(0, ps.limit); noteIds = noteIds.slice(0, ps.limit);

View file

@ -63,6 +63,8 @@ export const moderationLogTypes = [
'createAvatarDecoration', 'createAvatarDecoration',
'updateAvatarDecoration', 'updateAvatarDecoration',
'deleteAvatarDecoration', 'deleteAvatarDecoration',
'unsetUserAvatar',
'unsetUserBanner',
] as const; ] as const;
export type ModerationLogPayloads = { export type ModerationLogPayloads = {
@ -237,6 +239,18 @@ export type ModerationLogPayloads = {
avatarDecorationId: string; avatarDecorationId: string;
avatarDecoration: any; avatarDecoration: any;
}; };
unsetUserAvatar: {
userId: string;
userUsername: string;
userHost: string | null;
fileId: string;
};
unsetUserBanner: {
userId: string;
userUsername: string;
userHost: string | null;
fileId: string;
};
}; };
export type Serialized<T> = { export type Serialized<T> = {

View file

@ -70,7 +70,7 @@
"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", "twemoji-parser": "14.0.0",
"typescript": "5.2.2", "typescript": "5.3.2",
"uuid": "9.0.1", "uuid": "9.0.1",
"v-code-diff": "1.7.2", "v-code-diff": "1.7.2",
"vanilla-tilt": "1.8.1", "vanilla-tilt": "1.8.1",

View file

@ -114,7 +114,6 @@ const props = defineProps<{
& + article { & + article {
left: 0; left: 0;
width: 100%;
} }
} }
} }
@ -124,6 +123,7 @@ const props = defineProps<{
> .thumbnail { > .thumbnail {
height: 80px; height: 80px;
overflow: clip;
} }
> article { > article {

View file

@ -123,12 +123,11 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
</MkFolder> </MkFolder>
<MkButton v-if="$i.isAdmin" inline danger @click="deleteAccount">{{ i18n.ts.deleteAccount }}</MkButton>
<div> <div>
<MkButton v-if="iAmModerator" inline danger style="margin-right: 8px;" @click="deleteUserAvatar"><i class="ti ti-user-circle"></i> {{ i18n.ts.deleteUserAvatar }}</MkButton> <MkButton v-if="iAmModerator" inline danger style="margin-right: 8px;" @click="unsetUserAvatar"><i class="ti ti-user-circle"></i> {{ i18n.ts.unsetUserAvatar }}</MkButton>
<MkButton v-if="iAmModerator" inline danger @click="deleteUserBanner"><i class="ti ti-photo"></i> {{ i18n.ts.deleteUserBanner }}</MkButton> <MkButton v-if="iAmModerator" inline danger @click="unsetUserBanner"><i class="ti ti-photo"></i> {{ i18n.ts.unsetUserBanner }}</MkButton>
</div> </div>
<MkButton v-if="$i.isAdmin" inline danger @click="deleteAccount">{{ i18n.ts.deleteAccount }}</MkButton>
</div> </div>
</FormSection> </FormSection>
</div> </div>
@ -330,14 +329,14 @@ async function toggleSuspend(v) {
} }
} }
async function deleteUserAvatar() { async function unsetUserAvatar() {
const confirm = await os.confirm({ const confirm = await os.confirm({
type: 'warning', type: 'warning',
text: i18n.ts.deleteUserAvatarConfirm, text: i18n.ts.unsetUserAvatarConfirm,
}); });
if (confirm.canceled) return; if (confirm.canceled) return;
const process = async () => { const process = async () => {
await os.api('admin/delete-user-avatar', { userId: user.id }); await os.api('admin/unset-user-avatar', { userId: user.id });
os.success(); os.success();
}; };
await process().catch(err => { await process().catch(err => {
@ -349,14 +348,14 @@ async function deleteUserAvatar() {
refreshUser(); refreshUser();
} }
async function deleteUserBanner() { async function unsetUserBanner() {
const confirm = await os.confirm({ const confirm = await os.confirm({
type: 'warning', type: 'warning',
text: i18n.ts.deleteUserBannerConfirm, text: i18n.ts.unsetUserBannerConfirm,
}); });
if (confirm.canceled) return; if (confirm.canceled) return;
const process = async () => { const process = async () => {
await os.api('admin/delete-user-banner', { userId: user.id }); await os.api('admin/unset-user-banner', { userId: user.id });
os.success(); os.success();
}; };
await process().catch(err => { await process().catch(err => {

View file

@ -38,6 +38,7 @@ import { } from 'vue';
import XHeader from './_header_.vue'; import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue'; import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import FormSuspense from '@/components/form/suspense.vue'; import FormSuspense from '@/components/form/suspense.vue';
import FormSection from '@/components/form/section.vue'; import FormSection from '@/components/form/section.vue';
import * as os from '@/os.js'; import * as os from '@/os.js';

View file

@ -73,6 +73,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="enableActiveEmailValidation" @update:modelValue="save"> <MkSwitch v-model="enableActiveEmailValidation" @update:modelValue="save">
<template #label>Enable</template> <template #label>Enable</template>
</MkSwitch> </MkSwitch>
<MkSwitch v-model="enableVerifymailApi" @update:modelValue="save">
<template #label>Use Verifymail API</template>
</MkSwitch>
<MkInput v-model="verifymailAuthKey" @update:modelValue="save">
<template #prefix><i class="ti ti-key"></i></template>
<template #label>Verifymail API Auth Key</template>
</MkInput>
</div> </div>
</MkFolder> </MkFolder>
@ -132,6 +139,8 @@ let setSensitiveFlagAutomatically: boolean = $ref(false);
let enableSensitiveMediaDetectionForVideos: boolean = $ref(false); let enableSensitiveMediaDetectionForVideos: boolean = $ref(false);
let enableIpLogging: boolean = $ref(false); let enableIpLogging: boolean = $ref(false);
let enableActiveEmailValidation: boolean = $ref(false); let enableActiveEmailValidation: boolean = $ref(false);
let enableVerifymailApi: boolean = $ref(false);
let verifymailAuthKey: string | null = $ref(null);
async function init() { async function init() {
const meta = await os.api('admin/meta'); const meta = await os.api('admin/meta');
@ -150,6 +159,8 @@ async function init() {
enableSensitiveMediaDetectionForVideos = meta.enableSensitiveMediaDetectionForVideos; enableSensitiveMediaDetectionForVideos = meta.enableSensitiveMediaDetectionForVideos;
enableIpLogging = meta.enableIpLogging; enableIpLogging = meta.enableIpLogging;
enableActiveEmailValidation = meta.enableActiveEmailValidation; enableActiveEmailValidation = meta.enableActiveEmailValidation;
enableVerifymailApi = meta.enableVerifymailApi;
verifymailAuthKey = meta.verifymailAuthKey;
} }
function save() { function save() {
@ -167,6 +178,8 @@ function save() {
enableSensitiveMediaDetectionForVideos, enableSensitiveMediaDetectionForVideos,
enableIpLogging, enableIpLogging,
enableActiveEmailValidation, enableActiveEmailValidation,
enableVerifymailApi,
verifymailAuthKey,
}).then(() => { }).then(() => {
fetchInstance(); fetchInstance();
}); });

View file

@ -54,22 +54,24 @@ import { miLocalStorage } from '@/local-storage.js';
const { t, ts } = i18n; const { t, ts } = i18n;
const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'collapseRenotes',
'menu', 'menu',
'visibility', 'visibility',
'localOnly', 'localOnly',
'statusbars', 'statusbars',
'widgets', 'widgets',
'tl', 'tl',
'pinnedUserLists',
'overridedDeviceKind', 'overridedDeviceKind',
'serverDisconnectedBehavior', 'serverDisconnectedBehavior',
'collapseRenotes',
'showNoteActionsOnlyHover',
'nsfw', 'nsfw',
'highlightSensitiveMedia',
'animation', 'animation',
'animatedMfm', 'animatedMfm',
'advancedMfm', 'advancedMfm',
'loadRawImages', 'loadRawImages',
'imageNewTab', 'imageNewTab',
'enableDataSaverMode',
'disableShowingAnimatedImages', 'disableShowingAnimatedImages',
'emojiStyle', 'emojiStyle',
'disableDrawer', 'disableDrawer',
@ -89,9 +91,28 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'menuDisplay', 'menuDisplay',
'reportError', 'reportError',
'squareAvatars', 'squareAvatars',
'showAvatarDecorations',
'numberOfPageCache', 'numberOfPageCache',
'showNoteActionsOnlyHover',
'showClipButtonInNoteFooter',
'reactionsDisplaySize',
'forceShowAds',
'aiChanMode', 'aiChanMode',
'devMode',
'mediaListWithOneImageAppearance', 'mediaListWithOneImageAppearance',
'notificationPosition',
'notificationStackAxis',
'enableCondensedLineForAcct',
'keepScreenOn',
'defaultWithReplies',
'disableStreamingTimeline',
'useGroupedNotifications',
'sound_masterVolume',
'sound_note',
'sound_noteMy',
'sound_notification',
'sound_antenna',
'sound_channel',
]; ];
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
'lightTheme', 'lightTheme',

View file

@ -122,7 +122,7 @@ export const soundsTypes = [
'Copyright_Misskey.io/ThinaticSystem/yonderuzo3', 'Copyright_Misskey.io/ThinaticSystem/yonderuzo3',
] as const; ] as const;
export async function getAudio(file: string, useCache = true) { export async function loadAudio(file: string, useCache = true) {
if (useCache && cache.has(file)) { if (useCache && cache.has(file)) {
return cache.get(file)!; return cache.get(file)!;
} }
@ -138,12 +138,6 @@ export async function getAudio(file: string, useCache = true) {
return audioBuffer; return audioBuffer;
} }
export function setVolume(audio: HTMLAudioElement, volume: number): HTMLAudioElement {
const masterVolume = defaultStore.state.sound_masterVolume;
audio.volume = masterVolume - ((1 - volume) * masterVolume);
return audio;
}
export function play(type: 'noteMy' | 'note' | 'antenna' | 'channel' | 'notification') { export function play(type: 'noteMy' | 'note' | 'antenna' | 'channel' | 'notification') {
const sound = defaultStore.state[`sound_${type}`]; const sound = defaultStore.state[`sound_${type}`];
if (_DEV_) console.log('play', type, sound); if (_DEV_) console.log('play', type, sound);
@ -152,16 +146,22 @@ export function play(type: 'noteMy' | 'note' | 'antenna' | 'channel' | 'notifica
} }
export async function playFile(file: string, volume: number) { export async function playFile(file: string, volume: number) {
const buffer = await loadAudio(file);
createSourceNode(buffer, volume)?.start();
}
export function createSourceNode(buffer: AudioBuffer, volume: number) : AudioBufferSourceNode | null {
const masterVolume = defaultStore.state.sound_masterVolume; const masterVolume = defaultStore.state.sound_masterVolume;
if (masterVolume === 0 || volume === 0) { if (masterVolume === 0 || volume === 0) {
return; return null;
} }
const gainNode = ctx.createGain(); const gainNode = ctx.createGain();
gainNode.gain.value = masterVolume * volume; gainNode.gain.value = masterVolume * volume;
const soundSource = ctx.createBufferSource(); const soundSource = ctx.createBufferSource();
soundSource.buffer = await getAudio(file); soundSource.buffer = buffer;
soundSource.connect(gainNode).connect(ctx.destination); soundSource.connect(gainNode).connect(ctx.destination);
soundSource.start();
return soundSource;
} }

View file

@ -99,7 +99,10 @@ const current = reactive({
}, },
}); });
const prev = reactive({} as typeof current); const prev = reactive({} as typeof current);
const jammedSound = sound.setVolume(sound.getAudio('syuilo/queue-jammed'), 1); let jammedAudioBuffer: AudioBuffer | null = $ref(null);
let jammedSoundNodePlaying: boolean = $ref(false);
sound.loadAudio('syuilo/queue-jammed').then(buf => jammedAudioBuffer = buf);
for (const domain of ['inbox', 'deliver']) { for (const domain of ['inbox', 'deliver']) {
prev[domain] = deepClone(current[domain]); prev[domain] = deepClone(current[domain]);
@ -113,8 +116,13 @@ const onStats = (stats) => {
current[domain].waiting = stats[domain].waiting; current[domain].waiting = stats[domain].waiting;
current[domain].delayed = stats[domain].delayed; current[domain].delayed = stats[domain].delayed;
if (current[domain].waiting > 0 && widgetProps.sound && jammedSound.paused) { if (current[domain].waiting > 0 && widgetProps.sound && jammedAudioBuffer && !jammedSoundNodePlaying) {
jammedSound.play(); const soundNode = sound.createSourceNode(jammedAudioBuffer, 1);
if (soundNode) {
jammedSoundNodePlaying = true;
soundNode.onended = () => jammedSoundNodePlaying = false;
soundNode.start();
}
} }
} }
}; };

View file

@ -352,13 +352,13 @@ export type Endpoints = {
}; };
res: null; res: null;
}; };
'admin/delete-user-avatar': { 'admin/unset-user-avatar': {
req: { req: {
userId: User['id']; userId: User['id'];
}; };
res: null; res: null;
}; };
'admin/delete-user-banner': { 'admin/unset-user-banner': {
req: { req: {
userId: User['id']; userId: User['id'];
}; };
@ -2708,10 +2708,16 @@ type ModerationLog = {
} | { } | {
type: 'resolveAbuseReport'; type: 'resolveAbuseReport';
info: ModerationLogPayloads['resolveAbuseReport']; info: ModerationLogPayloads['resolveAbuseReport'];
} | {
type: 'unsetUserAvatar';
info: ModerationLogPayloads['unsetUserAvatar'];
} | {
type: 'unsetUserBanner';
info: ModerationLogPayloads['unsetUserBanner'];
}); });
// @public (undocumented) // @public (undocumented)
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration"]; export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner"];
// @public (undocumented) // @public (undocumented)
export const mutedNoteReasons: readonly ["word", "manual", "spam", "other"]; export const mutedNoteReasons: readonly ["word", "manual", "spam", "other"];

View file

@ -32,7 +32,7 @@
"jest-websocket-mock": "2.5.0", "jest-websocket-mock": "2.5.0",
"mock-socket": "9.3.1", "mock-socket": "9.3.1",
"tsd": "0.29.0", "tsd": "0.29.0",
"typescript": "5.2.2" "typescript": "5.3.2"
}, },
"files": [ "files": [
"built" "built"

View file

@ -15,8 +15,8 @@ export type Endpoints = {
// admin // admin
'admin/abuse-user-reports': { req: TODO; res: TODO; }; 'admin/abuse-user-reports': { req: TODO; res: TODO; };
'admin/delete-all-files-of-a-user': { req: { userId: User['id']; }; res: null; }; 'admin/delete-all-files-of-a-user': { req: { userId: User['id']; }; res: null; };
'admin/delete-user-avatar': { req: { userId: User['id']; }; res: null; }; 'admin/unset-user-avatar': { req: { userId: User['id']; }; res: null; };
'admin/delete-user-banner': { req: { userId: User['id']; }; res: null; }; 'admin/unset-user-banner': { req: { userId: User['id']; }; res: null; };
'admin/delete-logs': { req: NoParams; res: null; }; 'admin/delete-logs': { req: NoParams; res: null; };
'admin/get-index-stats': { req: TODO; res: TODO; }; 'admin/get-index-stats': { req: TODO; res: TODO; };
'admin/get-table-stats': { req: TODO; res: TODO; }; 'admin/get-table-stats': { req: TODO; res: TODO; };

View file

@ -81,6 +81,8 @@ export const moderationLogTypes = [
'createAvatarDecoration', 'createAvatarDecoration',
'updateAvatarDecoration', 'updateAvatarDecoration',
'deleteAvatarDecoration', 'deleteAvatarDecoration',
'unsetUserAvatar',
'unsetUserBanner',
] as const; ] as const;
export type ModerationLogPayloads = { export type ModerationLogPayloads = {
@ -255,4 +257,16 @@ export type ModerationLogPayloads = {
avatarDecorationId: string; avatarDecorationId: string;
avatarDecoration: any; avatarDecoration: any;
}; };
unsetUserAvatar: {
userId: string;
userUsername: string;
userHost: string | null;
fileId: string;
};
unsetUserBanner: {
userId: string;
userUsername: string;
userHost: string | null;
fileId: string;
};
}; };

View file

@ -737,4 +737,10 @@ export type ModerationLog = {
} | { } | {
type: 'resolveAbuseReport'; type: 'resolveAbuseReport';
info: ModerationLogPayloads['resolveAbuseReport']; info: ModerationLogPayloads['resolveAbuseReport'];
} | {
type: 'unsetUserAvatar';
info: ModerationLogPayloads['unsetUserAvatar'];
} | {
type: 'unsetUserBanner';
info: ModerationLogPayloads['unsetUserBanner'];
}); });

View file

@ -18,7 +18,7 @@
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.67", "@typescript/lib-webworker": "npm:@types/serviceworker@0.0.67",
"eslint": "8.53.0", "eslint": "8.53.0",
"eslint-plugin-import": "2.29.0", "eslint-plugin-import": "2.29.0",
"typescript": "5.2.2" "typescript": "5.3.2"
}, },
"type": "module" "type": "module"
} }

View file

@ -28,8 +28,8 @@ importers:
specifier: 5.24.0 specifier: 5.24.0
version: 5.24.0 version: 5.24.0
typescript: typescript:
specifier: 5.2.2 specifier: 5.3.2
version: 5.2.2 version: 5.3.2
optionalDependencies: optionalDependencies:
'@tensorflow/tfjs-core': '@tensorflow/tfjs-core':
specifier: 4.4.0 specifier: 4.4.0
@ -37,10 +37,10 @@ importers:
devDependencies: devDependencies:
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(eslint@8.53.0)(typescript@5.3.2)
cross-env: cross-env:
specifier: 7.0.3 specifier: 7.0.3
version: 7.0.3 version: 7.0.3
@ -381,8 +381,8 @@ importers:
specifier: 0.3.17 specifier: 0.3.17
version: 0.3.17(ioredis@5.3.2)(pg@8.11.3) version: 0.3.17(ioredis@5.3.2)(pg@8.11.3)
typescript: typescript:
specifier: 5.2.2 specifier: 5.3.2
version: 5.2.2 version: 5.3.2
ulid: ulid:
specifier: 2.3.0 specifier: 2.3.0
version: 2.3.0 version: 2.3.0
@ -615,10 +615,10 @@ importers:
version: 8.5.9 version: 8.5.9
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(eslint@8.53.0)(typescript@5.3.2)
aws-sdk-client-mock: aws-sdk-client-mock:
specifier: 3.0.0 specifier: 3.0.0
version: 3.0.0 version: 3.0.0
@ -663,7 +663,7 @@ importers:
version: 5.0.5(rollup@4.4.1) version: 5.0.5(rollup@4.4.1)
'@rollup/plugin-typescript': '@rollup/plugin-typescript':
specifier: 11.1.5 specifier: 11.1.5
version: 11.1.5(rollup@4.4.1)(typescript@5.2.2) version: 11.1.5(rollup@4.4.1)(typescript@5.3.2)
'@rollup/pluginutils': '@rollup/pluginutils':
specifier: 5.0.5 specifier: 5.0.5
version: 5.0.5(rollup@4.4.1) version: 5.0.5(rollup@4.4.1)
@ -809,8 +809,8 @@ importers:
specifier: 14.0.0 specifier: 14.0.0
version: 14.0.0 version: 14.0.0
typescript: typescript:
specifier: 5.2.2 specifier: 5.3.2
version: 5.2.2 version: 5.3.2
uuid: uuid:
specifier: 9.0.1 specifier: 9.0.1
version: 9.0.1 version: 9.0.1
@ -825,7 +825,7 @@ importers:
version: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0) version: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0)
vue: vue:
specifier: 3.3.8 specifier: 3.3.8
version: 3.3.8(typescript@5.2.2) version: 3.3.8(typescript@5.3.2)
vuedraggable: vuedraggable:
specifier: next specifier: next
version: 4.1.0(vue@3.3.8) version: 4.1.0(vue@3.3.8)
@ -865,10 +865,10 @@ importers:
version: 7.5.3 version: 7.5.3
'@storybook/react': '@storybook/react':
specifier: 7.5.3 specifier: 7.5.3
version: 7.5.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) version: 7.5.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2)
'@storybook/react-vite': '@storybook/react-vite':
specifier: 7.5.3 specifier: 7.5.3
version: 7.5.3(react-dom@18.2.0)(react@18.2.0)(rollup@4.4.1)(typescript@5.2.2)(vite@4.5.0) version: 7.5.3(react-dom@18.2.0)(react@18.2.0)(rollup@4.4.1)(typescript@5.3.2)(vite@4.5.0)
'@storybook/testing-library': '@storybook/testing-library':
specifier: 0.2.2 specifier: 0.2.2
version: 0.2.2 version: 0.2.2
@ -883,7 +883,7 @@ importers:
version: 7.5.3(@vue/compiler-core@3.3.8)(vue@3.3.8) version: 7.5.3(@vue/compiler-core@3.3.8)(vue@3.3.8)
'@storybook/vue3-vite': '@storybook/vue3-vite':
specifier: 7.5.3 specifier: 7.5.3
version: 7.5.3(@vue/compiler-core@3.3.8)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.8) version: 7.5.3(@vue/compiler-core@3.3.8)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2)(vite@4.5.0)(vue@3.3.8)
'@testing-library/vue': '@testing-library/vue':
specifier: 8.0.0 specifier: 8.0.0
version: 8.0.0(@vue/compiler-sfc@3.3.8)(vue@3.3.8) version: 8.0.0(@vue/compiler-sfc@3.3.8)(vue@3.3.8)
@ -925,10 +925,10 @@ importers:
version: 8.5.9 version: 8.5.9
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(eslint@8.53.0)(typescript@5.3.2)
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: 0.34.6 specifier: 0.34.6
version: 0.34.6(vitest@0.34.6) version: 0.34.6(vitest@0.34.6)
@ -964,7 +964,7 @@ importers:
version: 4.0.5 version: 4.0.5
msw: msw:
specifier: 1.3.2 specifier: 1.3.2
version: 1.3.2(typescript@5.2.2) version: 1.3.2(typescript@5.3.2)
msw-storybook-addon: msw-storybook-addon:
specifier: 1.10.0 specifier: 1.10.0
version: 1.10.0(msw@1.3.2) version: 1.10.0(msw@1.3.2)
@ -1006,7 +1006,7 @@ importers:
version: 9.3.2(eslint@8.53.0) version: 9.3.2(eslint@8.53.0)
vue-tsc: vue-tsc:
specifier: 1.8.22 specifier: 1.8.22
version: 1.8.22(typescript@5.2.2) version: 1.8.22(typescript@5.3.2)
packages/misskey-js: packages/misskey-js:
dependencies: dependencies:
@ -1037,10 +1037,10 @@ importers:
version: 20.9.1 version: 20.9.1
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(eslint@8.53.0)(typescript@5.3.2)
eslint: eslint:
specifier: 8.53.0 specifier: 8.53.0
version: 8.53.0 version: 8.53.0
@ -1060,8 +1060,8 @@ importers:
specifier: 0.29.0 specifier: 0.29.0
version: 0.29.0 version: 0.29.0
typescript: typescript:
specifier: 5.2.2 specifier: 5.3.2
version: 5.2.2 version: 5.3.2
packages/sw: packages/sw:
dependencies: dependencies:
@ -1077,7 +1077,7 @@ importers:
devDependencies: devDependencies:
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(eslint@8.53.0)(typescript@5.3.2)
'@typescript/lib-webworker': '@typescript/lib-webworker':
specifier: npm:@types/serviceworker@0.0.67 specifier: npm:@types/serviceworker@0.0.67
version: /@types/serviceworker@0.0.67 version: /@types/serviceworker@0.0.67
@ -1088,8 +1088,8 @@ importers:
specifier: 2.29.0 specifier: 2.29.0
version: 2.29.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0) version: 2.29.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)
typescript: typescript:
specifier: 5.2.2 specifier: 5.3.2
version: 5.2.2 version: 5.3.2
packages: packages:
@ -4257,7 +4257,7 @@ packages:
chalk: 4.1.2 chalk: 4.1.2
dev: true dev: true
/@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.2.2)(vite@4.5.0): /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.2)(vite@4.5.0):
resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==} resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==}
peerDependencies: peerDependencies:
typescript: '>= 4.3.x' typescript: '>= 4.3.x'
@ -4269,8 +4269,8 @@ packages:
glob: 7.2.3 glob: 7.2.3
glob-promise: 4.2.2(glob@7.2.3) glob-promise: 4.2.2(glob@7.2.3)
magic-string: 0.27.0 magic-string: 0.27.0
react-docgen-typescript: 2.2.2(typescript@5.2.2) react-docgen-typescript: 2.2.2(typescript@5.3.2)
typescript: 5.2.2 typescript: 5.3.2
vite: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0) vite: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0)
dev: true dev: true
@ -5261,7 +5261,7 @@ packages:
rollup: 4.4.1 rollup: 4.4.1
dev: false dev: false
/@rollup/plugin-typescript@11.1.5(rollup@4.4.1)(typescript@5.2.2): /@rollup/plugin-typescript@11.1.5(rollup@4.4.1)(typescript@5.3.2):
resolution: {integrity: sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==} resolution: {integrity: sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
peerDependencies: peerDependencies:
@ -5277,7 +5277,7 @@ packages:
'@rollup/pluginutils': 5.0.5(rollup@4.4.1) '@rollup/pluginutils': 5.0.5(rollup@4.4.1)
resolve: 1.22.3 resolve: 1.22.3
rollup: 4.4.1 rollup: 4.4.1
typescript: 5.2.2 typescript: 5.3.2
dev: false dev: false
/@rollup/pluginutils@5.0.5(rollup@4.4.1): /@rollup/pluginutils@5.0.5(rollup@4.4.1):
@ -6370,7 +6370,7 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@storybook/builder-vite@7.5.3(typescript@5.2.2)(vite@4.5.0): /@storybook/builder-vite@7.5.3(typescript@5.3.2)(vite@4.5.0):
resolution: {integrity: sha512-c104V3O75OCVnfZj0Jr70V09g0KSbPGvQK2Zh31omXGvakG8XrhWolYxkmjOcForJmAqsXnKs/nw3F75Gp853g==} resolution: {integrity: sha512-c104V3O75OCVnfZj0Jr70V09g0KSbPGvQK2Zh31omXGvakG8XrhWolYxkmjOcForJmAqsXnKs/nw3F75Gp853g==}
peerDependencies: peerDependencies:
'@preact/preset-vite': '*' '@preact/preset-vite': '*'
@ -6401,7 +6401,7 @@ packages:
fs-extra: 11.1.1 fs-extra: 11.1.1
magic-string: 0.30.5 magic-string: 0.30.5
rollup: 3.29.4 rollup: 3.29.4
typescript: 5.2.2 typescript: 5.3.2
vite: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0) vite: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0)
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
@ -6772,7 +6772,7 @@ packages:
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
dev: true dev: true
/@storybook/react-vite@7.5.3(react-dom@18.2.0)(react@18.2.0)(rollup@4.4.1)(typescript@5.2.2)(vite@4.5.0): /@storybook/react-vite@7.5.3(react-dom@18.2.0)(react@18.2.0)(rollup@4.4.1)(typescript@5.3.2)(vite@4.5.0):
resolution: {integrity: sha512-ArPyHgiPbT5YvcyK4xK/DfqBOpn4R4/EP3kfIGhx8QKJyOtxPEYFdkLIZ5xu3KnPX7/z7GT+4a6Rb+8sk9gliA==} resolution: {integrity: sha512-ArPyHgiPbT5YvcyK4xK/DfqBOpn4R4/EP3kfIGhx8QKJyOtxPEYFdkLIZ5xu3KnPX7/z7GT+4a6Rb+8sk9gliA==}
engines: {node: '>=16'} engines: {node: '>=16'}
peerDependencies: peerDependencies:
@ -6780,10 +6780,10 @@ packages:
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 vite: ^3.0.0 || ^4.0.0 || ^5.0.0
dependencies: dependencies:
'@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.2.2)(vite@4.5.0) '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.2)(vite@4.5.0)
'@rollup/pluginutils': 5.0.5(rollup@4.4.1) '@rollup/pluginutils': 5.0.5(rollup@4.4.1)
'@storybook/builder-vite': 7.5.3(typescript@5.2.2)(vite@4.5.0) '@storybook/builder-vite': 7.5.3(typescript@5.3.2)(vite@4.5.0)
'@storybook/react': 7.5.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) '@storybook/react': 7.5.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2)
'@vitejs/plugin-react': 3.1.0(vite@4.5.0) '@vitejs/plugin-react': 3.1.0(vite@4.5.0)
magic-string: 0.30.5 magic-string: 0.30.5
react: 18.2.0 react: 18.2.0
@ -6799,7 +6799,7 @@ packages:
- vite-plugin-glimmerx - vite-plugin-glimmerx
dev: true dev: true
/@storybook/react@7.5.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): /@storybook/react@7.5.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2):
resolution: {integrity: sha512-dZILdM36xMFDjdmmy421G5X+sOIncB2qF3IPTooniG1i1Z6v/dVNo57ovdID9lDTNa+AWr2fLB9hANiISMqmjQ==} resolution: {integrity: sha512-dZILdM36xMFDjdmmy421G5X+sOIncB2qF3IPTooniG1i1Z6v/dVNo57ovdID9lDTNa+AWr2fLB9hANiISMqmjQ==}
engines: {node: '>=16.0.0'} engines: {node: '>=16.0.0'}
peerDependencies: peerDependencies:
@ -6832,7 +6832,7 @@ packages:
react-element-to-jsx-string: 15.0.0(react-dom@18.2.0)(react@18.2.0) react-element-to-jsx-string: 15.0.0(react-dom@18.2.0)(react@18.2.0)
ts-dedent: 2.2.0 ts-dedent: 2.2.0
type-fest: 2.19.0 type-fest: 2.19.0
typescript: 5.2.2 typescript: 5.3.2
util-deprecate: 1.0.2 util-deprecate: 1.0.2
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
@ -6914,7 +6914,7 @@ packages:
file-system-cache: 2.3.0 file-system-cache: 2.3.0
dev: true dev: true
/@storybook/vue3-vite@7.5.3(@vue/compiler-core@3.3.8)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.8): /@storybook/vue3-vite@7.5.3(@vue/compiler-core@3.3.8)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2)(vite@4.5.0)(vue@3.3.8):
resolution: {integrity: sha512-gkNwDDn2AKthAtaoPrHb0+2gi33UluxpfSq/M5COoMEVFphj6y/jyDa+OEYlceXgnD8g2xvX4/yv2TbTNDzmcQ==} resolution: {integrity: sha512-gkNwDDn2AKthAtaoPrHb0+2gi33UluxpfSq/M5COoMEVFphj6y/jyDa+OEYlceXgnD8g2xvX4/yv2TbTNDzmcQ==}
engines: {node: ^14.18 || >=16} engines: {node: ^14.18 || >=16}
peerDependencies: peerDependencies:
@ -6922,7 +6922,7 @@ packages:
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 vite: ^3.0.0 || ^4.0.0 || ^5.0.0
dependencies: dependencies:
'@storybook/builder-vite': 7.5.3(typescript@5.2.2)(vite@4.5.0) '@storybook/builder-vite': 7.5.3(typescript@5.3.2)(vite@4.5.0)
'@storybook/core-server': 7.5.3 '@storybook/core-server': 7.5.3
'@storybook/vue3': 7.5.3(@vue/compiler-core@3.3.8)(vue@3.3.8) '@storybook/vue3': 7.5.3(@vue/compiler-core@3.3.8)(vue@3.3.8)
'@vitejs/plugin-vue': 4.5.0(vite@4.5.0)(vue@3.3.8) '@vitejs/plugin-vue': 4.5.0(vite@4.5.0)(vue@3.3.8)
@ -6959,7 +6959,7 @@ packages:
lodash: 4.17.21 lodash: 4.17.21
ts-dedent: 2.2.0 ts-dedent: 2.2.0
type-fest: 2.19.0 type-fest: 2.19.0
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
vue-component-type-helpers: 1.8.22 vue-component-type-helpers: 1.8.22
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
@ -7454,7 +7454,7 @@ packages:
'@testing-library/dom': 9.3.3 '@testing-library/dom': 9.3.3
'@vue/compiler-sfc': 3.3.8 '@vue/compiler-sfc': 3.3.8
'@vue/test-utils': 2.4.1(vue@3.3.8) '@vue/test-utils': 2.4.1(vue@3.3.8)
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
transitivePeerDependencies: transitivePeerDependencies:
- '@vue/server-renderer' - '@vue/server-renderer'
dev: true dev: true
@ -8095,7 +8095,7 @@ packages:
dev: true dev: true
optional: true optional: true
/@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.3.2):
resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==} resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
@ -8107,10 +8107,10 @@ packages:
optional: true optional: true
dependencies: dependencies:
'@eslint-community/regexpp': 4.6.2 '@eslint-community/regexpp': 4.6.2
'@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/scope-manager': 6.11.0
'@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.2)
'@typescript-eslint/visitor-keys': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0 eslint: 8.53.0
@ -8118,13 +8118,13 @@ packages:
ignore: 5.2.4 ignore: 5.2.4
natural-compare: 1.4.0 natural-compare: 1.4.0
semver: 7.5.4 semver: 7.5.4
ts-api-utils: 1.0.1(typescript@5.2.2) ts-api-utils: 1.0.1(typescript@5.3.2)
typescript: 5.2.2 typescript: 5.3.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.2):
resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==} resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
@ -8136,11 +8136,11 @@ packages:
dependencies: dependencies:
'@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/scope-manager': 6.11.0
'@typescript-eslint/types': 6.11.0 '@typescript-eslint/types': 6.11.0
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.2)
'@typescript-eslint/visitor-keys': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0 eslint: 8.53.0
typescript: 5.2.2 typescript: 5.3.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -8153,7 +8153,7 @@ packages:
'@typescript-eslint/visitor-keys': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0
dev: true dev: true
/@typescript-eslint/type-utils@6.11.0(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/type-utils@6.11.0(eslint@8.53.0)(typescript@5.3.2):
resolution: {integrity: sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==} resolution: {integrity: sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
@ -8163,12 +8163,12 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.2)
'@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.2)
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0 eslint: 8.53.0
ts-api-utils: 1.0.1(typescript@5.2.2) ts-api-utils: 1.0.1(typescript@5.3.2)
typescript: 5.2.2 typescript: 5.3.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -8178,7 +8178,7 @@ packages:
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
dev: true dev: true
/@typescript-eslint/typescript-estree@6.11.0(typescript@5.2.2): /@typescript-eslint/typescript-estree@6.11.0(typescript@5.3.2):
resolution: {integrity: sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==} resolution: {integrity: sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
@ -8193,13 +8193,13 @@ packages:
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
semver: 7.5.4 semver: 7.5.4
ts-api-utils: 1.0.1(typescript@5.2.2) ts-api-utils: 1.0.1(typescript@5.3.2)
typescript: 5.2.2 typescript: 5.3.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/utils@6.11.0(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/utils@6.11.0(eslint@8.53.0)(typescript@5.3.2):
resolution: {integrity: sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==} resolution: {integrity: sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
@ -8210,7 +8210,7 @@ packages:
'@types/semver': 7.5.5 '@types/semver': 7.5.5
'@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/scope-manager': 6.11.0
'@typescript-eslint/types': 6.11.0 '@typescript-eslint/types': 6.11.0
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.2)
eslint: 8.53.0 eslint: 8.53.0
semver: 7.5.4 semver: 7.5.4
transitivePeerDependencies: transitivePeerDependencies:
@ -8254,7 +8254,7 @@ packages:
vue: ^3.2.25 vue: ^3.2.25
dependencies: dependencies:
vite: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0) vite: 4.5.0(@types/node@20.9.1)(sass@1.69.5)(terser@5.24.0)
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
/@vitest/coverage-v8@0.34.6(vitest@0.34.6): /@vitest/coverage-v8@0.34.6(vitest@0.34.6):
resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==} resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==}
@ -8349,7 +8349,7 @@ packages:
ast-kit: 0.11.2(rollup@4.4.1) ast-kit: 0.11.2(rollup@4.4.1)
local-pkg: 0.5.0 local-pkg: 0.5.0
magic-string-ast: 0.3.0 magic-string-ast: 0.3.0
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
dev: false dev: false
@ -8366,7 +8366,7 @@ packages:
'@vue/shared': 3.3.8 '@vue/shared': 3.3.8
magic-string: 0.30.5 magic-string: 0.30.5
unplugin: 1.5.1 unplugin: 1.5.1
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
dev: false dev: false
@ -8437,7 +8437,7 @@ packages:
'@vue/compiler-dom': 3.3.8 '@vue/compiler-dom': 3.3.8
'@vue/shared': 3.3.8 '@vue/shared': 3.3.8
/@vue/language-core@1.8.22(typescript@5.2.2): /@vue/language-core@1.8.22(typescript@5.3.2):
resolution: {integrity: sha512-bsMoJzCrXZqGsxawtUea1cLjUT9dZnDsy5TuZ+l1fxRMzUGQUG9+Ypq4w//CqpWmrx7nIAJpw2JVF/t258miRw==} resolution: {integrity: sha512-bsMoJzCrXZqGsxawtUea1cLjUT9dZnDsy5TuZ+l1fxRMzUGQUG9+Ypq4w//CqpWmrx7nIAJpw2JVF/t258miRw==}
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
@ -8452,7 +8452,7 @@ packages:
computeds: 0.0.1 computeds: 0.0.1
minimatch: 9.0.3 minimatch: 9.0.3
muggle-string: 0.3.1 muggle-string: 0.3.1
typescript: 5.2.2 typescript: 5.3.2
vue-template-compiler: 2.7.14 vue-template-compiler: 2.7.14
dev: true dev: true
@ -8490,7 +8490,7 @@ packages:
dependencies: dependencies:
'@vue/compiler-ssr': 3.3.8 '@vue/compiler-ssr': 3.3.8
'@vue/shared': 3.3.8 '@vue/shared': 3.3.8
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
/@vue/shared@3.3.6: /@vue/shared@3.3.6:
resolution: {integrity: sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ==} resolution: {integrity: sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ==}
@ -8513,7 +8513,7 @@ packages:
optional: true optional: true
dependencies: dependencies:
js-beautify: 1.14.9 js-beautify: 1.14.9
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
vue-component-type-helpers: 1.8.4 vue-component-type-helpers: 1.8.4
dev: true dev: true
@ -11180,7 +11180,7 @@ packages:
eslint-import-resolver-webpack: eslint-import-resolver-webpack:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.2)
debug: 3.2.7(supports-color@5.5.0) debug: 3.2.7(supports-color@5.5.0)
eslint: 8.53.0 eslint: 8.53.0
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
@ -11198,7 +11198,7 @@ packages:
'@typescript-eslint/parser': '@typescript-eslint/parser':
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.2)
array-includes: 3.1.7 array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3 array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.2 array.prototype.flat: 1.3.2
@ -14862,10 +14862,10 @@ packages:
msw: '>=0.35.0 <2.0.0' msw: '>=0.35.0 <2.0.0'
dependencies: dependencies:
is-node-process: 1.2.0 is-node-process: 1.2.0
msw: 1.3.2(typescript@5.2.2) msw: 1.3.2(typescript@5.3.2)
dev: true dev: true
/msw@1.3.2(typescript@5.2.2): /msw@1.3.2(typescript@5.3.2):
resolution: {integrity: sha512-wKLhFPR+NitYTkQl5047pia0reNGgf0P6a1eTnA5aNlripmiz0sabMvvHcicE8kQ3/gZcI0YiPFWmYfowfm3lA==} resolution: {integrity: sha512-wKLhFPR+NitYTkQl5047pia0reNGgf0P6a1eTnA5aNlripmiz0sabMvvHcicE8kQ3/gZcI0YiPFWmYfowfm3lA==}
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
@ -14894,7 +14894,7 @@ packages:
path-to-regexp: 6.2.1 path-to-regexp: 6.2.1
strict-event-emitter: 0.4.6 strict-event-emitter: 0.4.6
type-fest: 2.19.0 type-fest: 2.19.0
typescript: 5.2.2 typescript: 5.3.2
yargs: 17.6.2 yargs: 17.6.2
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
@ -16783,12 +16783,12 @@ packages:
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
dev: true dev: true
/react-docgen-typescript@2.2.2(typescript@5.2.2): /react-docgen-typescript@2.2.2(typescript@5.3.2):
resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==}
peerDependencies: peerDependencies:
typescript: '>= 4.3.x' typescript: '>= 4.3.x'
dependencies: dependencies:
typescript: 5.2.2 typescript: 5.3.2
dev: true dev: true
/react-docgen@6.0.4: /react-docgen@6.0.4:
@ -18636,13 +18636,13 @@ packages:
escape-string-regexp: 5.0.0 escape-string-regexp: 5.0.0
dev: false dev: false
/ts-api-utils@1.0.1(typescript@5.2.2): /ts-api-utils@1.0.1(typescript@5.3.2):
resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==}
engines: {node: '>=16.13.0'} engines: {node: '>=16.13.0'}
peerDependencies: peerDependencies:
typescript: '>=4.2.0' typescript: '>=4.2.0'
dependencies: dependencies:
typescript: 5.2.2 typescript: 5.3.2
dev: true dev: true
/ts-dedent@2.2.0: /ts-dedent@2.2.0:
@ -18906,8 +18906,8 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/typescript@5.2.2: /typescript@5.3.2:
resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==}
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
@ -19195,7 +19195,7 @@ packages:
diff: 5.1.0 diff: 5.1.0
diff-match-patch: 1.0.5 diff-match-patch: 1.0.5
highlight.js: 11.8.0 highlight.js: 11.8.0
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
vue-demi: 0.13.11(vue@3.3.8) vue-demi: 0.13.11(vue@3.3.8)
dev: false dev: false
@ -19409,7 +19409,7 @@ packages:
'@vue/composition-api': '@vue/composition-api':
optional: true optional: true
dependencies: dependencies:
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
dev: false dev: false
/vue-docgen-api@4.64.1(vue@3.3.8): /vue-docgen-api@4.64.1(vue@3.3.8):
@ -19453,7 +19453,7 @@ packages:
peerDependencies: peerDependencies:
vue: '>=2' vue: '>=2'
dependencies: dependencies:
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
dev: true dev: true
/vue-template-compiler@2.7.14: /vue-template-compiler@2.7.14:
@ -19463,19 +19463,19 @@ packages:
he: 1.2.0 he: 1.2.0
dev: true dev: true
/vue-tsc@1.8.22(typescript@5.2.2): /vue-tsc@1.8.22(typescript@5.3.2):
resolution: {integrity: sha512-j9P4kHtW6eEE08aS5McFZE/ivmipXy0JzrnTgbomfABMaVKx37kNBw//irL3+LlE3kOo63XpnRigyPC3w7+z+A==} resolution: {integrity: sha512-j9P4kHtW6eEE08aS5McFZE/ivmipXy0JzrnTgbomfABMaVKx37kNBw//irL3+LlE3kOo63XpnRigyPC3w7+z+A==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
dependencies: dependencies:
'@volar/typescript': 1.10.7 '@volar/typescript': 1.10.7
'@vue/language-core': 1.8.22(typescript@5.2.2) '@vue/language-core': 1.8.22(typescript@5.3.2)
semver: 7.5.4 semver: 7.5.4
typescript: 5.2.2 typescript: 5.3.2
dev: true dev: true
/vue@3.3.8(typescript@5.2.2): /vue@3.3.8(typescript@5.3.2):
resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==}
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
@ -19488,7 +19488,7 @@ packages:
'@vue/runtime-dom': 3.3.8 '@vue/runtime-dom': 3.3.8
'@vue/server-renderer': 3.3.8(vue@3.3.8) '@vue/server-renderer': 3.3.8(vue@3.3.8)
'@vue/shared': 3.3.8 '@vue/shared': 3.3.8
typescript: 5.2.2 typescript: 5.3.2
/vuedraggable@4.1.0(vue@3.3.8): /vuedraggable@4.1.0(vue@3.3.8):
resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==}
@ -19496,7 +19496,7 @@ packages:
vue: ^3.0.1 vue: ^3.0.1
dependencies: dependencies:
sortablejs: 1.14.0 sortablejs: 1.14.0
vue: 3.3.8(typescript@5.2.2) vue: 3.3.8(typescript@5.3.2)
dev: false dev: false
/w3c-xmlserializer@4.0.0: /w3c-xmlserializer@4.0.0: