This commit is contained in:
Shun Sakai 2024-11-09 05:24:55 +09:00 committed by GitHub
commit 1fd3c4b8ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 142 additions and 69 deletions

View file

@ -29,6 +29,7 @@
- Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように - Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588) (Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588)
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715) (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715)
- Enhance: パスワードのハッシュ化に使用する鍵導出関数をbcryptからArgon2に変更
- fix(backend): フォロワーへのメッセージの絵文字をemojisに含めるように - fix(backend): フォロワーへのメッセージの絵文字をemojisに含めるように
- Fix: Nested proxy requestsを検出した際にブロックするように - Fix: Nested proxy requestsを検出した際にブロックするように
[ghsa-gq5q-c77c-v236](https://github.com/misskey-dev/misskey/security/advisories/ghsa-gq5q-c77c-v236) [ghsa-gq5q-c77c-v236](https://github.com/misskey-dev/misskey/security/advisories/ghsa-gq5q-c77c-v236)

View file

@ -99,6 +99,7 @@
"accepts": "1.3.8", "accepts": "1.3.8",
"ajv": "8.17.1", "ajv": "8.17.1",
"archiver": "7.0.1", "archiver": "7.0.1",
"argon2": "^0.41.1",
"async-mutex": "0.5.0", "async-mutex": "0.5.0",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"blurhash": "2.0.5", "blurhash": "2.0.5",
@ -134,8 +135,8 @@
"json5": "2.2.3", "json5": "2.2.3",
"jsonld": "8.3.2", "jsonld": "8.3.2",
"jsrsasign": "11.1.0", "jsrsasign": "11.1.0",
"meilisearch": "0.42.0",
"juice": "11.0.0", "juice": "11.0.0",
"meilisearch": "0.42.0",
"mfm-js": "0.24.0", "mfm-js": "0.24.0",
"microformats-parser": "2.0.2", "microformats-parser": "2.0.2",
"mime-types": "2.1.35", "mime-types": "2.1.35",

View file

@ -5,7 +5,7 @@
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { IsNull, DataSource } from 'typeorm'; import { IsNull, DataSource } from 'typeorm';
import { genRsaKeyPair } from '@/misc/gen-key-pair.js'; import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
import { MiUser } from '@/models/User.js'; import { MiUser } from '@/models/User.js';
@ -32,8 +32,7 @@ export class CreateSystemUserService {
const password = randomUUID(); const password = randomUUID();
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await argon2.hash(password);
const hash = await bcrypt.hash(password, salt);
// Generate secret // Generate secret
const secret = generateNativeUserToken(); const secret = generateNativeUserToken();

View file

@ -5,7 +5,7 @@
import { generateKeyPair } from 'node:crypto'; import { generateKeyPair } from 'node:crypto';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { DataSource, IsNull } from 'typeorm'; import { DataSource, IsNull } from 'typeorm';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { MiMeta, UsedUsernamesRepository, UsersRepository } from '@/models/_.js'; import type { MiMeta, UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
@ -69,8 +69,7 @@ export class SignupService {
} }
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); hash = await argon2.hash(password);
hash = await bcrypt.hash(password, salt);
} }
// Generate secret // Generate secret

View file

