mirror of
https://github.com/bitwarden/browser
synced 2026-02-11 05:53:42 +00:00
Merge branch 'main' into billing/pm-29602/build-upgrade-dialogs
This commit is contained in:
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -156,6 +156,8 @@ apps/desktop/macos/autofill-extension @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/src/app/components/fido2placeholder.component.ts @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/desktop_native/windows_plugin_authenticator @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/desktop_native/autotype @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/desktop_native/core/src/ssh_agent @bitwarden/team-autofill-desktop-dev @bitwarden/wg-ssh-keys
|
||||
apps/desktop/desktop_native/ssh_agent @bitwarden/team-autofill-desktop-dev @bitwarden/wg-ssh-keys
|
||||
apps/desktop/desktop_native/napi/src/autofill.rs @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/desktop_native/napi/src/autotype.rs @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/desktop_native/napi/src/sshagent.rs @bitwarden/team-autofill-desktop-dev
|
||||
@@ -164,8 +166,6 @@ apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/src/services/duckduckgo-message-handler.service.ts @bitwarden/team-autofill-desktop-dev
|
||||
apps/desktop/src/services/encrypted-message-handler.service.ts @bitwarden/team-autofill-desktop-dev
|
||||
.github/workflows/alert-ddg-files-modified.yml @bitwarden/team-autofill-desktop-dev
|
||||
# SSH Agent
|
||||
apps/desktop/desktop_native/core/src/ssh_agent @bitwarden/team-autofill-desktop-dev @bitwarden/wg-ssh-keys
|
||||
|
||||
## UI Foundation ##
|
||||
.github/workflows/chromatic.yml @bitwarden/team-ui-foundation
|
||||
|
||||
1
.github/renovate.json5
vendored
1
.github/renovate.json5
vendored
@@ -313,7 +313,6 @@
|
||||
"@types/inquirer",
|
||||
"@types/koa",
|
||||
"@types/koa__multer",
|
||||
"@types/koa__router",
|
||||
"@types/koa-bodyparser",
|
||||
"@types/koa-json",
|
||||
"@types/lunr",
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@koa/multer": "4.0.0",
|
||||
"@koa/router": "14.0.0",
|
||||
"@koa/router": "15.2.0",
|
||||
"big-integer": "1.6.52",
|
||||
"browser-hrtime": "1.1.8",
|
||||
"chalk": "4.1.2",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import http from "node:http";
|
||||
import net from "node:net";
|
||||
|
||||
import * as koaRouter from "@koa/router";
|
||||
import { Router } from "@koa/router";
|
||||
import { OptionValues } from "commander";
|
||||
import * as koa from "koa";
|
||||
import * as koaBodyParser from "koa-bodyparser";
|
||||
@@ -29,7 +29,7 @@ export class ServeCommand {
|
||||
);
|
||||
|
||||
const server = new koa();
|
||||
const router = new koaRouter();
|
||||
const router = new Router();
|
||||
process.env.BW_SERVE = "true";
|
||||
process.env.BW_NOINTERACTION = "true";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import * as koaMulter from "@koa/multer";
|
||||
import * as koaRouter from "@koa/router";
|
||||
import { Router } from "@koa/router";
|
||||
import * as koa from "koa";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
@@ -218,7 +218,7 @@ export class OssServeConfigurator {
|
||||
);
|
||||
}
|
||||
|
||||
async configureRouter(router: koaRouter) {
|
||||
async configureRouter(router: Router) {
|
||||
router.get("/generate", async (ctx, next) => {
|
||||
const response = await this.generateCommand.run(ctx.request.query);
|
||||
this.processResponse(ctx.response, response);
|
||||
|
||||
16
apps/desktop/desktop_native/Cargo.lock
generated
16
apps/desktop/desktop_native/Cargo.lock
generated
@@ -377,9 +377,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.7.3"
|
||||
version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3"
|
||||
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
@@ -3295,6 +3295,9 @@ dependencies = [
|
||||
"bcrypt-pbkdf",
|
||||
"ed25519-dalek",
|
||||
"num-bigint-dig",
|
||||
"p256",
|
||||
"p384",
|
||||
"p521",
|
||||
"rand_core 0.6.4",
|
||||
"rsa",
|
||||
"sec1",
|
||||
@@ -3306,6 +3309,15 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ssh_agent"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
"ssh-key",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
|
||||
@@ -9,6 +9,7 @@ members = [
|
||||
"napi",
|
||||
"process_isolation",
|
||||
"proxy",
|
||||
"ssh_agent",
|
||||
"windows_plugin_authenticator",
|
||||
]
|
||||
|
||||
|
||||
19
apps/desktop/desktop_native/ssh_agent/Cargo.toml
Normal file
19
apps/desktop/desktop_native/ssh_agent/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "ssh_agent"
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
version = { workspace = true }
|
||||
publish = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
ssh-key = { version = "=0.6.7", features = [
|
||||
"encryption",
|
||||
"ed25519",
|
||||
"rsa",
|
||||
"rand_core",
|
||||
] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
184
apps/desktop/desktop_native/ssh_agent/src/crypto/mod.rs
Normal file
184
apps/desktop/desktop_native/ssh_agent/src/crypto/mod.rs
Normal file
@@ -0,0 +1,184 @@
|
||||
//! Cryptographic key management for the SSH agent.
|
||||
//!
|
||||
//! This module provides the core primitive types and functionality for managing
|
||||
//! SSH keys in the Bitwarden SSH agent.
|
||||
//!
|
||||
//! # Supported signing algorithms
|
||||
//!
|
||||
//! - Ed25519
|
||||
//! - RSA
|
||||
//!
|
||||
//! ECDSA keys are not currently supported (PM-29894)
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use ssh_key::private::{Ed25519Keypair, RsaKeypair};
|
||||
|
||||
/// Represents an SSH key and its associated metadata.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct SSHKeyData {
|
||||
/// Private key of the key pair
|
||||
private_key: PrivateKey,
|
||||
/// Public key of the key pair
|
||||
public_key: PublicKey,
|
||||
/// Human-readable name
|
||||
name: String,
|
||||
/// Vault cipher ID associated with the key pair
|
||||
cipher_id: String,
|
||||
}
|
||||
|
||||
impl SSHKeyData {
|
||||
/// Creates a new `SSHKeyData` instance.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `private_key` - The private key component
|
||||
/// * `public_key` - The public key component
|
||||
/// * `name` - A human-readable name for the key
|
||||
/// * `cipher_id` - The vault cipher identifier associated with this key
|
||||
pub(crate) fn new(
|
||||
private_key: PrivateKey,
|
||||
public_key: PublicKey,
|
||||
name: String,
|
||||
cipher_id: String,
|
||||
) -> Self {
|
||||
Self {
|
||||
private_key,
|
||||
public_key,
|
||||
name,
|
||||
cipher_id,
|
||||
}
|
||||
}
|
||||
|
||||
/// # Returns
|
||||
///
|
||||
/// A reference to the [`PublicKey`].
|
||||
pub(crate) fn public_key(&self) -> &PublicKey {
|
||||
&self.public_key
|
||||
}
|
||||
|
||||
/// # Returns
|
||||
///
|
||||
/// A reference to the [`PrivateKey`].
|
||||
pub(crate) fn private_key(&self) -> &PrivateKey {
|
||||
&self.private_key
|
||||
}
|
||||
|
||||
/// # Returns
|
||||
///
|
||||
/// A reference to the human-readable name for this key.
|
||||
pub(crate) fn name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// # Returns
|
||||
///
|
||||
/// A reference to the cipher ID that links this key to a vault entry.
|
||||
pub(crate) fn cipher_id(&self) -> &String {
|
||||
&self.cipher_id
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an SSH private key.
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub(crate) enum PrivateKey {
|
||||
Ed25519(Ed25519Keypair),
|
||||
Rsa(RsaKeypair),
|
||||
}
|
||||
|
||||
impl TryFrom<ssh_key::private::PrivateKey> for PrivateKey {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(key: ssh_key::private::PrivateKey) -> Result<Self, Self::Error> {
|
||||
match key.algorithm() {
|
||||
ssh_key::Algorithm::Ed25519 => Ok(Self::Ed25519(
|
||||
key.key_data()
|
||||
.ed25519()
|
||||
.ok_or(anyhow!("Failed to parse ed25519 key"))?
|
||||
.to_owned(),
|
||||
)),
|
||||
ssh_key::Algorithm::Rsa { hash: _ } => Ok(Self::Rsa(
|
||||
key.key_data()
|
||||
.rsa()
|
||||
.ok_or(anyhow!("Failed to parse RSA key"))?
|
||||
.to_owned(),
|
||||
)),
|
||||
_ => Err(anyhow!("Unsupported key type")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an SSH public key.
|
||||
///
|
||||
/// Contains the algorithm identifier (e.g., "ssh-ed25519", "ssh-rsa")
|
||||
/// and the binary blob of the public key data.
|
||||
#[derive(Clone, Ord, Eq, PartialOrd, PartialEq)]
|
||||
pub(crate) struct PublicKey {
|
||||
pub alg: String,
|
||||
pub blob: Vec<u8>,
|
||||
}
|
||||
|
||||
impl PublicKey {
|
||||
pub(crate) fn alg(&self) -> &str {
|
||||
&self.alg
|
||||
}
|
||||
|
||||
pub(crate) fn blob(&self) -> &[u8] {
|
||||
&self.blob
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PublicKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "PublicKey(\"{self}\")")
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PublicKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use base64::{prelude::BASE64_STANDARD, Engine as _};
|
||||
|
||||
write!(f, "{} {}", self.alg(), BASE64_STANDARD.encode(self.blob()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ssh_key::{
|
||||
private::{Ed25519Keypair, RsaKeypair},
|
||||
rand_core::OsRng,
|
||||
LineEnding,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
const MIN_KEY_BIT_SIZE: usize = 2048;
|
||||
|
||||
fn create_valid_ed25519_key_string() -> String {
|
||||
let ed25519_keypair = Ed25519Keypair::random(&mut OsRng);
|
||||
let ssh_key =
|
||||
ssh_key::PrivateKey::new(ssh_key::private::KeypairData::Ed25519(ed25519_keypair), "")
|
||||
.unwrap();
|
||||
ssh_key.to_openssh(LineEnding::LF).unwrap().to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_privatekey_from_ed25519() {
|
||||
let key_string = create_valid_ed25519_key_string();
|
||||
let ssh_key = ssh_key::PrivateKey::from_openssh(&key_string).unwrap();
|
||||
|
||||
let private_key = PrivateKey::try_from(ssh_key).unwrap();
|
||||
assert!(matches!(private_key, PrivateKey::Ed25519(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_privatekey_from_rsa() {
|
||||
let rsa_keypair = RsaKeypair::random(&mut OsRng, MIN_KEY_BIT_SIZE).unwrap();
|
||||
let ssh_key =
|
||||
ssh_key::PrivateKey::new(ssh_key::private::KeypairData::Rsa(rsa_keypair), "").unwrap();
|
||||
|
||||
let private_key = PrivateKey::try_from(ssh_key).unwrap();
|
||||
assert!(matches!(private_key, PrivateKey::Rsa(_)));
|
||||
}
|
||||
}
|
||||
7
apps/desktop/desktop_native/ssh_agent/src/lib.rs
Normal file
7
apps/desktop/desktop_native/ssh_agent/src/lib.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
//! Bitwarden SSH Agent implementation
|
||||
//!
|
||||
//! <https://www.ietf.org/archive/id/draft-miller-ssh-agent-11.html#RFC4253>
|
||||
|
||||
#![allow(dead_code)] // TODO remove when all code is used in follow-up PR
|
||||
|
||||
mod crypto;
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as koaRouter from "@koa/router";
|
||||
import { Router } from "@koa/router";
|
||||
|
||||
import { OssServeConfigurator } from "@bitwarden/cli/oss-serve-configurator";
|
||||
|
||||
@@ -16,7 +16,7 @@ export class BitServeConfigurator extends OssServeConfigurator {
|
||||
super(serviceContainer);
|
||||
}
|
||||
|
||||
override async configureRouter(router: koaRouter): Promise<void> {
|
||||
override async configureRouter(router: Router): Promise<void> {
|
||||
// Register OSS endpoints
|
||||
await super.configureRouter(router);
|
||||
|
||||
@@ -24,7 +24,7 @@ export class BitServeConfigurator extends OssServeConfigurator {
|
||||
this.serveDeviceApprovals(router);
|
||||
}
|
||||
|
||||
private serveDeviceApprovals(router: koaRouter) {
|
||||
private serveDeviceApprovals(router: Router) {
|
||||
router.get("/device-approval/:organizationId", async (ctx, next) => {
|
||||
if (await this.errorIfLocked(ctx.response)) {
|
||||
await next();
|
||||
|
||||
@@ -28,6 +28,7 @@ export type OptionalInitialValues = {
|
||||
// Credit Card Information
|
||||
cardholderName?: string;
|
||||
number?: string;
|
||||
brand?: string;
|
||||
expMonth?: string;
|
||||
expYear?: string;
|
||||
code?: string;
|
||||
|
||||
@@ -108,12 +108,17 @@ describe("CardDetailsSectionComponent", () => {
|
||||
const cardholderName = "Ron Burgundy";
|
||||
const number = "4242 4242 4242 4242";
|
||||
const code = "619";
|
||||
const brand = "Maestro";
|
||||
const expMonth = "5";
|
||||
const expYear = "2028";
|
||||
|
||||
const cardView = new CardView();
|
||||
cardView.cardholderName = cardholderName;
|
||||
cardView.number = number;
|
||||
cardView.code = code;
|
||||
cardView.brand = "Visa";
|
||||
cardView.brand = brand;
|
||||
cardView.expMonth = expMonth;
|
||||
cardView.expYear = expYear;
|
||||
|
||||
getInitialCipherView.mockReturnValueOnce({ card: cardView });
|
||||
|
||||
@@ -123,7 +128,9 @@ describe("CardDetailsSectionComponent", () => {
|
||||
cardholderName,
|
||||
number,
|
||||
code,
|
||||
brand: cardView.brand,
|
||||
brand,
|
||||
expMonth,
|
||||
expYear,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -154,4 +161,27 @@ describe("CardDetailsSectionComponent", () => {
|
||||
|
||||
expect(heading.nativeElement.textContent.trim()).toBe("cardDetails");
|
||||
});
|
||||
|
||||
it("initializes `cardDetailsForm` from `initialValues` when provided and editing existing cipher", () => {
|
||||
const initialCardholderName = "New Name";
|
||||
const initialBrand = "Amex";
|
||||
|
||||
(cipherFormProvider as any).config = {
|
||||
initialValues: {
|
||||
cardholderName: initialCardholderName,
|
||||
brand: initialBrand,
|
||||
},
|
||||
};
|
||||
|
||||
const existingCard = new CardView();
|
||||
existingCard.cardholderName = "Old Name";
|
||||
existingCard.brand = "Visa";
|
||||
|
||||
getInitialCipherView.mockReturnValueOnce({ card: existingCard });
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.cardDetailsForm.value.cardholderName).toBe(initialCardholderName);
|
||||
expect(component.cardDetailsForm.value.brand).toBe(initialBrand);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -158,6 +158,7 @@ export class CardDetailsSectionComponent implements OnInit {
|
||||
this.cardDetailsForm.patchValue({
|
||||
cardholderName: this.initialValues?.cardholderName ?? existingCard.cardholderName,
|
||||
number: this.initialValues?.number ?? existingCard.number,
|
||||
brand: this.initialValues?.brand ?? existingCard.brand,
|
||||
expMonth: this.initialValues?.expMonth ?? existingCard.expMonth,
|
||||
expYear: this.initialValues?.expYear ?? existingCard.expYear,
|
||||
code: this.initialValues?.code ?? existingCard.code,
|
||||
|
||||
72
package-lock.json
generated
72
package-lock.json
generated
@@ -28,7 +28,7 @@
|
||||
"@electron/fuses": "1.8.0",
|
||||
"@emotion/css": "11.13.5",
|
||||
"@koa/multer": "4.0.0",
|
||||
"@koa/router": "14.0.0",
|
||||
"@koa/router": "15.2.0",
|
||||
"@microsoft/signalr": "8.0.7",
|
||||
"@microsoft/signalr-protocol-msgpack": "8.0.7",
|
||||
"@ng-select/ng-select": "20.7.0",
|
||||
@@ -104,7 +104,6 @@
|
||||
"@types/jsdom": "21.1.7",
|
||||
"@types/koa": "3.0.1",
|
||||
"@types/koa__multer": "2.0.7",
|
||||
"@types/koa__router": "12.0.4",
|
||||
"@types/koa-bodyparser": "4.3.7",
|
||||
"@types/koa-json": "2.0.24",
|
||||
"@types/lowdb": "1.0.15",
|
||||
@@ -200,7 +199,7 @@
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"dependencies": {
|
||||
"@koa/multer": "4.0.0",
|
||||
"@koa/router": "14.0.0",
|
||||
"@koa/router": "15.2.0",
|
||||
"big-integer": "1.6.52",
|
||||
"browser-hrtime": "1.1.8",
|
||||
"chalk": "4.1.2",
|
||||
@@ -8746,18 +8745,46 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@koa/router": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@koa/router/-/router-14.0.0.tgz",
|
||||
"integrity": "sha512-LBSu5K0qAaaQcXX/0WIB9PGDevyCxxpnc1uq13vV/CgObaVxuis5hKl3Eboq/8gcb6ebnkAStW9NB/Em2eYyFA==",
|
||||
"version": "15.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@koa/router/-/router-15.2.0.tgz",
|
||||
"integrity": "sha512-7YUhq4W83cybfNa4E7JqJpWzoCTSvbnFltkvRaUaUX1ybFzlUoLNY1SqT8XmIAO6nGbFrev+FvJHw4mL+4WhuQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.1",
|
||||
"http-errors": "^2.0.0",
|
||||
"debug": "^4.4.3",
|
||||
"http-errors": "^2.0.1",
|
||||
"koa-compose": "^4.1.0",
|
||||
"path-to-regexp": "^8.2.0"
|
||||
"path-to-regexp": "^8.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"koa": "^2.0.0 || ^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"koa": {
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@koa/router/node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/@leichtgewicht/ip-codec": {
|
||||
@@ -15735,16 +15762,6 @@
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/koa__router": {
|
||||
"version": "12.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-12.0.4.tgz",
|
||||
"integrity": "sha512-Y7YBbSmfXZpa/m5UGGzb7XadJIRBRnwNY9cdAojZGp65Cpe5MAP3mOZE7e3bImt8dfKS4UFcR16SLH8L/z7PBw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/koa-bodyparser": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa-bodyparser/-/koa-bodyparser-4.3.7.tgz",
|
||||
@@ -21479,9 +21496,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
@@ -35514,12 +35531,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
|
||||
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
|
||||
"integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/path-type": {
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
"@types/jsdom": "21.1.7",
|
||||
"@types/koa": "3.0.1",
|
||||
"@types/koa__multer": "2.0.7",
|
||||
"@types/koa__router": "12.0.4",
|
||||
"@types/koa-bodyparser": "4.3.7",
|
||||
"@types/koa-json": "2.0.24",
|
||||
"@types/lowdb": "1.0.15",
|
||||
@@ -167,7 +166,7 @@
|
||||
"@electron/fuses": "1.8.0",
|
||||
"@emotion/css": "11.13.5",
|
||||
"@koa/multer": "4.0.0",
|
||||
"@koa/router": "14.0.0",
|
||||
"@koa/router": "15.2.0",
|
||||
"@microsoft/signalr": "8.0.7",
|
||||
"@microsoft/signalr-protocol-msgpack": "8.0.7",
|
||||
"@ng-select/ng-select": "20.7.0",
|
||||
|
||||
Reference in New Issue
Block a user