+
+
-
diff --git a/apps/web/src/app/billing/individual/user-subscription.component.ts b/apps/web/src/app/billing/individual/user-subscription.component.ts
index fa21317c18..8535f23f82 100644
--- a/apps/web/src/app/billing/individual/user-subscription.component.ts
+++ b/apps/web/src/app/billing/individual/user-subscription.component.ts
@@ -20,6 +20,10 @@ import {
OffboardingSurveyDialogResultType,
openOffboardingSurvey,
} from "../shared/offboarding-survey.component";
+import {
+ UpdateLicenseDialogComponent,
+ UpdateLicenseDialogResult,
+} from "../shared/update-license-dialog.component";
@Component({
templateUrl: "user-subscription.component.html",
@@ -131,21 +135,16 @@ export class UserSubscriptionComponent implements OnInit {
});
}
- updateLicense() {
+ updateLicense = async () => {
if (this.loading) {
return;
}
- this.showUpdateLicense = true;
- }
-
- closeUpdateLicense(load: boolean) {
- this.showUpdateLicense = false;
- if (load) {
- // 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.load();
+ const dialogRef = UpdateLicenseDialogComponent.open(this.dialogService);
+ const result = await lastValueFrom(dialogRef.closed);
+ if (result === UpdateLicenseDialogResult.Updated) {
+ await this.load();
}
- }
+ };
adjustStorage = (add: boolean) => {
return async () => {
diff --git a/apps/web/src/app/billing/shared/billing-shared.module.ts b/apps/web/src/app/billing/shared/billing-shared.module.ts
index 35fe33c7e0..0031cff775 100644
--- a/apps/web/src/app/billing/shared/billing-shared.module.ts
+++ b/apps/web/src/app/billing/shared/billing-shared.module.ts
@@ -12,6 +12,7 @@ import { PaymentMethodComponent } from "./payment-method.component";
import { PaymentComponent } from "./payment.component";
import { SecretsManagerSubscribeComponent } from "./sm-subscribe.component";
import { TaxInfoComponent } from "./tax-info.component";
+import { UpdateLicenseDialogComponent } from "./update-license-dialog.component";
import { UpdateLicenseComponent } from "./update-license.component";
@NgModule({
@@ -24,6 +25,7 @@ import { UpdateLicenseComponent } from "./update-license.component";
PaymentMethodComponent,
SecretsManagerSubscribeComponent,
UpdateLicenseComponent,
+ UpdateLicenseDialogComponent,
OffboardingSurveyComponent,
],
exports: [
@@ -34,6 +36,7 @@ import { UpdateLicenseComponent } from "./update-license.component";
BillingHistoryComponent,
SecretsManagerSubscribeComponent,
UpdateLicenseComponent,
+ UpdateLicenseDialogComponent,
OffboardingSurveyComponent,
],
})
diff --git a/apps/web/src/app/billing/shared/update-license-dialog.component.html b/apps/web/src/app/billing/shared/update-license-dialog.component.html
new file mode 100644
index 0000000000..6430c47528
--- /dev/null
+++ b/apps/web/src/app/billing/shared/update-license-dialog.component.html
@@ -0,0 +1,40 @@
+
diff --git a/apps/web/src/app/billing/shared/update-license-dialog.component.ts b/apps/web/src/app/billing/shared/update-license-dialog.component.ts
new file mode 100644
index 0000000000..5f9a1e94be
--- /dev/null
+++ b/apps/web/src/app/billing/shared/update-license-dialog.component.ts
@@ -0,0 +1,38 @@
+import { Component } from "@angular/core";
+import { FormBuilder } from "@angular/forms";
+
+import { ApiService } from "@bitwarden/common/abstractions/api.service";
+import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { DialogService } from "@bitwarden/components";
+
+import { UpdateLicenseComponent } from "./update-license.component";
+
+export enum UpdateLicenseDialogResult {
+ Updated = "updated",
+ Cancelled = "cancelled",
+}
+@Component({
+ templateUrl: "update-license-dialog.component.html",
+})
+export class UpdateLicenseDialogComponent extends UpdateLicenseComponent {
+ constructor(
+ apiService: ApiService,
+ i18nService: I18nService,
+ platformUtilsService: PlatformUtilsService,
+ organizationApiService: OrganizationApiServiceAbstraction,
+ formBuilder: FormBuilder,
+ ) {
+ super(apiService, i18nService, platformUtilsService, organizationApiService, formBuilder);
+ }
+ async submitLicense() {
+ await this.submit();
+ }
+ submitLicenseDialog = async () => {
+ await this.submitLicense();
+ };
+ static open(dialogService: DialogService) {
+ return dialogService.open
(UpdateLicenseDialogComponent);
+ }
+}
From 5a25024f591d590d6a1c297b97cf3168ff6fb96c Mon Sep 17 00:00:00 2001
From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com>
Date: Tue, 28 May 2024 17:38:15 +0100
Subject: [PATCH 2/7] Change Addons to Add-ons (#9392)
---
apps/web/src/locales/en/messages.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json
index c21955179d..e090f6a7ab 100644
--- a/apps/web/src/locales/en/messages.json
+++ b/apps/web/src/locales/en/messages.json
@@ -2102,7 +2102,7 @@
"message": "Bitwarden Families plan."
},
"addons": {
- "message": "Addons"
+ "message": "Add-ons"
},
"premiumAccess": {
"message": "Premium access"
From 3fc2570a0e2437242b880fd1662f31f573ab11c9 Mon Sep 17 00:00:00 2001
From: DanHillesheim <79476558+DanHillesheim@users.noreply.github.com>
Date: Tue, 28 May 2024 10:42:53 -0600
Subject: [PATCH 3/7] Trial initiation content updates (#9138)
---
.../content/enterprise-content.component.html | 73 +++++++++++-------
.../content/logo-badges.component.html | 11 +++
.../content/logo-badges.component.ts | 7 ++
.../content/teams1-content.component.html | 43 +++++++----
.../trial-initiation.module.ts | 2 +
.../register-layout/vault-signup-badges.png | Bin 0 -> 20376 bytes
6 files changed, 94 insertions(+), 42 deletions(-)
create mode 100644 apps/web/src/app/auth/trial-initiation/content/logo-badges.component.html
create mode 100644 apps/web/src/app/auth/trial-initiation/content/logo-badges.component.ts
create mode 100644 apps/web/src/images/register-layout/vault-signup-badges.png
diff --git a/apps/web/src/app/auth/trial-initiation/content/enterprise-content.component.html b/apps/web/src/app/auth/trial-initiation/content/enterprise-content.component.html
index 120748d4c0..4abb44db4f 100644
--- a/apps/web/src/app/auth/trial-initiation/content/enterprise-content.component.html
+++ b/apps/web/src/app/auth/trial-initiation/content/enterprise-content.component.html
@@ -1,34 +1,51 @@
-The Password Manager Trusted by Millions
-
-
Everything enterprises need out of a password manager:
+
Start your 7-day free trial of Bitwarden
+
+
+ Strengthen business security with the password manager designed for seamless administration and
+ employee usability.
+
- - Secure password sharing
- -
- Easy, flexible SSO and SCIM integrations
+
-
+ Instantly and securely share credentials with the groups and individuals who need them
+
+ -
+ Strengthen employee security practices through centralized administrative control and
+ policies
+
+ -
+ Streamline user onboarding and automate account provisioning with turnkey SSO and SCIM
+ integrations
+
+ -
+ Migrate to Bitwarden in minutes with comprehensive import options
+
+ -
+ Save time and increase productivity with autofill and instant device syncing
+
+ -
+ Empower employees to secure their digital life at home, at work, and on the go by offering a
+ free Families plan to all Enterprise users
- - Free families plan for users
- - Quick import and migration tools
- - Simple, streamlined user experience
- - Priority support and trainers
diff --git a/apps/web/src/app/auth/trial-initiation/content/logo-badges.component.html b/apps/web/src/app/auth/trial-initiation/content/logo-badges.component.html
new file mode 100644
index 0000000000..d1b33eab3a
--- /dev/null
+++ b/apps/web/src/app/auth/trial-initiation/content/logo-badges.component.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/apps/web/src/app/auth/trial-initiation/content/logo-badges.component.ts b/apps/web/src/app/auth/trial-initiation/content/logo-badges.component.ts
new file mode 100644
index 0000000000..c23432b67c
--- /dev/null
+++ b/apps/web/src/app/auth/trial-initiation/content/logo-badges.component.ts
@@ -0,0 +1,7 @@
+import { Component } from "@angular/core";
+
+@Component({
+ selector: "app-logo-badges",
+ templateUrl: "logo-badges.component.html",
+})
+export class LogoBadgesComponent {}
diff --git a/apps/web/src/app/auth/trial-initiation/content/teams1-content.component.html b/apps/web/src/app/auth/trial-initiation/content/teams1-content.component.html
index d26bbabaef..42f99be26b 100644
--- a/apps/web/src/app/auth/trial-initiation/content/teams1-content.component.html
+++ b/apps/web/src/app/auth/trial-initiation/content/teams1-content.component.html
@@ -1,21 +1,36 @@
-
Start Your Teams Free Trial Now
-
-
$4 per month / per user
-
Annual subscription
-
+
Start your 7-day free trial for Teams
+
- Millions of individuals, teams, and organizations worldwide trust Bitwarden for secure password
- storage and sharing.
+ Strengthen business security with an easy-to-use password manager your team will love.
-
- - Collaborate and share securely
- - Deploy and manage quickly and easily
- - Access anywhere on any device
- - Create your account to get started
+
+ -
+ Instantly and securely share credentials with the groups and individuals who need them
+
+ -
+ Migrate to Bitwarden in minutes with comprehensive import options
+
+ -
+ Save time and increase productivity with autofill and instant device syncing
+
+ -
+ Enhance security practices across your team with easy user management
+
diff --git a/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts b/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts
index 6e25e97858..57d982fd00 100644
--- a/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts
+++ b/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts
@@ -24,6 +24,7 @@ import { DefaultContentComponent } from "./content/default-content.component";
import { EnterpriseContentComponent } from "./content/enterprise-content.component";
import { Enterprise1ContentComponent } from "./content/enterprise1-content.component";
import { Enterprise2ContentComponent } from "./content/enterprise2-content.component";
+import { LogoBadgesComponent } from "./content/logo-badges.component";
import { LogoCnet5StarsComponent } from "./content/logo-cnet-5-stars.component";
import { LogoCnetComponent } from "./content/logo-cnet.component";
import { LogoForbesComponent } from "./content/logo-forbes.component";
@@ -69,6 +70,7 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul
CnetTeamsContentComponent,
AbmEnterpriseContentComponent,
AbmTeamsContentComponent,
+ LogoBadgesComponent,
LogoCnet5StarsComponent,
LogoCnetComponent,
LogoForbesComponent,
diff --git a/apps/web/src/images/register-layout/vault-signup-badges.png b/apps/web/src/images/register-layout/vault-signup-badges.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a80ffaebb9ad3d6ba162b5237f0b465205f974d
GIT binary patch
literal 20376
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
Date: Tue, 28 May 2024 20:35:10 +0200
Subject: [PATCH 4/7] Fix missing confirmation toast on vault export (#9398)
Co-authored-by: Daniel James Smith
---
apps/web/src/app/tools/vault-export/export.component.ts | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/apps/web/src/app/tools/vault-export/export.component.ts b/apps/web/src/app/tools/vault-export/export.component.ts
index 7902d2818d..df53e599ed 100644
--- a/apps/web/src/app/tools/vault-export/export.component.ts
+++ b/apps/web/src/app/tools/vault-export/export.component.ts
@@ -42,4 +42,9 @@ export class ExportComponent extends BaseExportComponent {
organizationService,
);
}
+
+ protected saved() {
+ super.saved();
+ this.platformUtilsService.showToast("success", null, this.i18nService.t("exportSuccess"));
+ }
}
From e14e2627ad7409b5a538bf928a9abdf5858957fe Mon Sep 17 00:00:00 2001
From: Cesar Gonzalez
Date: Tue, 28 May 2024 14:05:24 -0500
Subject: [PATCH 5/7] [PM-8447] Autofill On Load Causes Extension to Hang After
Browser Startup (#9400)
---
.../services/autofill.service.spec.ts | 20 +++++++++++++++++++
.../src/autofill/services/autofill.service.ts | 7 ++++++-
.../browser/src/background/main.background.ts | 1 +
.../src/popup/services/services.module.ts | 1 +
4 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/apps/browser/src/autofill/services/autofill.service.spec.ts b/apps/browser/src/autofill/services/autofill.service.spec.ts
index 24b1c90b3f..23f690544d 100644
--- a/apps/browser/src/autofill/services/autofill.service.spec.ts
+++ b/apps/browser/src/autofill/services/autofill.service.spec.ts
@@ -1,6 +1,8 @@
import { mock, mockReset, MockProxy } from "jest-mock-extended";
import { BehaviorSubject, of } from "rxjs";
+import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
+import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service";
import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants";
import { AutofillSettingsService } from "@bitwarden/common/autofill/services/autofill-settings.service";
@@ -78,12 +80,17 @@ describe("AutofillService", () => {
const userVerificationService = mock();
const billingAccountProfileStateService = mock();
const platformUtilsService = mock();
+ let activeAccountStatusMock$: BehaviorSubject;
+ let authService: MockProxy;
beforeEach(() => {
scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService);
inlineMenuVisibilityMock$ = new BehaviorSubject(AutofillOverlayVisibility.OnFieldFocus);
autofillSettingsService = mock();
(autofillSettingsService as any).inlineMenuVisibility$ = inlineMenuVisibilityMock$;
+ activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Unlocked);
+ authService = mock();
+ authService.activeAccountStatus$ = activeAccountStatusMock$;
autofillService = new AutofillService(
cipherService,
autofillSettingsService,
@@ -95,6 +102,7 @@ describe("AutofillService", () => {
billingAccountProfileStateService,
scriptInjectorService,
accountService,
+ authService,
);
domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider);
@@ -287,6 +295,18 @@ describe("AutofillService", () => {
});
});
+ it("skips injecting the autofiller script when the user's account is not unlocked", async () => {
+ activeAccountStatusMock$.next(AuthenticationStatus.Locked);
+
+ await autofillService.injectAutofillScripts(sender.tab, sender.frameId, true);
+
+ expect(BrowserApi.executeScriptInTab).not.toHaveBeenCalledWith(tabMock.id, {
+ file: "content/autofiller.js",
+ frameId: sender.frameId,
+ ...defaultExecuteScriptOptions,
+ });
+ });
+
it("will inject the bootstrap-autofill-overlay script if the user has the autofill overlay enabled", async () => {
await autofillService.injectAutofillScripts(sender.tab, sender.frameId);
diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts
index 5348ca5b9a..9ec2052381 100644
--- a/apps/browser/src/autofill/services/autofill.service.ts
+++ b/apps/browser/src/autofill/services/autofill.service.ts
@@ -3,7 +3,9 @@ import { pairwise } from "rxjs/operators";
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
+import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
+import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants";
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
@@ -61,6 +63,7 @@ export default class AutofillService implements AutofillServiceInterface {
private billingAccountProfileStateService: BillingAccountProfileStateService,
private scriptInjectorService: ScriptInjectorService,
private accountService: AccountService,
+ private authService: AuthService,
) {}
/**
@@ -113,6 +116,8 @@ export default class AutofillService implements AutofillServiceInterface {
// Autofill user settings loaded from state can await the active account state indefinitely
// if not guarded by an active account check (e.g. the user is logged in)
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
+ const authStatus = await firstValueFrom(this.authService.activeAccountStatus$);
+ const accountIsUnlocked = authStatus === AuthenticationStatus.Unlocked;
let overlayVisibility: InlineMenuVisibilitySetting = AutofillOverlayVisibility.Off;
let autoFillOnPageLoadIsEnabled = false;
@@ -126,7 +131,7 @@ export default class AutofillService implements AutofillServiceInterface {
const injectedScripts = [mainAutofillScript];
- if (activeAccount) {
+ if (activeAccount && accountIsUnlocked) {
autoFillOnPageLoadIsEnabled = await this.getAutofillOnPageLoad();
}
diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts
index a382a76781..2072f8396e 100644
--- a/apps/browser/src/background/main.background.ts
+++ b/apps/browser/src/background/main.background.ts
@@ -872,6 +872,7 @@ export default class MainBackground {
this.billingAccountProfileStateService,
this.scriptInjectorService,
this.accountService,
+ this.authService,
);
this.auditService = new AuditService(this.cryptoFunctionService, this.apiService);
diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts
index d260b4ec7b..342b3d26a6 100644
--- a/apps/browser/src/popup/services/services.module.ts
+++ b/apps/browser/src/popup/services/services.module.ts
@@ -341,6 +341,7 @@ const safeProviders: SafeProvider[] = [
BillingAccountProfileStateService,
ScriptInjectorService,
AccountServiceAbstraction,
+ AuthService,
],
}),
safeProvider({
From e47f83db80546a6fec4bbd04d2cb49ab05c31c49 Mon Sep 17 00:00:00 2001
From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com>
Date: Tue, 28 May 2024 14:17:20 -0500
Subject: [PATCH 6/7] fix: remove view events menu option for users without
permission, refs PM-7024 (#9355)
---
apps/web/src/app/vault/org-vault/vault.component.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/web/src/app/vault/org-vault/vault.component.html b/apps/web/src/app/vault/org-vault/vault.component.html
index 06907b9e5d..af8789c906 100644
--- a/apps/web/src/app/vault/org-vault/vault.component.html
+++ b/apps/web/src/app/vault/org-vault/vault.component.html
@@ -62,7 +62,7 @@
[showPremiumFeatures]="organization?.useTotp"
[showBulkMove]="false"
[showBulkTrashOptions]="filter.type === 'trash'"
- [useEvents]="organization?.useEvents"
+ [useEvents]="organization?.canAccessEventLogs"
[showAdminActions]="true"
(onEvent)="onVaultItemsEvent($event)"
[showBulkEditCollectionAccess]="organization?.flexibleCollections"
From bc170f520748a8f320e0ccbc6fb2edcb31972fb2 Mon Sep 17 00:00:00 2001
From: Jake Fink
Date: Tue, 28 May 2024 15:17:30 -0400
Subject: [PATCH 7/7] use valid userId when logging out (#9334)
---
apps/browser/src/background/main.background.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts
index 2072f8396e..51d18f15a3 100644
--- a/apps/browser/src/background/main.background.ts
+++ b/apps/browser/src/background/main.background.ts
@@ -1333,7 +1333,7 @@ export default class MainBackground {
]);
//Needs to be checked before state is cleaned
- const needStorageReseed = await this.needsStorageReseed(userId);
+ const needStorageReseed = await this.needsStorageReseed(userBeingLoggedOut);
await this.stateService.clean({ userId: userBeingLoggedOut });
await this.accountService.clean(userBeingLoggedOut);