@ -5,6 +5,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs'; import bcrypt from 'bcryptjs';
import * as argon2 from 'argon2';
import { IsNull } from 'typeorm'; import { IsNull } from 'typeorm';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
@ -155,7 +156,7 @@ export class SigninApiService {
} }
// Compare password // Compare password
const same = await bcrypt.compare(password, profile.password!); const same = await argon2.verify(profile.password!, password) || bcrypt.compareSync(password, profile.password!);
const fail = async (status?: number, failure?: { id: string; }) => { const fail = async (status?: number, failure?: { id: string; }) => {
// Append signin history // Append signin history
@ -204,6 +205,14 @@ export class SigninApiService {
} }
if (same) { if (same) {
// Check if the password is still hashed using bcrypt
if (profile.password!.startsWith('$2')) {
// Rehash the password using Argon2
const newHash = await argon2.hash(password);
this.userProfilesRepository.update(user.id, {
password: newHash,
});
}
return this.signinService.signin(request, reply, user); return this.signinService.signin(request, reply, user);
} else { } else {
return await fail(403, { return await fail(403, {
@ -220,6 +229,14 @@ export class SigninApiService {
} }
try { try {
// Check if the password is still hashed using bcrypt
if (profile.password!.startsWith('$2')) {
// Rehash the password using Argon2
const newHash = await argon2.hash(password);
this.userProfilesRepository.update(user.id, {
password: newHash,
});
}
await this.userAuthService.twoFactorAuthenticate(profile, token); await this.userAuthService.twoFactorAuthenticate(profile, token);
} catch (e) { } catch (e) {
return await fail(403, { return await fail(403, {

View file

@ -4,7 +4,7 @@
*/ */
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { IsNull } from 'typeorm'; import { IsNull } from 'typeorm';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket, MiMeta } from '@/models/_.js'; import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket, MiMeta } from '@/models/_.js';
@ -186,8 +186,7 @@ export class SignupApiService {
const code = secureRndstr(16, { chars: L_CHARS }); const code = secureRndstr(16, { chars: L_CHARS });
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await argon2.hash(password);
const hash = await bcrypt.hash(password, salt);
const pendingUser = await this.userPendingsRepository.insertOne({ const pendingUser = await this.userPendingsRepository.insertOne({
id: this.idService.gen(), id: this.idService.gen(),

View file

@ -4,7 +4,7 @@
*/ */
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js'; import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
@ -65,7 +65,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const passwd = secureRndstr(8); const passwd = secureRndstr(8);
// Generate hash of password // Generate hash of password
const hash = bcrypt.hashSync(passwd); const hash = await argon2.hash(passwd);
await this.userProfilesRepository.update({ await this.userProfilesRepository.update({
userId: user.id, userId: user.id,

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js';
@ -86,7 +86,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); const passwordMatched = await argon2.verify(profile.password ?? '', ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UserProfilesRepository } from '@/models/_.js'; import type { UserProfilesRepository } from '@/models/_.js';
@ -217,7 +217,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); const passwordMatched = await argon2.verify(profile.password ?? '', ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import * as OTPAuth from 'otpauth'; import * as OTPAuth from 'otpauth';
import * as QRCode from 'qrcode'; import * as QRCode from 'qrcode';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
@ -77,7 +77,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); const passwordMatched = await argon2.verify(profile.password ?? '', ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UserProfilesRepository, UserSecurityKeysRepository } from '@/models/_.js'; import type { UserProfilesRepository, UserSecurityKeysRepository } from '@/models/_.js';
@ -66,7 +66,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); const passwordMatched = await argon2.verify(profile.password ?? '', ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js';
@ -62,7 +62,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); const passwordMatched = await argon2.verify(profile.password ?? '', ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);
} }

View file

@ -3,7 +3,6 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UserSecurityKeysRepository } from '@/models/_.js'; import type { UserSecurityKeysRepository } from '@/models/_.js';

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UserProfilesRepository } from '@/models/_.js'; import type { UserProfilesRepository } from '@/models/_.js';
@ -50,15 +50,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.currentPassword, profile.password!); const passwordMatched = await argon2.verify(profile.password!, ps.currentPassword);
if (!passwordMatched) { if (!passwordMatched) {
throw new Error('incorrect password'); throw new Error('incorrect password');
} }
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await argon2.hash(ps.newPassword);
const hash = await bcrypt.hash(ps.newPassword, salt);
await this.userProfilesRepository.update(me.id, { await this.userProfilesRepository.update(me.id, {
password: hash, password: hash,

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js'; import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
@ -59,7 +59,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
return; return;
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password!); const passwordMatched = await argon2.verify(profile.password!, ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new Error('incorrect password'); throw new Error('incorrect password');
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js'; import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
@ -43,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
// Compare password // Compare password
const same = await bcrypt.compare(ps.password, profile.password!); const same = await argon2.verify(profile.password!, ps.password);
if (!same) { if (!same) {
throw new Error('incorrect password'); throw new Error('incorrect password');

View file

@ -5,7 +5,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import ms from 'ms'; import ms from 'ms';
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { MiMeta, UserProfilesRepository } from '@/models/_.js'; import type { MiMeta, UserProfilesRepository } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js';
@ -96,7 +96,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
} }
const passwordMatched = await bcrypt.compare(ps.password, profile.password!); const passwordMatched = await argon2.verify(profile.password!, ps.password);
if (!passwordMatched) { if (!passwordMatched) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import bcrypt from 'bcryptjs'; import * as argon2 from 'argon2';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import type { UserProfilesRepository, PasswordResetRequestsRepository } from '@/models/_.js'; import type { UserProfilesRepository, PasswordResetRequestsRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
@ -53,8 +53,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await argon2.hash(ps.password);
const hash = await bcrypt.hash(ps.password, salt);
await this.userProfilesRepository.update(req.userId, { await this.userProfilesRepository.update(req.userId, {
password: hash, password: hash,

View file

@ -397,7 +397,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true); assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
assert.strictEqual(res.body.some(note => note.id === carolNote1.id), false); assert.strictEqual(res.body.some(note => note.id === carolNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === carolNote2.id), false); assert.strictEqual(res.body.some(note => note.id === carolNote2.id), false);
}, 1000 * 10); }, 1000 * 100);
test.concurrent('フォローしているユーザーのチャンネル投稿が含まれない', async () => { test.concurrent('フォローしているユーザーのチャンネル投稿が含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]); const [alice, bob] = await Promise.all([signup(), signup()]);
@ -744,7 +744,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false); assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true); assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
}, 1000 * 10); }, 1000 * 100);
}); });
describe('Social TL', () => { describe('Social TL', () => {
@ -955,7 +955,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false); assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true); assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
}, 1000 * 10); }, 1000 * 100);
}); });
describe('User List TL', () => { describe('User List TL', () => {
@ -1168,7 +1168,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false); assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true); assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
}, 1000 * 10); }, 1000 * 100);
test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => { test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]); const [alice, bob] = await Promise.all([signup(), signup()]);
@ -1327,7 +1327,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false); assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true); assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
}, 1000 * 10); }, 1000 * 100);
test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => { test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]); const [alice, bob] = await Promise.all([signup(), signup()]);

