Skip to content

Commit 5f7e1f9

Browse files
authored
chore(flag-removal): [Auth/PM20439] Remove flagging logic and flag (BrowserExtensionLoginApproval) (#16568)
1 parent 0bfc5da commit 5f7e1f9

File tree

11 files changed

+64
-127
lines changed

11 files changed

+64
-127
lines changed

apps/browser/src/auth/popup/settings/account-security.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ <h2 bitTypography="h6">{{ "vaultTimeoutHeader" | i18n }}</h2>
102102
</bit-card>
103103
</bit-section>
104104

105-
<bit-section *ngIf="extensionLoginApprovalFlagEnabled">
105+
<bit-section>
106106
<bit-section-header>
107107
<h2 bitTypography="h6">{{ "manageDevices" | i18n }}</h2>
108108
</bit-section-header>

apps/browser/src/auth/popup/settings/account-security.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Component } from "@angular/core";
22
import { ComponentFixture, TestBed } from "@angular/core/testing";
33
import { By } from "@angular/platform-browser";
4+
import { ActivatedRoute } from "@angular/router";
45
import { mock } from "jest-mock-extended";
56
import { firstValueFrom, of } from "rxjs";
67

@@ -19,7 +20,6 @@ import {
1920
VaultTimeoutStringType,
2021
VaultTimeoutAction,
2122
} from "@bitwarden/common/key-management/vault-timeout";
22-
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
2323
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
2424
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
2525
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -67,6 +67,7 @@ describe("AccountSecurityComponent", () => {
6767
providers: [
6868
{ provide: AccountService, useValue: accountService },
6969
{ provide: AccountSecurityComponent, useValue: mock<AccountSecurityComponent>() },
70+
{ provide: ActivatedRoute, useValue: mock<ActivatedRoute>() },
7071
{ provide: BiometricsService, useValue: mock<BiometricsService>() },
7172
{ provide: BiometricStateService, useValue: biometricStateService },
7273
{ provide: DialogService, useValue: dialogService },
@@ -88,7 +89,6 @@ describe("AccountSecurityComponent", () => {
8889
{ provide: LogService, useValue: mock<LogService>() },
8990
{ provide: OrganizationService, useValue: mock<OrganizationService>() },
9091
{ provide: CollectionService, useValue: mock<CollectionService>() },
91-
{ provide: ConfigService, useValue: mock<ConfigService>() },
9292
{ provide: ValidationService, useValue: validationService },
9393
],
9494
})

apps/browser/src/auth/popup/settings/account-security.component.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/
3131
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
3232
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
3333
import { getUserId } from "@bitwarden/common/auth/services/account.service";
34-
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
3534
import { PinServiceAbstraction } from "@bitwarden/common/key-management/pin/pin.service.abstraction";
3635
import {
3736
VaultTimeout,
@@ -41,7 +40,6 @@ import {
4140
VaultTimeoutSettingsService,
4241
VaultTimeoutStringType,
4342
} from "@bitwarden/common/key-management/vault-timeout";
44-
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
4543
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
4644
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
4745
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -115,7 +113,6 @@ export class AccountSecurityComponent implements OnInit, OnDestroy {
115113
biometricUnavailabilityReason: string;
116114
showChangeMasterPass = true;
117115
pinEnabled$: Observable<boolean> = of(true);
118-
extensionLoginApprovalFlagEnabled = false;
119116

120117
form = this.formBuilder.group({
121118
vaultTimeout: [null as VaultTimeout | null],
@@ -157,7 +154,6 @@ export class AccountSecurityComponent implements OnInit, OnDestroy {
157154
private biometricsService: BiometricsService,
158155
private vaultNudgesService: NudgesService,
159156
private validationService: ValidationService,
160-
private configService: ConfigService,
161157
private logService: LogService,
162158
) {}
163159

@@ -239,10 +235,6 @@ export class AccountSecurityComponent implements OnInit, OnDestroy {
239235
};
240236
this.form.patchValue(initialValues, { emitEvent: false });
241237

242-
this.extensionLoginApprovalFlagEnabled = await this.configService.getFeatureFlag(
243-
FeatureFlag.PM14938_BrowserExtensionLoginApproval,
244-
);
245-
246238
timer(0, 1000)
247239
.pipe(
248240
switchMap(async () => {

apps/browser/src/popup/app-routing.module.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
} from "@bitwarden/angular/auth/guards";
1515
import { ChangePasswordComponent } from "@bitwarden/angular/auth/password-management/change-password";
1616
import { SetInitialPasswordComponent } from "@bitwarden/angular/auth/password-management/set-initial-password/set-initial-password.component";
17-
import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard";
1817
import {
1918
DevicesIcon,
2019
RegistrationUserAddIcon,
@@ -40,7 +39,6 @@ import {
4039
TwoFactorAuthComponent,
4140
TwoFactorAuthGuard,
4241
} from "@bitwarden/auth/angular";
43-
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
4442
import { AnonLayoutWrapperComponent, AnonLayoutWrapperData } from "@bitwarden/components";
4543
import { LockComponent, ConfirmKeyConnectorDomainComponent } from "@bitwarden/key-management-ui";
4644

@@ -262,7 +260,7 @@ const routes: Routes = [
262260
{
263261
path: "device-management",
264262
component: ExtensionDeviceManagementComponent,
265-
canActivate: [canAccessFeature(FeatureFlag.PM14938_BrowserExtensionLoginApproval), authGuard],
263+
canActivate: [authGuard],
266264
data: { elevation: 1 } satisfies RouteDataProperties,
267265
},
268266
{

apps/browser/src/popup/app.component.ts

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
4242
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
4343
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
4444
import { PendingAuthRequestsStateService } from "@bitwarden/common/auth/services/auth-request-answering/pending-auth-requests.state";
45-
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
4645
import { AnimationControlService } from "@bitwarden/common/platform/abstractions/animation-control.service";
47-
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
4846
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
4947
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
5048
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -82,7 +80,6 @@ export class AppComponent implements OnInit, OnDestroy {
8280
private activeUserId: UserId;
8381
private routerAnimations = false;
8482
private processingPendingAuth = false;
85-
private extensionLoginApprovalFeatureFlag = false;
8683

8784
private destroy$ = new Subject<void>();
8885

@@ -118,7 +115,6 @@ export class AppComponent implements OnInit, OnDestroy {
118115
private authRequestService: AuthRequestServiceAbstraction,
119116
private pendingAuthRequestsState: PendingAuthRequestsStateService,
120117
private authRequestAnsweringService: AuthRequestAnsweringServiceAbstraction,
121-
private readonly configService: ConfigService,
122118
) {
123119
this.deviceTrustToastService.setupListeners$.pipe(takeUntilDestroyed()).subscribe();
124120

@@ -127,10 +123,6 @@ export class AppComponent implements OnInit, OnDestroy {
127123
}
128124

129125
async ngOnInit() {
130-
this.extensionLoginApprovalFeatureFlag = await firstValueFrom(
131-
this.configService.getFeatureFlag$(FeatureFlag.PM14938_BrowserExtensionLoginApproval),
132-
);
133-
134126
initPopupClosedListener();
135127

136128
this.compactModeService.init();
@@ -140,24 +132,22 @@ export class AppComponent implements OnInit, OnDestroy {
140132
this.activeUserId = account?.id;
141133
});
142134

143-
if (this.extensionLoginApprovalFeatureFlag) {
144-
// Trigger processing auth requests when the active user is in an unlocked state. Runs once when
145-
// the popup is open.
146-
this.accountService.activeAccount$
147-
.pipe(
148-
map((a) => a?.id), // Extract active userId
149-
distinctUntilChanged(), // Only when userId actually changes
150-
filter((userId) => userId != null), // Require a valid userId
151-
switchMap((userId) => this.authService.authStatusFor$(userId).pipe(take(1))), // Get current auth status once for new user
152-
filter((status) => status === AuthenticationStatus.Unlocked), // Only when the new user is Unlocked
153-
tap(() => {
154-
// Trigger processing when switching users while popup is open
155-
void this.authRequestAnsweringService.processPendingAuthRequests();
156-
}),
157-
takeUntil(this.destroy$),
158-
)
159-
.subscribe();
160-
}
135+
// Trigger processing auth requests when the active user is in an unlocked state. Runs once when
136+
// the popup is open.
137+
this.accountService.activeAccount$
138+
.pipe(
139+
map((a) => a?.id), // Extract active userId
140+
distinctUntilChanged(), // Only when userId actually changes
141+
filter((userId) => userId != null), // Require a valid userId
142+
switchMap((userId) => this.authService.authStatusFor$(userId).pipe(take(1))), // Get current auth status once for new user
143+
filter((status) => status === AuthenticationStatus.Unlocked), // Only when the new user is Unlocked
144+
tap(() => {
145+
// Trigger processing when switching users while popup is open
146+
void this.authRequestAnsweringService.processPendingAuthRequests();
147+
}),
148+
takeUntil(this.destroy$),
149+
)
150+
.subscribe();
161151

162152
this.authService.activeAccountStatus$
163153
.pipe(
@@ -169,24 +159,22 @@ export class AppComponent implements OnInit, OnDestroy {
169159
)
170160
.subscribe();
171161

172-
if (this.extensionLoginApprovalFeatureFlag) {
173-
// When the popup is already open and the active account transitions to Unlocked,
174-
// process any pending auth requests for the active user. The above subscription does not handle
175-
// this case.
176-
this.authService.activeAccountStatus$
177-
.pipe(
178-
startWith(null as unknown as AuthenticationStatus), // Seed previous value to handle initial emission
179-
pairwise(), // Compare previous and current statuses
180-
filter(
181-
([prev, curr]) =>
182-
prev !== AuthenticationStatus.Unlocked && curr === AuthenticationStatus.Unlocked, // Fire on transitions into Unlocked (incl. initial)
183-
),
184-
takeUntil(this.destroy$),
185-
)
186-
.subscribe(() => {
187-
void this.authRequestAnsweringService.processPendingAuthRequests();
188-
});
189-
}
162+
// When the popup is already open and the active account transitions to Unlocked,
163+
// process any pending auth requests for the active user. The above subscription does not handle
164+
// this case.
165+
this.authService.activeAccountStatus$
166+
.pipe(
167+
startWith(null as unknown as AuthenticationStatus), // Seed previous value to handle initial emission
168+
pairwise(), // Compare previous and current statuses
169+
filter(
170+
([prev, curr]) =>
171+
prev !== AuthenticationStatus.Unlocked && curr === AuthenticationStatus.Unlocked, // Fire on transitions into Unlocked (incl. initial)
172+
),
173+
takeUntil(this.destroy$),
174+
)
175+
.subscribe(() => {
176+
void this.authRequestAnsweringService.processPendingAuthRequests();
177+
});
190178

191179
this.ngZone.runOutsideAngular(() => {
192180
window.onmousedown = () => this.recordActivity();
@@ -241,10 +229,7 @@ export class AppComponent implements OnInit, OnDestroy {
241229
}
242230

243231
await this.router.navigate(["lock"]);
244-
} else if (
245-
msg.command === "openLoginApproval" &&
246-
this.extensionLoginApprovalFeatureFlag
247-
) {
232+
} else if (msg.command === "openLoginApproval") {
248233
if (this.processingPendingAuth) {
249234
return;
250235
}

apps/desktop/src/vault/app/vault/vault-v2.component.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import { Account, AccountService } from "@bitwarden/common/auth/abstractions/acc
2525
import { getUserId } from "@bitwarden/common/auth/services/account.service";
2626
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
2727
import { EventType } from "@bitwarden/common/enums";
28-
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
2928
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
3029
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
3130
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -319,26 +318,13 @@ export class VaultV2Component<C extends CipherViewLike>
319318
this.searchBarService.setEnabled(true);
320319
this.searchBarService.setPlaceholderText(this.i18nService.t("searchVault"));
321320

322-
if (
323-
(await firstValueFrom(
324-
this.configService.getFeatureFlag$(FeatureFlag.PM14938_BrowserExtensionLoginApproval),
325-
)) === true
326-
) {
327-
const authRequests = await firstValueFrom(
328-
this.authRequestService.getLatestPendingAuthRequest$(),
329-
);
330-
if (authRequests != null) {
331-
this.messagingService.send("openLoginApproval", {
332-
notificationId: authRequests.id,
333-
});
334-
}
335-
} else {
336-
const authRequest = await this.apiService.getLastAuthRequest();
337-
if (authRequest != null) {
338-
this.messagingService.send("openLoginApproval", {
339-
notificationId: authRequest.id,
340-
});
341-
}
321+
const authRequests = await firstValueFrom(
322+
this.authRequestService.getLatestPendingAuthRequest$(),
323+
);
324+
if (authRequests != null) {
325+
this.messagingService.send("openLoginApproval", {
326+
notificationId: authRequests.id,
327+
});
342328
}
343329

344330
this.activeUserId = await firstValueFrom(

apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { TestBed } from "@angular/core/testing";
2-
import { mock, MockProxy } from "jest-mock-extended";
3-
import { BehaviorSubject, firstValueFrom, of, take, timeout } from "rxjs";
2+
import { BehaviorSubject, firstValueFrom, take, timeout } from "rxjs";
43

54
import {
65
AuthRequestServiceAbstraction,
@@ -13,7 +12,6 @@ import { DeviceView } from "@bitwarden/common/auth/abstractions/devices/views/de
1312
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
1413
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
1514
import { DeviceType } from "@bitwarden/common/enums";
16-
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
1715
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
1816
import { Utils } from "@bitwarden/common/platform/misc/utils";
1917
import { StateProvider } from "@bitwarden/common/platform/state";
@@ -45,14 +43,11 @@ describe("VaultBannersService", () => {
4543
});
4644
const devices$ = new BehaviorSubject<DeviceView[]>([]);
4745
const pendingAuthRequests$ = new BehaviorSubject<Array<AuthRequestResponse>>([]);
48-
let configService: MockProxy<ConfigService>;
4946

5047
beforeEach(() => {
5148
lastSync$.next(new Date("2024-05-14"));
5249
isSelfHost.mockClear();
5350
getEmailVerified.mockClear().mockResolvedValue(true);
54-
configService = mock<ConfigService>();
55-
configService.getFeatureFlag$.mockImplementation(() => of(true));
5651

5752
TestBed.configureTestingModule({
5853
providers: [
@@ -99,10 +94,6 @@ describe("VaultBannersService", () => {
9994
provide: AuthRequestServiceAbstraction,
10095
useValue: { getPendingAuthRequests$: () => pendingAuthRequests$ },
10196
},
102-
{
103-
provide: ConfigService,
104-
useValue: configService,
105-
},
10697
],
10798
});
10899
});

apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ import {
66
UserDecryptionOptionsServiceAbstraction,
77
} from "@bitwarden/auth/common";
88
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
9-
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
109
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
11-
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
12-
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
1310
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
1411
import {
1512
StateProvider,
@@ -70,34 +67,20 @@ export class VaultBannersService {
7067
private kdfConfigService: KdfConfigService,
7168
private syncService: SyncService,
7269
private userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
73-
private devicesService: DevicesServiceAbstraction,
7470
private authRequestService: AuthRequestServiceAbstraction,
75-
private configService: ConfigService,
7671
) {}
7772

7873
/** Returns true when the pending auth request banner should be shown */
7974
async shouldShowPendingAuthRequestBanner(userId: UserId): Promise<boolean> {
8075
const alreadyDismissed = (await this.getBannerDismissedState(userId)).includes(
8176
VisibleVaultBanner.PendingAuthRequest,
8277
);
83-
// TODO: PM-20439 remove feature flag
84-
const browserLoginApprovalFeatureFlag = await firstValueFrom(
85-
this.configService.getFeatureFlag$(FeatureFlag.PM14938_BrowserExtensionLoginApproval),
86-
);
87-
if (browserLoginApprovalFeatureFlag === true) {
88-
const pendingAuthRequests = await firstValueFrom(
89-
this.authRequestService.getPendingAuthRequests$(),
90-
);
9178

92-
return pendingAuthRequests.length > 0 && !alreadyDismissed;
93-
} else {
94-
const devices = await firstValueFrom(this.devicesService.getDevices$());
95-
const hasPendingRequest = devices.some(
96-
(device) => device.response?.devicePendingAuthRequest != null,
97-
);
79+
const pendingAuthRequests = await firstValueFrom(
80+
this.authRequestService.getPendingAuthRequests$(),
81+
);
9882

99-
return hasPendingRequest && !alreadyDismissed;
100-
}
83+
return pendingAuthRequests.length > 0 && !alreadyDismissed;
10184
}
10285

10386
shouldShowPremiumBanner$(userId: UserId): Observable<boolean> {

libs/common/src/enums/feature-flag.enum.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export enum FeatureFlag {
1515
CollectionVaultRefactor = "pm-25030-resolve-ts-upgrade-errors",
1616

1717
/* Auth */
18-
PM14938_BrowserExtensionLoginApproval = "pm-14938-browser-extension-login-approvals",
1918
PM22110_DisableAlternateLoginMethods = "pm-22110-disable-alternate-login-methods",
2019

2120
/* Autofill */
@@ -98,7 +97,6 @@ export const DefaultFeatureFlagValue = {
9897
[FeatureFlag.PM22136_SdkCipherEncryption]: FALSE,
9998

10099
/* Auth */
101-
[FeatureFlag.PM14938_BrowserExtensionLoginApproval]: FALSE,
102100
[FeatureFlag.PM22110_DisableAlternateLoginMethods]: FALSE,
103101

104102
/* Billing */

libs/common/src/platform/server-notifications/internal/default-server-notifications.multiuser.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ describe("DefaultServerNotificationsService (multi-user)", () => {
132132
const flagValueByFlag: Partial<Record<FeatureFlag, boolean>> = {
133133
[FeatureFlag.InactiveUserServerNotification]: true,
134134
[FeatureFlag.PushNotificationsWhenLocked]: true,
135-
[FeatureFlag.PM14938_BrowserExtensionLoginApproval]: true,
136135
};
137136
return new BehaviorSubject(flagValueByFlag[flag] ?? false) as any;
138137
});

0 commit comments

Comments
 (0)