diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7a7bb31ea54..ad802d791e8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -114,18 +114,33 @@ apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-d 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 -## DevOps team files ## -/.github/workflows @bitwarden/dept-devops - -# DevOps for Docker changes. -**/Dockerfile @bitwarden/dept-devops -**/*.Dockerfile @bitwarden/dept-devops -**/.dockerignore @bitwarden/dept-devops -**/entrypoint.sh @bitwarden/dept-devops - ## Locales ## apps/browser/src/_locales/en/messages.json apps/browser/store/locales/en apps/cli/src/locales/en/messages.json apps/desktop/src/locales/en/messages.json apps/web/src/locales/en/messages.json + +## BRE team owns these workflows ## +.github/workflows/brew-bump-desktop.yml @bitwarden/dept-bre +.github/workflows/deploy-web.yml @bitwarden/dept-bre +.github/workflows/publish-cli.yml @bitwarden/dept-bre +.github/workflows/publish-desktop.yml @bitwarden/dept-bre +.github/workflows/publish-web.yml @bitwarden/dept-bre +.github/workflows/retrieve-current-desktop-rollout.yml @bitwarden/dept-bre +.github/workflows/staged-rollout-desktop.yml @bitwarden/dept-bre + +## Shared ownership workflows ## +.github/workflows/release-browser.yml +.github/workflows/release-cli.yml +.github/workflows/release-desktop-beta.yml +.github/workflows/release-desktop.yml +.github/workflows/release-web.yml +.github/workflows/version-auto-bump.yml +.github/workflows/version-bump.yml + +## Docker files have shared ownership ## +**/Dockerfile +**/*.Dockerfile +**/.dockerignore +**/entrypoint.sh diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 25386222d4e..290663f4347 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -71,6 +71,15 @@ "joinOrganization": { "message": "Join organization" }, + "joinOrganizationName": { + "message": "Join $ORGANIZATIONNAME$", + "placeholders": { + "organizationName": { + "content": "$1", + "example": "My Org Name" + } + } + }, "finishJoiningThisOrganizationBySettingAMasterPassword": { "message": "Finish joining this organization by setting a master password." }, diff --git a/apps/browser/src/auth/popup/hint.component.ts b/apps/browser/src/auth/popup/hint.component.ts index bc1f68f4c43..e97236fe6a8 100644 --- a/apps/browser/src/auth/popup/hint.component.ts +++ b/apps/browser/src/auth/popup/hint.component.ts @@ -34,7 +34,7 @@ export class HintComponent extends BaseHintComponent { toastService, ); - super.onSuccessfulSubmit = async () => { + this.onSuccessfulSubmit = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.router.navigate([this.successRoute]); diff --git a/apps/browser/src/auth/popup/lock.component.ts b/apps/browser/src/auth/popup/lock.component.ts index 96bda7012d1..75fcfc58f6a 100644 --- a/apps/browser/src/auth/popup/lock.component.ts +++ b/apps/browser/src/auth/popup/lock.component.ts @@ -105,7 +105,7 @@ export class LockComponent extends BaseLockComponent implements OnInit { this.successRoute = "/tabs/current"; this.isInitialLockScreen = (window as any).previousPopupUrl == null; - super.onSuccessfulSubmit = async () => { + this.onSuccessfulSubmit = async () => { const previousUrl = this.routerService.getPreviousUrl(); if (previousUrl) { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. diff --git a/apps/browser/src/auth/popup/login-via-auth-request.component.ts b/apps/browser/src/auth/popup/login-via-auth-request.component.ts index 53f29badee6..33ec2acf387 100644 --- a/apps/browser/src/auth/popup/login-via-auth-request.component.ts +++ b/apps/browser/src/auth/popup/login-via-auth-request.component.ts @@ -74,7 +74,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { loginStrategyService, toastService, ); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { await syncService.fullSync(true); }; } diff --git a/apps/browser/src/auth/popup/login.component.ts b/apps/browser/src/auth/popup/login.component.ts index ea72fb61f5f..fd4d9bc547a 100644 --- a/apps/browser/src/auth/popup/login.component.ts +++ b/apps/browser/src/auth/popup/login.component.ts @@ -78,10 +78,10 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { registerRouteService, toastService, ); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { await syncService.fullSync(true); }; - super.successRoute = "/tabs/vault"; + this.successRoute = "/tabs/vault"; this.showPasswordless = flagEnabled("showPasswordless"); } diff --git a/apps/browser/src/auth/popup/sso.component.ts b/apps/browser/src/auth/popup/sso.component.ts index 42222c42b97..988563c2fe6 100644 --- a/apps/browser/src/auth/popup/sso.component.ts +++ b/apps/browser/src/auth/popup/sso.component.ts @@ -79,7 +79,7 @@ export class SsoComponent extends BaseSsoComponent { }); this.clientId = "browser"; - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); @@ -92,13 +92,13 @@ export class SsoComponent extends BaseSsoComponent { this.win.close(); }; - super.onSuccessfulLoginTde = async () => { + this.onSuccessfulLoginTde = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); }; - super.onSuccessfulLoginTdeNavigate = async () => { + this.onSuccessfulLoginTdeNavigate = async () => { this.win.close(); }; } diff --git a/apps/browser/src/auth/popup/two-factor-auth.component.ts b/apps/browser/src/auth/popup/two-factor-auth.component.ts index 27c95321100..9e755746e6f 100644 --- a/apps/browser/src/auth/popup/two-factor-auth.component.ts +++ b/apps/browser/src/auth/popup/two-factor-auth.component.ts @@ -118,7 +118,7 @@ export class TwoFactorAuthComponent win, toastService, ); - super.onSuccessfulLoginTdeNavigate = async () => { + this.onSuccessfulLoginTdeNavigate = async () => { this.win.close(); }; this.onSuccessfulLoginNavigate = this.goAfterLogIn; @@ -131,7 +131,7 @@ export class TwoFactorAuthComponent // WebAuthn fallback response this.selectedProviderType = TwoFactorProviderType.WebAuthn; this.token = this.route.snapshot.paramMap.get("webAuthnResponse"); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.syncService.fullSync(true); diff --git a/apps/browser/src/auth/popup/two-factor.component.ts b/apps/browser/src/auth/popup/two-factor.component.ts index e9167a5087a..27c4604be91 100644 --- a/apps/browser/src/auth/popup/two-factor.component.ts +++ b/apps/browser/src/auth/popup/two-factor.component.ts @@ -87,23 +87,23 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnInit accountService, toastService, ); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); }; - super.onSuccessfulLoginTde = async () => { + this.onSuccessfulLoginTde = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); }; - super.onSuccessfulLoginTdeNavigate = async () => { + this.onSuccessfulLoginTdeNavigate = async () => { this.win.close(); }; - super.successRoute = "/tabs/vault"; + this.successRoute = "/tabs/vault"; // FIXME: Chromium 110 has broken WebAuthn support in extensions via an iframe this.webAuthnNewTab = true; } @@ -113,7 +113,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnInit // WebAuthn fallback response this.selectedProviderType = TwoFactorProviderType.WebAuthn; this.token = this.route.snapshot.paramMap.get("webAuthnResponse"); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.syncService.fullSync(true); @@ -155,7 +155,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnInit // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe this.route.queryParams.pipe(first()).subscribe(async (qParams) => { if (qParams.sso === "true") { - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // This is not awaited so we don't pause the application while the sync is happening. // This call is executed by the service that lives in the background script so it will continue // the sync even if this tab closes. diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts index 1f0a38ad806..4109662fd66 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts @@ -1158,7 +1158,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ } if ( - this.showInlineMenuIdentities && this.inlineMenuFieldQualificationService.isFieldForAccountCreationForm( autofillFieldData, pageDetails, diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 0bf26f8c070..1a95ad74839 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -20,9 +20,11 @@ import { LockV2Component, PasswordHintComponent, RegistrationFinishComponent, + RegistrationLockAltIcon, RegistrationStartComponent, RegistrationStartSecondaryComponent, RegistrationStartSecondaryComponentData, + RegistrationUserAddIcon, SetPasswordJitComponent, UserLockIcon, } from "@bitwarden/auth/angular"; @@ -448,6 +450,47 @@ const routes: Routes = [ path: "", component: ExtensionAnonLayoutWrapperComponent, children: [ + { + path: "signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { + state: "signup", + pageIcon: RegistrationUserAddIcon, + pageTitle: { + key: "createAccount", + }, + showBackButton: true, + } satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationStartComponent, + }, + { + path: "", + component: RegistrationStartSecondaryComponent, + outlet: "secondary", + data: { + loginRoute: "/home", + } satisfies RegistrationStartSecondaryComponentData, + }, + ], + }, + { + path: "finish-signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { + pageIcon: RegistrationLockAltIcon, + state: "finish-signup", + showBackButton: true, + } satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationFinishComponent, + }, + ], + }, { path: "lockV2", canActivate: [canAccessFeature(FeatureFlag.ExtensionRefresh), lockGuard()], @@ -472,49 +515,6 @@ const routes: Routes = [ path: "", component: AnonLayoutWrapperComponent, children: [ - { - path: "signup", - canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], - data: { - state: "signup", - pageTitle: { - key: "createAccount", - }, - } satisfies RouteDataProperties & AnonLayoutWrapperData, - children: [ - { - path: "", - component: RegistrationStartComponent, - }, - { - path: "", - component: RegistrationStartSecondaryComponent, - outlet: "secondary", - data: { - loginRoute: "/home", - } satisfies RegistrationStartSecondaryComponentData, - }, - ], - }, - { - path: "finish-signup", - canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], - data: { - pageTitle: { - key: "setAStrongPassword", - }, - pageSubtitle: { - key: "finishCreatingYourAccountBySettingAPassword", - }, - state: "finish-signup", - } satisfies RouteDataProperties & AnonLayoutWrapperData, - children: [ - { - path: "", - component: RegistrationFinishComponent, - }, - ], - }, { path: "set-password-jit", canActivate: [canAccessFeature(FeatureFlag.EmailVerification)], diff --git a/apps/cli/package.json b/apps/cli/package.json index c5aeb306230..55bcee689d0 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -57,7 +57,7 @@ }, "dependencies": { "@koa/multer": "3.0.2", - "@koa/router": "12.0.1", + "@koa/router": "13.1.0", "argon2": "0.40.1", "big-integer": "1.6.52", "browser-hrtime": "1.1.8", @@ -68,7 +68,7 @@ "inquirer": "8.2.6", "jsdom": "25.0.1", "jszip": "3.10.1", - "koa": "2.15.0", + "koa": "2.15.3", "koa-bodyparser": "4.4.1", "koa-json": "2.0.2", "lowdb": "1.0.0", diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index e8ae31e78a8..8b8f62047f0 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -19,9 +19,11 @@ import { LockV2Component, PasswordHintComponent, RegistrationFinishComponent, + RegistrationLockAltIcon, RegistrationStartComponent, RegistrationStartSecondaryComponent, RegistrationStartSecondaryComponentData, + RegistrationUserAddIcon, SetPasswordJitComponent, UserLockIcon, } from "@bitwarden/auth/angular"; @@ -169,6 +171,7 @@ const routes: Routes = [ path: "signup", canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], data: { + pageIcon: RegistrationUserAddIcon, pageTitle: { key: "createAccount", }, @@ -192,12 +195,7 @@ const routes: Routes = [ path: "finish-signup", canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], data: { - pageTitle: { - key: "setAStrongPassword", - }, - pageSubtitle: { - key: "finishCreatingYourAccountBySettingAPassword", - }, + pageIcon: RegistrationLockAltIcon, } satisfies AnonLayoutWrapperData, children: [ { diff --git a/apps/desktop/src/auth/login/login-via-auth-request.component.ts b/apps/desktop/src/auth/login/login-via-auth-request.component.ts index c0a6a51b907..12be2f01c08 100644 --- a/apps/desktop/src/auth/login/login-via-auth-request.component.ts +++ b/apps/desktop/src/auth/login/login-via-auth-request.component.ts @@ -83,7 +83,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { toastService, ); - super.onSuccessfulLogin = () => { + this.onSuccessfulLogin = () => { return syncService.fullSync(true); }; } diff --git a/apps/desktop/src/auth/login/login.component.ts b/apps/desktop/src/auth/login/login.component.ts index b43e5bc84f0..6ba143421ca 100644 --- a/apps/desktop/src/auth/login/login.component.ts +++ b/apps/desktop/src/auth/login/login.component.ts @@ -99,7 +99,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit, OnDest registerRouteService, toastService, ); - super.onSuccessfulLogin = () => { + this.onSuccessfulLogin = () => { return syncService.fullSync(true); }; } diff --git a/apps/desktop/src/auth/sso.component.ts b/apps/desktop/src/auth/sso.component.ts index 6821a548945..760eef14e80 100644 --- a/apps/desktop/src/auth/sso.component.ts +++ b/apps/desktop/src/auth/sso.component.ts @@ -65,13 +65,13 @@ export class SsoComponent extends BaseSsoComponent { accountService, toastService, ); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); }; - super.onSuccessfulLoginTde = async () => { + this.onSuccessfulLoginTde = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); diff --git a/apps/desktop/src/auth/two-factor.component.ts b/apps/desktop/src/auth/two-factor.component.ts index d2c5efe929f..0050ec65608 100644 --- a/apps/desktop/src/auth/two-factor.component.ts +++ b/apps/desktop/src/auth/two-factor.component.ts @@ -89,13 +89,13 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest accountService, toastService, ); - super.onSuccessfulLogin = async () => { + this.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); }; - super.onSuccessfulLoginTde = async () => { + this.onSuccessfulLoginTde = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises syncService.fullSync(true); diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 4647853f715..9924a91fa36 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -602,6 +602,15 @@ "joinOrganization": { "message": "Join organization" }, + "joinOrganizationName": { + "message": "Join $ORGANIZATIONNAME$", + "placeholders": { + "organizationName": { + "content": "$1", + "example": "My Org Name" + } + } + }, "finishJoiningThisOrganizationBySettingAMasterPassword": { "message": "Finish joining this organization by setting a master password." }, diff --git a/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.html b/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.html index 85fb04730d4..2b6c86b1fdc 100644 --- a/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.html +++ b/apps/web/src/app/admin-console/organizations/policies/personal-ownership.component.html @@ -2,15 +2,7 @@ {{ "personalOwnershipExemption" | i18n }} -
-
- - -
-
+ + + {{ "turnOn" | i18n }} + diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.html b/apps/web/src/app/admin-console/organizations/settings/account.component.html index e4d3ee7de95..d1a1a091929 100644 --- a/apps/web/src/app/admin-console/organizations/settings/account.component.html +++ b/apps/web/src/app/admin-console/organizations/settings/account.component.html @@ -52,7 +52,11 @@