114
pnpm-lock.yaml generated
View file

@ -179,6 +179,9 @@ importers:
archiver: archiver:
specifier: 7.0.1 specifier: 7.0.1
version: 7.0.1 version: 7.0.1
argon2:
specifier: ^0.41.1
version: 0.41.1
async-mutex: async-mutex:
specifier: 0.5.0 specifier: 0.5.0
version: 0.5.0 version: 0.5.0
@ -1163,7 +1166,7 @@ importers:
version: 7.17.0(eslint@9.11.0)(typescript@5.6.2) version: 7.17.0(eslint@9.11.0)(typescript@5.6.2)
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: 1.6.0 specifier: 1.6.0
version: 1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.33.0)) version: 1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.33.0))
'@vue/runtime-core': '@vue/runtime-core':
specifier: 3.5.11 specifier: 3.5.11
version: 3.5.11 version: 3.5.11
@ -3508,6 +3511,10 @@ packages:
resolution: {integrity: sha512-aGQIwo6/sWtyyqhVK4e1MtxYz4N1X8CNt6SOtCc+Wnczs5S5ONaLHDDR8LYaGn0MgOwvGgXyuZ5sJIfd7iyoUw==} resolution: {integrity: sha512-aGQIwo6/sWtyyqhVK4e1MtxYz4N1X8CNt6SOtCc+Wnczs5S5ONaLHDDR8LYaGn0MgOwvGgXyuZ5sJIfd7iyoUw==}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
'@phc/format@1.0.0':
resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==}
engines: {node: '>=10'}
'@pkgjs/parseargs@0.11.0': '@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'} engines: {node: '>=14'}
@ -5377,6 +5384,10 @@ packages:
arg@5.0.2: arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
argon2@0.41.1:
resolution: {integrity: sha512-dqCW8kJXke8Ik+McUcMDltrbuAWETPyU6iq+4AhxqKphWi7pChB/Zgd/Tp/o8xRLbg8ksMj46F/vph9wnxpTzQ==}
engines: {node: '>=16.17.0'}
argparse@1.0.10: argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
@ -8917,6 +8928,10 @@ packages:
node-addon-api@3.2.1: node-addon-api@3.2.1:
resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==}
node-addon-api@8.2.1:
resolution: {integrity: sha512-vmEOvxwiH8tlOcv4SyE8RH34rI5/nWVaigUeAUPawC6f0+HoDthwI0vkMu4tbtsZrXq6QXFfrkhjofzKEs5tpA==}
engines: {node: ^18 || ^20 || >= 21}
node-bitmap@0.0.1: node-bitmap@0.0.1:
resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==} resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==}
engines: {node: '>=v0.6.5'} engines: {node: '>=v0.6.5'}
@ -8955,6 +8970,10 @@ packages:
resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==}
hasBin: true hasBin: true
node-gyp-build@4.8.2:
resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==}
hasBin: true
node-gyp@10.2.0: node-gyp@10.2.0:
resolution: {integrity: sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==} resolution: {integrity: sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==}
engines: {node: ^16.14.0 || >=18.0.0} engines: {node: ^16.14.0 || >=18.0.0}
@ -14158,6 +14177,8 @@ snapshots:
jsprim: 1.4.2 jsprim: 1.4.2
sshpk: 1.17.0 sshpk: 1.17.0
'@phc/format@1.0.0': {}
'@pkgjs/parseargs@0.11.0': '@pkgjs/parseargs@0.11.0':
optional: true optional: true
@ -15962,7 +15983,7 @@ snapshots:
'@typescript-eslint/types': 7.17.0 '@typescript-eslint/types': 7.17.0
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4) '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.11.0 eslint: 9.11.0
optionalDependencies: optionalDependencies:
typescript: 5.5.4 typescript: 5.5.4
@ -15975,7 +15996,7 @@ snapshots:
'@typescript-eslint/types': 7.17.0 '@typescript-eslint/types': 7.17.0
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2)
'@typescript-eslint/visitor-keys': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.11.0 eslint: 9.11.0
optionalDependencies: optionalDependencies:
typescript: 5.6.2 typescript: 5.6.2
@ -15988,7 +16009,7 @@ snapshots:
'@typescript-eslint/types': 7.17.0 '@typescript-eslint/types': 7.17.0
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2)
'@typescript-eslint/visitor-keys': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0 eslint: 9.8.0
optionalDependencies: optionalDependencies:
typescript: 5.6.2 typescript: 5.6.2
@ -16009,7 +16030,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
'@typescript-eslint/utils': 7.1.0(eslint@9.11.0)(typescript@5.3.3) '@typescript-eslint/utils': 7.1.0(eslint@9.11.0)(typescript@5.3.3)
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.11.0 eslint: 9.11.0
ts-api-utils: 1.0.1(typescript@5.3.3) ts-api-utils: 1.0.1(typescript@5.3.3)
optionalDependencies: optionalDependencies:
@ -16021,7 +16042,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4) '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4)
'@typescript-eslint/utils': 7.17.0(eslint@9.11.0)(typescript@5.5.4) '@typescript-eslint/utils': 7.17.0(eslint@9.11.0)(typescript@5.5.4)
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.11.0 eslint: 9.11.0
ts-api-utils: 1.3.0(typescript@5.5.4) ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies: optionalDependencies:
@ -16033,7 +16054,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2)
'@typescript-eslint/utils': 7.17.0(eslint@9.11.0)(typescript@5.6.2) '@typescript-eslint/utils': 7.17.0(eslint@9.11.0)(typescript@5.6.2)
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.11.0 eslint: 9.11.0
ts-api-utils: 1.3.0(typescript@5.6.2) ts-api-utils: 1.3.0(typescript@5.6.2)
optionalDependencies: optionalDependencies:
@ -16045,7 +16066,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.6.2)
'@typescript-eslint/utils': 7.17.0(eslint@9.8.0)(typescript@5.6.2) '@typescript-eslint/utils': 7.17.0(eslint@9.8.0)(typescript@5.6.2)
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0 eslint: 9.8.0
ts-api-utils: 1.3.0(typescript@5.6.2) ts-api-utils: 1.3.0(typescript@5.6.2)
optionalDependencies: optionalDependencies:
@ -16061,7 +16082,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/types': 7.1.0 '@typescript-eslint/types': 7.1.0
'@typescript-eslint/visitor-keys': 7.1.0 '@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.3 minimatch: 9.0.3
@ -16076,7 +16097,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/types': 7.17.0 '@typescript-eslint/types': 7.17.0
'@typescript-eslint/visitor-keys': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.4 minimatch: 9.0.4
@ -16091,7 +16112,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/types': 7.17.0 '@typescript-eslint/types': 7.17.0
'@typescript-eslint/visitor-keys': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.4 minimatch: 9.0.4
@ -16175,7 +16196,7 @@ snapshots:
dependencies: dependencies:
'@ampproject/remapping': 2.2.1 '@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3 '@bcoe/v8-coverage': 0.2.3
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
istanbul-lib-coverage: 3.2.2 istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1 istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.4 istanbul-lib-source-maps: 5.0.4
@ -16190,11 +16211,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.33.0))': '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.33.0))':
dependencies: dependencies:
'@ampproject/remapping': 2.2.1 '@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3 '@bcoe/v8-coverage': 0.2.3
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
istanbul-lib-coverage: 3.2.2 istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1 istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.4 istanbul-lib-source-maps: 5.0.4
@ -16205,7 +16226,7 @@ snapshots:
std-env: 3.7.0 std-env: 3.7.0
strip-literal: 2.1.0 strip-literal: 2.1.0
test-exclude: 6.0.0 test-exclude: 6.0.0
vitest: 1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.33.0) vitest: 1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.33.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -16515,7 +16536,7 @@ snapshots:
agent-base@7.1.0: agent-base@7.1.0:
dependencies: dependencies:
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -16644,6 +16665,12 @@ snapshots:
arg@5.0.2: {} arg@5.0.2: {}
argon2@0.41.1:
dependencies:
'@phc/format': 1.0.0
node-addon-api: 8.2.1
node-gyp-build: 4.8.2
argparse@1.0.10: argparse@1.0.10:
dependencies: dependencies:
sprintf-js: 1.0.3 sprintf-js: 1.0.3
@ -19487,7 +19514,7 @@ snapshots:
http-proxy-agent@7.0.2: http-proxy-agent@7.0.2:
dependencies: dependencies:
agent-base: 7.1.0 agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -19526,7 +19553,7 @@ snapshots:
https-proxy-agent@5.0.1: https-proxy-agent@5.0.1:
dependencies: dependencies:
agent-base: 6.0.2 agent-base: 6.0.2
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
optional: true optional: true
@ -19534,14 +19561,14 @@ snapshots:
https-proxy-agent@7.0.2: https-proxy-agent@7.0.2:
dependencies: dependencies:
agent-base: 7.1.0 agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
https-proxy-agent@7.0.5: https-proxy-agent@7.0.5:
dependencies: dependencies:
agent-base: 7.1.0 agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -19914,7 +19941,7 @@ snapshots:
istanbul-lib-source-maps@5.0.4: istanbul-lib-source-maps@5.0.4:
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.25 '@jridgewell/trace-mapping': 0.3.25
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
istanbul-lib-coverage: 3.2.2 istanbul-lib-coverage: 3.2.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -20315,6 +20342,35 @@ snapshots:
jsdoc-type-pratt-parser@4.1.0: {} jsdoc-type-pratt-parser@4.1.0: {}
jsdom@24.1.1:
dependencies:
cssstyle: 4.0.1
data-urls: 5.0.0
decimal.js: 10.4.3
form-data: 4.0.0
html-encoding-sniffer: 4.0.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.5
is-potential-custom-element-name: 1.0.1
nwsapi: 2.2.12
parse5: 7.1.2
rrweb-cssom: 0.7.1
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 4.1.4
w3c-xmlserializer: 5.0.0
webidl-conversions: 7.0.0
whatwg-encoding: 3.1.1
whatwg-mimetype: 4.0.0
whatwg-url: 14.0.0
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
xml-name-validator: 5.0.0
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
optional: true
jsdom@24.1.1(bufferutil@4.0.7)(utf-8-validate@6.0.3): jsdom@24.1.1(bufferutil@4.0.7)(utf-8-validate@6.0.3):
dependencies: dependencies:
cssstyle: 4.0.1 cssstyle: 4.0.1
@ -21336,6 +21392,8 @@ snapshots:
node-addon-api@3.2.1: node-addon-api@3.2.1:
optional: true optional: true
node-addon-api@8.2.1: {}
node-bitmap@0.0.1: {} node-bitmap@0.0.1: {}
node-domexception@1.0.0: {} node-domexception@1.0.0: {}
@ -21364,6 +21422,8 @@ snapshots:
node-gyp-build@4.6.0: node-gyp-build@4.6.0:
optional: true optional: true
node-gyp-build@4.8.2: {}
node-gyp@10.2.0: node-gyp@10.2.0:
dependencies: dependencies:
env-paths: 2.2.1 env-paths: 2.2.1
@ -22889,7 +22949,7 @@ snapshots:
dependencies: dependencies:
'@hapi/hoek': 11.0.4 '@hapi/hoek': 11.0.4
'@hapi/wreck': 18.0.1 '@hapi/wreck': 18.0.1
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
joi: 17.11.0 joi: 17.11.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -23849,7 +23909,7 @@ snapshots:
vite-node@1.6.0(@types/node@20.14.12)(sass@1.79.3)(terser@5.33.0): vite-node@1.6.0(@types/node@20.14.12)(sass@1.79.3)(terser@5.33.0):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
pathe: 1.1.2 pathe: 1.1.2
picocolors: 1.0.1 picocolors: 1.0.1
vite: 5.4.8(@types/node@20.14.12)(sass@1.79.3)(terser@5.33.0) vite: 5.4.8(@types/node@20.14.12)(sass@1.79.3)(terser@5.33.0)
@ -23867,7 +23927,7 @@ snapshots:
vite-node@1.6.0(@types/node@20.14.12)(sass@1.79.4)(terser@5.33.0): vite-node@1.6.0(@types/node@20.14.12)(sass@1.79.4)(terser@5.33.0):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
pathe: 1.1.2 pathe: 1.1.2
picocolors: 1.0.1 picocolors: 1.0.1
vite: 5.4.8(@types/node@20.14.12)(sass@1.79.4)(terser@5.33.0) vite: 5.4.8(@types/node@20.14.12)(sass@1.79.4)(terser@5.33.0)
@ -23949,7 +24009,7 @@ snapshots:
- supports-color - supports-color
- terser - terser
vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.33.0): vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.33.0):
dependencies: dependencies:
'@vitest/expect': 1.6.0 '@vitest/expect': 1.6.0
'@vitest/runner': 1.6.0 '@vitest/runner': 1.6.0
@ -23974,7 +24034,7 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/node': 20.14.12 '@types/node': 20.14.12
happy-dom: 10.0.3 happy-dom: 10.0.3
jsdom: 24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4) jsdom: 24.1.1
transitivePeerDependencies: transitivePeerDependencies:
- less - less
- lightningcss - lightningcss
@ -24046,7 +24106,7 @@ snapshots:
vue-eslint-parser@9.4.3(eslint@9.11.0): vue-eslint-parser@9.4.3(eslint@9.11.0):
dependencies: dependencies:
debug: 4.3.5(supports-color@5.5.0) debug: 4.3.5(supports-color@8.1.1)
eslint: 9.11.0 eslint: 9.11.0
eslint-scope: 7.2.2 eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3