- |
-
- |
-
- {{ user.email }}
- {{ user.name }}
- |
-
+ |
-
@@ -95,55 +81,21 @@
-
+
- | {{ "member" | i18n }} |
- {{ "status" | i18n }} |
+
+ {{ (accountDeprovisioning.enabled ? "member" : "user") | i18n }}
+ |
+ {{ "status" | i18n }} |
-
-
-
-
-
-
- {{ user.email }}
- {{ user.name }}
-
-
- |
-
- {{ statuses.get(user.id) }}
- |
-
- {{ "bulkFilteredMessage" | i18n }}
- |
-
-
-
-
-
-
-
- | {{ "member" | i18n }} |
- {{ "status" | i18n }} |
-
-
-
-
-
-
-
-
-
-
- {{ user.email }}
- {{ user.name }}
-
-
+ |
+
|
{{ statuses.get(user.id) }}
diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts
index 4187900060b..a1ac434d590 100644
--- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts
+++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts
@@ -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;
let providerService: MockProxy;
let accountService: FakeAccountService;
+ let platformUtilsService: MockProxy;
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();
providerService = mock();
accountService = mockAccountServiceWith(userId);
+ platformUtilsService = mock();
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();
});
diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts
index f962879d61a..1cc5c92c120 100644
--- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts
+++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts
@@ -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"),
diff --git a/package-lock.json b/package-lock.json
index 0ea31c0a8ad..c60ae62e657 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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": {
diff --git a/package.json b/package.json
index a9a281db728..5145b058f6f 100644
--- a/package.json
+++ b/package.json
@@ -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",
| |