Merge branch 'develop' into sensitive-dsv

This commit is contained in:
かっこかり 2023-09-21 15:59:41 +09:00 committed by GitHub
commit 5fd6091982
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 128 additions and 86 deletions

View file

@ -26,6 +26,7 @@
- Feat: 二要素認証のバックアップコードが生成されるようになりました
- ref. https://github.com/MisskeyIO/misskey/pull/121
- Feat: 二要素認証でパスキーをサポートするようになりました
- Feat: プロフィールでのリンク検証
- Feat: 通知をテストできるようになりました
- Feat: PWAのアイコンが設定できるようになりました
- Enhance: manifest.jsonをオーバーライド可能に

2
locales/index.d.ts vendored
View file

@ -1117,6 +1117,7 @@ export interface Locale {
"loadConversation": string;
"pinnedList": string;
"keepScreenOn": string;
"verifiedLink": string;
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;
@ -2021,6 +2022,7 @@ export interface Locale {
"metadataContent": string;
"changeAvatar": string;
"changeBanner": string;
"verifiedLinkDescription": string;
};
"_exportOrImport": {
"allNotes": string;

View file

@ -1114,6 +1114,7 @@ loadReplies: "返信を見る"
loadConversation: "会話を見る"
pinnedList: "ピン留めされたリスト"
keepScreenOn: "デバイスの画面を常にオンにする"
verifiedLink: "このリンク先の所有者であることが確認されました"
_announcement:
forExistingUsers: "既存ユーザーのみ"
@ -1936,6 +1937,7 @@ _profile:
metadataContent: "内容"
changeAvatar: "アイコン画像を変更"
changeBanner: "バナー画像を変更"
verifiedLinkDescription: "内容にURLを設定すると、リンク先のWebサイトに自分のプロフィールへのリンクが含まれている場合に所有者確認済みアイコンを表示させることができます。"
_exportOrImport:
allNotes: "全てのノート"

View file

@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "2023.9.0-beta.9",
"version": "2023.9.0-beta.10",
"codename": "nasubi",
"repository": {
"type": "git",

View file

@ -0,0 +1,11 @@
export class VerifiedLinks1695260774117 {
name = 'VerifiedLinks1695260774117'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "verifiedLinks" character varying array NOT NULL DEFAULT '{}'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "verifiedLinks"`);
}
}

View file

@ -384,6 +384,7 @@ export class UserEntityService implements OnModuleInit {
birthday: profile!.birthday,
lang: profile!.lang,
fields: profile!.fields,
verifiedLinks: profile!.verifiedLinks,
followersCount: followersCount ?? 0,
followingCount: followingCount ?? 0,
notesCount: user.notesCount,

View file

@ -48,6 +48,12 @@ export class MiUserProfile {
value: string;
}[];
@Column('varchar', {
array: true,
default: '{}',
})
public verifiedLinks: string[];
@Column('varchar', {
length: 32, nullable: true,
})

View file

@ -169,6 +169,15 @@ export const packedUserDetailedNotMeOnlySchema = {
},
},
},
verifiedLinks: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'string',
nullable: false, optional: false,
format: 'url',
},
},
followersCount: {
type: 'number',
nullable: false, optional: false,

View file

@ -6,11 +6,13 @@
import RE2 from 're2';
import * as mfm from 'mfm-js';
import { Inject, Injectable } from '@nestjs/common';
import ms from 'ms';
import { JSDOM } from 'jsdom';
import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js';
import { extractHashtags } from '@/misc/extract-hashtags.js';
import * as Acct from '@/misc/acct.js';
import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository } from '@/models/_.js';
import type { MiUser } from '@/models/User.js';
import type { MiLocalUser, MiUser } from '@/models/User.js';
import { birthdaySchema, descriptionSchema, locationSchema, nameSchema } from '@/models/User.js';
import type { MiUserProfile } from '@/models/UserProfile.js';
import { notificationTypes } from '@/types.js';
@ -27,6 +29,9 @@ import { RoleService } from '@/core/RoleService.js';
import { CacheService } from '@/core/CacheService.js';
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import type { Config } from '@/config.js';
import { safeForSql } from '@/misc/safe-for-sql.js';
import { ApiLoggerService } from '../../ApiLoggerService.js';
import { ApiError } from '../../error.js';
@ -37,6 +42,11 @@ export const meta = {
kind: 'write:account',
limit: {
duration: ms('1hour'),
max: 10,
},
errors: {
noSuchAvatar: {
message: 'No such avatar file.',
@ -173,6 +183,9 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.config)
private config: Config,
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@ -195,9 +208,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private hashtagService: HashtagService,
private roleService: RoleService,
private cacheService: CacheService,
private httpRequestService: HttpRequestService,
) {
super(meta, paramDef, async (ps, _user, token) => {
const user = await this.usersRepository.findOneByOrFail({ id: _user.id });
const user = await this.usersRepository.findOneByOrFail({ id: _user.id }) as MiLocalUser;
const isSecure = token == null;
const updates = {} as Partial<MiUser>;
@ -296,9 +310,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (ps.fields) {
profileUpdates.fields = ps.fields
.filter(x => typeof x.name === 'string' && x.name !== '' && typeof x.value === 'string' && x.value !== '')
.filter(x => typeof x.name === 'string' && x.name.trim() !== '' && typeof x.value === 'string' && x.value.trim() !== '')
.map(x => {
return { name: x.name, value: x.value };
return { name: x.name.trim(), value: x.value.trim() };
});
}
@ -364,7 +378,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (Object.keys(updates).includes('alsoKnownAs')) {
this.cacheService.uriPersonCache.set(this.userEntityService.genLocalUserUri(user.id), { ...user, ...updates });
}
if (Object.keys(profileUpdates).length > 0) await this.userProfilesRepository.update(user.id, profileUpdates);
await this.userProfilesRepository.update(user.id, {
...profileUpdates,
verifiedLinks: [],
});
const iObj = await this.userEntityService.pack<true, true>(user.id, user, {
detail: true,
@ -386,7 +404,34 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
// フォロワーにUpdateを配信
this.accountUpdateService.publishToFollowers(user.id);
const urls = updatedProfile.fields.filter(x => x.value.startsWith('https://'));
for (const url of urls) {
this.verifyLink(url.value, user);
}
return iObj;
});
}
private async verifyLink(url: string, user: MiLocalUser) {
if (!safeForSql(url)) return;
const html = await this.httpRequestService.getHtml(url);
const { window } = new JSDOM(html);
const doc = window.document;
const myLink = `${this.config.url}/@${user.username}`;
const includesMyLink = Array.from(doc.getElementsByTagName('a')).some(a => a.href === myLink);
if (includesMyLink) {
await this.userProfilesRepository.createQueryBuilder('profile').update()
.where('userId = :userId', { userId: user.id })
.set({
verifiedLinks: () => `array_append("verifiedLinks", '${url}')`, // ここでSQLインジェクションされそうなのでとりあえず safeForSql で弾いている
})
.execute();
}
}
}

View file

@ -102,6 +102,7 @@ describe('ユーザー', () => {
birthday: user.birthday,
lang: user.lang,
fields: user.fields,
verifiedLinks: user.verifiedLinks,
followersCount: user.followersCount,
followingCount: user.followingCount,
notesCount: user.notesCount,
@ -369,6 +370,7 @@ describe('ユーザー', () => {
assert.strictEqual(response.birthday, null);
assert.strictEqual(response.lang, null);
assert.deepStrictEqual(response.fields, []);
assert.deepStrictEqual(response.verifiedLinks, []);
assert.strictEqual(response.followersCount, 0);
assert.strictEqual(response.followingCount, 0);
assert.strictEqual(response.notesCount, 0);

View file

@ -89,6 +89,7 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host = 'mi
value: 'https://misskey-hub.net',
},
],
verifiedLinks: [],
followersCount: 1024,
followingCount: 16,
hasPendingFollowRequestFromYou: false,

View file

@ -59,13 +59,13 @@
"querystring": "0.2.1",
"rollup": "3.29.2",
"sanitize-html": "2.11.0",
"sass": "1.67.0",
"sass": "1.68.0",
"strict-event-emitter-types": "2.0.0",
"textarea-caret": "3.1.0",
"three": "0.156.1",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tsc-alias": "1.8.7",
"tsc-alias": "1.8.8",
"tsconfig-paths": "4.2.0",
"twemoji-parser": "14.0.0",
"typescript": "5.2.2",

View file

@ -76,6 +76,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</template>
</Sortable>
<MkInfo>{{ i18n.ts._profile.verifiedLinkDescription }}</MkInfo>
</div>
</MkFolder>
<template #caption>{{ i18n.ts._profile.metadataDescription }}</template>
@ -119,6 +121,7 @@ import { langmap } from '@/scripts/langmap.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import { claimAchievement } from '@/scripts/achievements.js';
import { defaultStore } from '@/store.js';
import MkInfo from '@/components/MkInfo.vue';
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));

View file

@ -101,6 +101,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</dt>
<dd class="value">
<Mfm :text="field.value" :author="user" :i="$i" :colored="false"/>
<i v-if="user.verifiedLinks.includes(field.value)" v-tooltip:dialog="i18n.ts.verifiedLink" class="ti ti-circle-check" :class="$style.verifiedLink"></i>
</dd>
</dl>
</div>
@ -671,7 +672,12 @@ onUnmounted(() => {
<style lang="scss" module>
.tl {
background: var(--bg);
border-radius: var(--radius);
overflow: clip;
border-radius: var(--radius);
overflow: clip;
}
.verifiedLink {
margin-left: 4px;
color: var(--success);
}
</style>

View file

@ -2778,6 +2778,7 @@ type UserDetailed = UserLite & {
name: string;
value: string;
}[];
verifiedLinks: string[];
followersCount: number;
followingCount: number;
hasPendingFollowRequestFromYou: boolean;

View file

@ -38,6 +38,7 @@ export type UserDetailed = UserLite & {
description: string | null;
ffVisibility: 'public' | 'followers' | 'private';
fields: {name: string; value: string}[];
verifiedLinks: string[];
followersCount: number;
followingCount: number;
hasPendingFollowRequestFromYou: boolean;

View file

@ -770,8 +770,8 @@ importers:
specifier: 2.11.0
version: 2.11.0
sass:
specifier: 1.67.0
version: 1.67.0
specifier: 1.68.0
version: 1.68.0
strict-event-emitter-types:
specifier: 2.0.0
version: 2.0.0
@ -788,8 +788,8 @@ importers:
specifier: 1.6.0
version: 1.6.0
tsc-alias:
specifier: 1.8.7
version: 1.8.7
specifier: 1.8.8
version: 1.8.8
tsconfig-paths:
specifier: 4.2.0
version: 4.2.0
@ -807,7 +807,7 @@ importers:
version: 1.8.1
vite:
specifier: 4.4.9
version: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
version: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
vue:
specifier: 3.3.4
version: 3.3.4
@ -976,7 +976,7 @@ importers:
version: 7.4.2
storybook-addon-misskey-theme:
specifier: github:misskey-dev/storybook-addon-misskey-theme
version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.4.3)(@storybook/components@7.4.2)(@storybook/core-events@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(@storybook/types@7.4.3)(react-dom@18.2.0)(react@18.2.0)
version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.4.3)(@storybook/components@7.4.3)(@storybook/core-events@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(@storybook/types@7.4.3)(react-dom@18.2.0)(react@18.2.0)
summaly:
specifier: github:misskey-dev/summaly
version: github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7
@ -985,7 +985,7 @@ importers:
version: 1.0.3
vitest:
specifier: 0.34.4
version: 0.34.4(happy-dom@10.0.3)(sass@1.67.0)(terser@5.20.0)
version: 0.34.4(happy-dom@10.0.3)(sass@1.68.0)(terser@5.20.0)
vitest-fetch-mock:
specifier: 0.2.2
version: 0.2.2(vitest@0.34.4)
@ -4262,7 +4262,7 @@ packages:
magic-string: 0.27.0
react-docgen-typescript: 2.2.2(typescript@5.2.2)
typescript: 5.2.2
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
dev: true
/@jridgewell/gen-mapping@0.3.2:
@ -6300,7 +6300,7 @@ packages:
remark-slug: 6.1.0
rollup: 3.29.2
typescript: 5.2.2
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
transitivePeerDependencies:
- encoding
- supports-color
@ -6413,29 +6413,6 @@ packages:
- supports-color
dev: true
/@storybook/components@7.4.2(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-ecbDzSUd74vf6IwHsbQr+9mVRxKWLmwd9zJ8RHMcR8UejTRAAR/eVvYoCG331TQ8TrhTmHTy5xCVv47pm6ORkQ==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@radix-ui/react-select': 1.2.2(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-toolbar': 1.0.4(react-dom@18.2.0)(react@18.2.0)
'@storybook/client-logger': 7.4.2
'@storybook/csf': 0.1.0
'@storybook/global': 5.0.0
'@storybook/theming': 7.4.2(react-dom@18.2.0)(react@18.2.0)
'@storybook/types': 7.4.2
memoizerific: 1.11.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0)
util-deprecate: 1.0.2
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
dev: true
/@storybook/components@7.4.3(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-qwRW8wGUuM+H6oKUXXoIDrZECXh/lzowrWXFAzZiocovYEhPtZfl/yvJLWHjOwtka3n7lA7J7EtcjWe8/tueJQ==}
peerDependencies:
@ -6861,7 +6838,7 @@ packages:
react: 18.2.0
react-docgen: 6.0.0-alpha.3
react-dom: 18.2.0(react@18.2.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
transitivePeerDependencies:
- '@preact/preset-vite'
- encoding
@ -6979,20 +6956,6 @@ packages:
ts-dedent: 2.2.0
dev: true
/@storybook/theming@7.4.2(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-wVmxZHVCqDoZgUOXTS4HRV4UClLtCydRNOEuUZ7X08QIPSA1FVL3gEpTQJfgCsyBX/cwSSofAMUbzAGEVNo+9g==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0)
'@storybook/client-logger': 7.4.2
'@storybook/global': 5.0.0
memoizerific: 1.11.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: true
/@storybook/theming@7.4.3(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-u5wLwWmhGcTmkcs6f2wDGv+w8wzwbNJat0WaIIbwdJfX7arH6nO5HkBhNxvl6FUFxX0tovp/e9ULzxVPc356jw==}
peerDependencies:
@ -7040,7 +7003,7 @@ packages:
magic-string: 0.30.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
vue-docgen-api: 4.64.1(vue@3.3.4)
transitivePeerDependencies:
- '@preact/preset-vite'
@ -7524,7 +7487,7 @@ packages:
dom-accessibility-api: 0.5.16
lodash: 4.17.21
redent: 3.0.0
vitest: 0.34.4(happy-dom@10.0.3)(sass@1.67.0)(terser@5.20.0)
vitest: 0.34.4(happy-dom@10.0.3)(sass@1.68.0)(terser@5.20.0)
dev: true
/@testing-library/user-event@14.4.3(@testing-library/dom@9.2.0):
@ -8322,7 +8285,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.22.11)
magic-string: 0.27.0
react-refresh: 0.14.0
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
transitivePeerDependencies:
- supports-color
dev: true
@ -8334,7 +8297,7 @@ packages:
vite: ^4.0.0
vue: ^3.2.25
dependencies:
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
vue: 3.3.4
/@vitest/coverage-v8@0.34.4(vitest@0.34.4):
@ -8353,7 +8316,7 @@ packages:
std-env: 3.3.3
test-exclude: 6.0.0
v8-to-istanbul: 9.1.0
vitest: 0.34.4(happy-dom@10.0.3)(sass@1.67.0)(terser@5.20.0)
vitest: 0.34.4(happy-dom@10.0.3)(sass@1.68.0)(terser@5.20.0)
transitivePeerDependencies:
- supports-color
dev: true
@ -17407,8 +17370,8 @@ packages:
postcss: 8.4.30
dev: false
/sass@1.67.0:
resolution: {integrity: sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A==}
/sass@1.68.0:
resolution: {integrity: sha512-Lmj9lM/fef0nQswm1J2HJcEsBUba4wgNx2fea6yJHODREoMFnwRpZydBnX/RjyXw2REIwdkbqE4hrTo4qfDBUA==}
engines: {node: '>=14.0.0'}
hasBin: true
dependencies:
@ -18622,18 +18585,6 @@ packages:
resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==}
dev: true
/tsc-alias@1.8.7:
resolution: {integrity: sha512-59Q/zUQa3miTf99mLbSqaW0hi1jt4WoG8Uhe5hSZJHQpSoFW9eEwvW7jlKMHXWvT+zrzy3SN9PE/YBhQ+WVydA==}
hasBin: true
dependencies:
chokidar: 3.5.3
commander: 9.5.0
globby: 11.1.0
mylas: 2.1.13
normalize-path: 3.0.0
plimit-lit: 1.5.0
dev: false
/tsc-alias@1.8.8:
resolution: {integrity: sha512-OYUOd2wl0H858NvABWr/BoSKNERw3N9GTi3rHPK8Iv4O1UyUXIrTTOAZNHsjlVpXFOhpJBVARI1s+rzwLivN3Q==}
hasBin: true
@ -19183,7 +19134,7 @@ packages:
core-util-is: 1.0.2
extsprintf: 1.3.0
/vite-node@0.34.4(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0):
/vite-node@0.34.4(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0):
resolution: {integrity: sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==}
engines: {node: '>=v14.18.0'}
hasBin: true
@ -19193,7 +19144,7 @@ packages:
mlly: 1.4.0
pathe: 1.1.1
picocolors: 1.0.0
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
transitivePeerDependencies:
- '@types/node'
- less
@ -19209,7 +19160,7 @@ packages:
resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==}
dev: true
/vite@4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0):
/vite@4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0):
resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
@ -19241,7 +19192,7 @@ packages:
esbuild: 0.18.17
postcss: 8.4.30
rollup: 3.29.2
sass: 1.67.0
sass: 1.68.0
terser: 5.20.0
optionalDependencies:
fsevents: 2.3.2
@ -19253,12 +19204,12 @@ packages:
vitest: '>=0.16.0'
dependencies:
cross-fetch: 3.1.5
vitest: 0.34.4(happy-dom@10.0.3)(sass@1.67.0)(terser@5.20.0)
vitest: 0.34.4(happy-dom@10.0.3)(sass@1.68.0)(terser@5.20.0)
transitivePeerDependencies:
- encoding
dev: true
/vitest@0.34.4(happy-dom@10.0.3)(sass@1.67.0)(terser@5.20.0):
/vitest@0.34.4(happy-dom@10.0.3)(sass@1.68.0)(terser@5.20.0):
resolution: {integrity: sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==}
engines: {node: '>=v14.18.0'}
hasBin: true
@ -19311,8 +19262,8 @@ packages:
strip-literal: 1.0.1
tinybench: 2.5.0
tinypool: 0.7.0
vite: 4.4.9(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite-node: 0.34.4(@types/node@20.6.3)(sass@1.67.0)(terser@5.20.0)
vite: 4.4.9(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
vite-node: 0.34.4(@types/node@20.6.3)(sass@1.68.0)(terser@5.20.0)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
@ -19855,7 +19806,7 @@ packages:
sharp: 0.31.3
dev: false
github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.4.3)(@storybook/components@7.4.2)(@storybook/core-events@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(@storybook/types@7.4.3)(react-dom@18.2.0)(react@18.2.0):
github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.4.3)(@storybook/components@7.4.3)(@storybook/core-events@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(@storybook/types@7.4.3)(react-dom@18.2.0)(react@18.2.0):
resolution: {tarball: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640}
id: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640
name: storybook-addon-misskey-theme
@ -19877,7 +19828,7 @@ packages:
optional: true
dependencies:
'@storybook/blocks': 7.4.3(react-dom@18.2.0)(react@18.2.0)
'@storybook/components': 7.4.2(react-dom@18.2.0)(react@18.2.0)
'@storybook/components': 7.4.3(react-dom@18.2.0)(react@18.2.0)
'@storybook/core-events': 7.4.3
'@storybook/manager-api': 7.4.3(react-dom@18.2.0)(react@18.2.0)
'@storybook/preview-api': 7.4.3