1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-10 21:50:15 +00:00

Merge branch 'main' into nathan/fix-autofill-signing

This commit is contained in:
Nathan Ansel
2025-02-06 09:33:07 -06:00
10 changed files with 156 additions and 127 deletions

2
.github/CODEOWNERS vendored
View File

@@ -134,7 +134,7 @@ libs/key-management @bitwarden/team-key-management-dev
libs/key-management-ui @bitwarden/team-key-management-dev
libs/common/src/key-management @bitwarden/team-key-management-dev
apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-dev
apps/desktop/desktop_native/core/src/biometric/ @bitwarden/team-key-management-dev
apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev
apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev
apps/desktop/src/services/biometric-message-handler.service.ts @bitwarden/team-key-management-dev

4
.github/codecov.yml vendored
View File

@@ -56,11 +56,11 @@ component_management:
- apps/browser/src/key-management/**
- apps/browser/src/background/nativeMessaging.background.ts
- apps/cli/src/key-management/**
- apps/desktop/destkop_native/core/src/biometric/**
- apps/desktop/desktop_native/core/src/biometric/**
- apps/desktop/src/key-management/**
- apps/desktop/src/services/biometric-message-handler.service.ts
- apps/desktop/src/services/native-messaging.service.ts
- apps/web/src/app/key-managemen/**
- apps/web/src/app/key-management/**
- libs/common/src/key-management/**
- libs/key-management/**
- libs/key-management-ui/**

View File

@@ -1,6 +1,6 @@
{
"name": "@bitwarden/browser",
"version": "2025.1.4",
"version": "2025.1.3",
"scripts": {
"build": "npm run build:chrome",
"build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack",

View File

@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "__MSG_extName__",
"short_name": "__MSG_appName__",
"version": "2025.1.4",
"version": "2025.1.3",
"description": "__MSG_extDesc__",
"default_locale": "en",
"author": "Bitwarden Inc.",

View File

@@ -3,7 +3,7 @@
"minimum_chrome_version": "102.0",
"name": "__MSG_extName__",
"short_name": "__MSG_appName__",
"version": "2025.1.4",
"version": "2025.1.3",
"description": "__MSG_extDesc__",
"default_locale": "en",
"author": "Bitwarden Inc.",

View File

@@ -26,61 +26,47 @@
{{ "nonCompliantMembersError" | i18n }}
</bit-callout>
<ng-template #userDisplay let-user>
<div class="tw-flex tw-items-center">
<div class="tw-mr-6">
<bit-avatar [text]="user | userName" [id]="user.id" size="small"></bit-avatar>
</div>
<ng-container *ngIf="user.name; else emailOnly">
<div class="tw-truncate" [title]="user.name + ' ' + user.email">
{{ user.name }}
<small class="tw-block tw-text-muted tw-truncate">
{{ user.email }}
</small>
</div>
</ng-container>
<ng-template #emailOnly>
<div class="tw-truncate" [title]="user.email">{{ user.email }}</div>
</ng-template>
</div>
</ng-template>
<ng-container *ngIf="!done">
<bit-callout type="warning" *ngIf="users.length > 0 && !error && isRevoking">
<p>{{ "revokeUsersWarning" | i18n }}</p>
</bit-callout>
<bit-table *ngIf="accountDeprovisioning.enabled">
<bit-table>
<ng-container header>
<tr>
<th bitCell class="tw-w-1/2">{{ "member" | i18n }}</th>
<th bitCell *ngIf="this.showNoMasterPasswordWarning">{{ "details" | i18n }}</th>
<th bitCell>{{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }}</th>
<th bitCell class="tw-w-1/2" *ngIf="this.showNoMasterPasswordWarning">
{{ "details" | i18n }}
</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow *ngFor="let user of users">
<td bitCell width="30">
<div class="tw-flex tw-items-center">
<div class="tw-flex tw-items-center tw-mr-6">
<bit-avatar [text]="user | userName" [id]="user.id" size="small"></bit-avatar>
</div>
<div>
{{ user.email }}
<small class="tw-block tw-text-muted" *ngIf="user.name">{{ user.name }}</small>
</div>
</div>
<td bitCell class="tw-max-w-0">
<ng-container
*ngTemplateOutlet="userDisplay; context: { $implicit: user }"
></ng-container>
</td>
<td bitCell *ngIf="this.showNoMasterPasswordWarning">
<span class="tw-block tw-lowercase tw-text-muted">
<ng-container *ngIf="user.hasMasterPassword === true"> - </ng-container>
<ng-container *ngIf="user.hasMasterPassword === false">
<i class="bwi bwi-exclamation-triangle" aria-hidden="true"></i>
{{ "noMasterPassword" | i18n }}
</ng-container>
</span>
</td>
</tr>
</ng-template>
</bit-table>
<bit-table *ngIf="!accountDeprovisioning.enabled">
<ng-container header>
<tr>
<th bitCell colspan="2">{{ "user" | i18n }}</th>
<th bitCell *ngIf="this.showNoMasterPasswordWarning">{{ "details" | i18n }}</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow *ngFor="let user of users">
<td bitCell width="30">
<bit-avatar [text]="user | userName" [id]="user.id" size="small"></bit-avatar>
</td>
<td bitCell>
{{ user.email }}
<small class="tw-block tw-text-muted" *ngIf="user.name">{{ user.name }}</small>
</td>
<td bitCell *ngIf="this.showNoMasterPasswordWarning">
<td bitCell class="tw-w-1/2" *ngIf="this.showNoMasterPasswordWarning">
<span class="tw-block tw-lowercase tw-text-muted">
<ng-container *ngIf="user.hasMasterPassword === true"> - </ng-container>
<ng-container *ngIf="user.hasMasterPassword === false">
@@ -95,55 +81,21 @@
</ng-container>
<ng-container *ngIf="done">
<bit-table *ngIf="accountDeprovisioning.enabled">
<bit-table>
<ng-container header>
<tr>
<th bitCell class="tw-w-1/2">{{ "member" | i18n }}</th>
<th bitCell>{{ "status" | i18n }}</th>
<th bitCell class="tw-w-1/2">
{{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }}
</th>
<th bitCell class="tw-w-1/2">{{ "status" | i18n }}</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow *ngFor="let user of users">
<td bitCell width="30">
<div class="tw-flex tw-items-center">
<div class="tw-flex tw-items-center tw-mr-6">
<bit-avatar [text]="user | userName" [id]="user.id" size="small"></bit-avatar>
</div>
<div>
{{ user.email }}
<small class="tw-block tw-text-muted" *ngIf="user.name">{{ user.name }}</small>
</div>
</div>
</td>
<td bitCell *ngIf="statuses.has(user.id)">
{{ statuses.get(user.id) }}
</td>
<td bitCell *ngIf="!statuses.has(user.id)">
{{ "bulkFilteredMessage" | i18n }}
</td>
</tr>
</ng-template>
</bit-table>
<bit-table *ngIf="!accountDeprovisioning.enabled">
<ng-container header>
<tr>
<th bitCell class="tw-w-1/2">{{ "member" | i18n }}</th>
<th bitCell>{{ "status" | i18n }}</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow *ngFor="let user of users">
<td bitCell width="30">
<div class="tw-flex tw-items-center">
<div class="tw-flex tw-items-center tw-mr-6">
<bit-avatar [text]="user | userName" [id]="user.id" size="small"></bit-avatar>
</div>
<div>
{{ user.email }}
<small class="tw-block tw-text-muted" *ngIf="user.name">{{ user.name }}</small>
</div>
</div>
<td bitCell class="tw-max-w-0">
<ng-container
*ngTemplateOutlet="userDisplay; context: { $implicit: user }"
></ng-container>
</td>
<td bitCell *ngIf="statuses.has(user.id)">
{{ statuses.get(user.id) }}

View File

@@ -11,6 +11,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/abstractions/pr
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SyncService } from "@bitwarden/common/platform/sync";
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
@@ -24,6 +25,7 @@ describe("ProductSwitcherService", () => {
let organizationService: MockProxy<OrganizationService>;
let providerService: MockProxy<ProviderService>;
let accountService: FakeAccountService;
let platformUtilsService: MockProxy<PlatformUtilsService>;
let activeRouteParams = convertToParamMap({ organizationId: "1234" });
const getLastSync = jest.fn().mockResolvedValue(new Date("2024-05-14"));
const userId = Utils.newGuid() as UserId;
@@ -43,11 +45,13 @@ describe("ProductSwitcherService", () => {
organizationService = mock<OrganizationService>();
providerService = mock<ProviderService>();
accountService = mockAccountServiceWith(userId);
platformUtilsService = mock<PlatformUtilsService>();
router.url = "/";
router.events = of({});
organizationService.organizations$.mockReturnValue(of([{}] as Organization[]));
providerService.getAll.mockResolvedValue([] as Provider[]);
platformUtilsService.isSelfHost.mockReturnValue(false);
TestBed.configureTestingModule({
providers: [
@@ -55,6 +59,7 @@ describe("ProductSwitcherService", () => {
{ provide: OrganizationService, useValue: organizationService },
{ provide: ProviderService, useValue: providerService },
{ provide: AccountService, useValue: accountService },
{ provide: PlatformUtilsService, useValue: platformUtilsService },
{
provide: ActivatedRoute,
useValue: {
@@ -138,11 +143,31 @@ describe("ProductSwitcherService", () => {
});
describe("Admin/Organizations", () => {
it("includes Organizations in other when there are organizations", async () => {
it("includes Organizations with the internal route in other when there are organizations on cloud", async () => {
initiateService();
const products = await firstValueFrom(service.products$);
const organizations = products.other.find((p) => p.name === "Organizations");
expect(organizations).toBeDefined();
expect(organizations.marketingRoute.route).toBe("/create-organization");
expect(organizations.marketingRoute.external).toBe(false);
expect(products.other.find((p) => p.name === "Organizations")).toBeDefined();
expect(products.bento.find((p) => p.name === "Admin Console")).toBeUndefined();
});
it("includes Organizations with the external route in other when there are organizations on Self-Host", async () => {
platformUtilsService.isSelfHost.mockReturnValue(true);
initiateService();
const products = await firstValueFrom(service.products$);
const organizations = products.other.find((p) => p.name === "Organizations");
expect(organizations).toBeDefined();
expect(organizations.marketingRoute.route).toBe("https://bitwarden.com/products/business/");
expect(organizations.marketingRoute.external).toBe(true);
expect(products.other.find((p) => p.name === "Organizations")).toBeDefined();
expect(products.bento.find((p) => p.name === "Admin Console")).toBeUndefined();
});

View File

@@ -21,6 +21,7 @@ import {
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SyncService } from "@bitwarden/common/platform/sync";
export type ProductSwitcherItem = {
@@ -101,6 +102,7 @@ export class ProductSwitcherService {
private i18n: I18nPipe,
private syncService: SyncService,
private accountService: AccountService,
private platformUtilsService: PlatformUtilsService,
) {
this.pollUntilSynced();
}
@@ -151,6 +153,16 @@ export class ProductSwitcherService {
// TODO: This should be migrated to an Observable provided by the provider service and moved to the combineLatest above. See AC-2092.
const providers = await this.providerService.getAll();
const orgsMarketingRoute = this.platformUtilsService.isSelfHost()
? {
route: "https://bitwarden.com/products/business/",
external: true,
}
: {
route: "/create-organization",
external: false,
};
const products = {
pm: {
name: "Password Manager",
@@ -197,10 +209,7 @@ export class ProductSwitcherService {
orgs: {
name: "Organizations",
icon: "bwi-business",
marketingRoute: {
route: "https://bitwarden.com/products/business/",
external: true,
},
marketingRoute: orgsMarketingRoute,
otherProductOverrides: {
name: "Share your passwords",
supportingText: this.i18n.transform("protectYourFamilyOrBusiness"),

95
package-lock.json generated
View File

@@ -36,12 +36,12 @@
"argon2-browser": "1.18.0",
"big-integer": "1.6.52",
"bootstrap": "4.6.0",
"braintree-web-drop-in": "1.43.0",
"braintree-web-drop-in": "1.44.0",
"buffer": "6.0.3",
"bufferutil": "4.0.9",
"chalk": "4.1.2",
"commander": "11.1.0",
"core-js": "3.39.0",
"core-js": "3.40.0",
"form-data": "4.0.1",
"https-proxy-agent": "7.0.5",
"inquirer": "8.2.6",
@@ -156,7 +156,7 @@
"lint-staged": "15.4.1",
"mini-css-extract-plugin": "2.9.2",
"node-ipc": "9.2.1",
"postcss": "8.4.49",
"postcss": "8.5.1",
"postcss-loader": "8.1.1",
"prettier": "3.4.2",
"prettier-plugin-tailwindcss": "0.6.10",
@@ -169,7 +169,7 @@
"style-loader": "4.0.0",
"tailwindcss": "3.4.17",
"ts-jest": "29.2.2",
"ts-loader": "9.5.1",
"ts-loader": "9.5.2",
"tsconfig-paths-webpack-plugin": "4.2.0",
"type-fest": "2.19.0",
"typescript": "5.4.2",
@@ -190,7 +190,7 @@
},
"apps/browser": {
"name": "@bitwarden/browser",
"version": "2025.1.4"
"version": "2025.1.3"
},
"apps/cli": {
"name": "@bitwarden/cli",
@@ -7921,6 +7921,36 @@
"license": "MIT",
"optional": true
},
"node_modules/@paypal/accelerated-checkout-loader": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@paypal/accelerated-checkout-loader/-/accelerated-checkout-loader-1.1.0.tgz",
"integrity": "sha512-S2KkIpq15VnxYyI0tycvfYiNsqdsg2a92El2huYUVLsWnBbubl8toYK8khaP5nnxZ0MGl9mEB9Y9axmfOw2Yvg==",
"license": "MIT",
"dependencies": {
"@braintree/asset-loader": "2.0.0",
"envify": "^4.1.0",
"typescript": "^4.6.4"
}
},
"node_modules/@paypal/accelerated-checkout-loader/node_modules/@braintree/asset-loader": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@braintree/asset-loader/-/asset-loader-2.0.0.tgz",
"integrity": "sha512-7Zs3/g3lPTfkdtWr7cKh3tk1pDruXR++TXwGKkx7BPuTjjLNFul2JSfI+ScHzNU4u/gZNPNQagsSTlYxIhBgMA==",
"license": "MIT"
},
"node_modules/@paypal/accelerated-checkout-loader/node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/@phc/format": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz",
@@ -12870,9 +12900,9 @@
}
},
"node_modules/braintree-web": {
"version": "3.103.0",
"resolved": "https://registry.npmjs.org/braintree-web/-/braintree-web-3.103.0.tgz",
"integrity": "sha512-gwmC5LSUP5VUC2HmUyaFnEyLjRRAo1iKKHS5eD9KIAZHB7cAQ2il1V1q2f5zdz7+7EE11eSHXznj6n/Qm6jp6w==",
"version": "3.113.0",
"resolved": "https://registry.npmjs.org/braintree-web/-/braintree-web-3.113.0.tgz",
"integrity": "sha512-qykYxZyld4X1tRNgXZQ3ZGzmhDGTBTRQ6Q24KaG9PuYqo+P2TVDEDOVC6tRbkx2RUIdXLv2M6WpkG7oLqEia9Q==",
"license": "MIT",
"dependencies": {
"@braintree/asset-loader": "2.0.1",
@@ -12883,6 +12913,7 @@
"@braintree/sanitize-url": "7.0.4",
"@braintree/uuid": "1.0.0",
"@braintree/wrap-promise": "2.1.0",
"@paypal/accelerated-checkout-loader": "1.1.0",
"card-validator": "10.0.0",
"credit-card-type": "10.0.1",
"framebus": "6.0.0",
@@ -12892,9 +12923,9 @@
}
},
"node_modules/braintree-web-drop-in": {
"version": "1.43.0",
"resolved": "https://registry.npmjs.org/braintree-web-drop-in/-/braintree-web-drop-in-1.43.0.tgz",
"integrity": "sha512-lkUpQfYXR0CGtR7mPRR17AnZoYkHjhycxVnMGIPcWT6JPagEZcG/7tYyy34iWjYZeGa2wsquLBDV2Xeita962Q==",
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/braintree-web-drop-in/-/braintree-web-drop-in-1.44.0.tgz",
"integrity": "sha512-maOq9SwiXztIzixJhOras7K44x4UIqqnkyQMYAJqxQ8WkADv9AkflCu2j3IeVYCus/Th9gWWFHcBugn3C4sZGw==",
"license": "MIT",
"dependencies": {
"@braintree/asset-loader": "2.0.1",
@@ -12902,7 +12933,7 @@
"@braintree/event-emitter": "0.4.1",
"@braintree/uuid": "1.0.0",
"@braintree/wrap-promise": "2.1.0",
"braintree-web": "3.103.0"
"braintree-web": "3.113.0"
}
},
"node_modules/browser-assert": {
@@ -14451,9 +14482,9 @@
}
},
"node_modules/core-js": {
"version": "3.39.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz",
"integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==",
"version": "3.40.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz",
"integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
@@ -15996,6 +16027,19 @@
"node": ">=6"
}
},
"node_modules/envify": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz",
"integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==",
"license": "MIT",
"dependencies": {
"esprima": "^4.0.0",
"through": "~2.3.4"
},
"bin": {
"envify": "bin/envify"
}
},
"node_modules/envinfo": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
@@ -16853,7 +16897,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
@@ -24966,9 +25009,9 @@
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
"funding": [
{
@@ -27088,9 +27131,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
"integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
"dev": true,
"funding": [
{
@@ -27108,7 +27151,7 @@
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"nanoid": "^3.3.8",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -31181,9 +31224,9 @@
}
},
"node_modules/ts-loader": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
"integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==",
"version": "9.5.2",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz",
"integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -117,7 +117,7 @@
"lint-staged": "15.4.1",
"mini-css-extract-plugin": "2.9.2",
"node-ipc": "9.2.1",
"postcss": "8.4.49",
"postcss": "8.5.1",
"postcss-loader": "8.1.1",
"prettier": "3.4.2",
"prettier-plugin-tailwindcss": "0.6.10",
@@ -130,7 +130,7 @@
"style-loader": "4.0.0",
"tailwindcss": "3.4.17",
"ts-jest": "29.2.2",
"ts-loader": "9.5.1",
"ts-loader": "9.5.2",
"tsconfig-paths-webpack-plugin": "4.2.0",
"type-fest": "2.19.0",
"typescript": "5.4.2",
@@ -166,12 +166,12 @@
"argon2-browser": "1.18.0",
"big-integer": "1.6.52",
"bootstrap": "4.6.0",
"braintree-web-drop-in": "1.43.0",
"braintree-web-drop-in": "1.44.0",
"buffer": "6.0.3",
"bufferutil": "4.0.9",
"chalk": "4.1.2",
"commander": "11.1.0",
"core-js": "3.39.0",
"core-js": "3.40.0",
"form-data": "4.0.1",
"https-proxy-agent": "7.0.5",
"inquirer": "8.2.6",