{{ "collectionManagement" | i18n }}

{{ "collectionManagementDesc" | i18n }}

@@ -60,12 +64,24 @@ {{ "allowAdminAccessToAllCollectionItemsDesc" | i18n }} - - {{ "limitCollectionCreationDeletionDesc" | i18n }} - - + + + {{ "limitCollectionCreationDesc" | i18n }} + + + + {{ "limitCollectionDeletionDesc" | i18n }} + + + + + + {{ "limitCollectionCreationDeletionDesc" | i18n }} + + + {{ "sendPasswordDescV2" | i18n }} - + = 12" + "node": ">= 18" } }, "node_modules/@leichtgewicht/ip-codec": { @@ -9524,9 +9521,9 @@ } }, "node_modules/@types/koa": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.14.0.tgz", - "integrity": "sha512-DTDUyznHGNHAl+wd1n0z1jxNajduyTh8R53xoewuerdBzGo6Ogj6F2299BFtrexJw4NtgjsI5SMPCmV9gZwGXA==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz", + "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==", "dev": true, "license": "MIT", "dependencies": { @@ -25243,9 +25240,9 @@ } }, "node_modules/koa": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.0.tgz", - "integrity": "sha512-KEL/vU1knsoUvfP4MC4/GthpQrY/p6dzwaaGI6Rt4NQuFqkw3qrvsdYF5pz3wOfi7IGTvMPHC9aZIcUKYFNxsw==", + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", "license": "MIT", "dependencies": { "accepts": "^1.3.5", @@ -27277,6 +27274,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -35777,9 +35775,9 @@ "license": "MIT" }, "node_modules/tailwindcss": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.11.tgz", - "integrity": "sha512-qhEuBcLemjSJk5ajccN9xJFtM/h0AVCPaA6C92jNP+M2J8kX+eMJHI7R2HFKUvvAsMpcfLILMCFYSeDwpMmlUg==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 86224e7277e..402b7c482d9 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@types/jest": "29.5.12", "@types/jquery": "3.5.30", "@types/jsdom": "21.1.7", - "@types/koa": "2.14.0", + "@types/koa": "2.15.0", "@types/koa__multer": "2.0.7", "@types/koa__router": "12.0.4", "@types/koa-bodyparser": "4.3.7", @@ -134,7 +134,7 @@ "sass-loader": "16.0.1", "storybook": "8.2.9", "style-loader": "3.3.4", - "tailwindcss": "3.4.11", + "tailwindcss": "3.4.14", "ts-jest": "29.2.2", "ts-loader": "9.5.1", "tsconfig-paths-webpack-plugin": "4.1.0", @@ -161,7 +161,7 @@ "@bitwarden/sdk-internal": "0.1.3", "@electron/fuses": "1.8.0", "@koa/multer": "3.0.2", - "@koa/router": "12.0.1", + "@koa/router": "13.1.0", "@microsoft/signalr": "8.0.7", "@microsoft/signalr-protocol-msgpack": "8.0.7", "@ng-select/ng-select": "11.2.0", @@ -181,7 +181,7 @@ "jquery": "3.7.1", "jsdom": "25.0.1", "jszip": "3.10.1", - "koa": "2.15.0", + "koa": "2.15.3", "koa-bodyparser": "4.4.1", "koa-json": "2.0.2", "lowdb": "1.0.0",