PM-14424 - LoginComponents should listen for unauthUiRefresh flag changes and forcibly change the UI on browser & desktop to make for a seamless experience without having to refresh. (#11830)
This commit is contained in:
parent
1e2a51a56b
commit
b5450227da
|
@ -1,10 +1,12 @@
|
||||||
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||||
import { FormBuilder, Validators } from "@angular/forms";
|
import { FormBuilder, Validators } from "@angular/forms";
|
||||||
import { Router } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { Subject, firstValueFrom, switchMap, takeUntil } from "rxjs";
|
import { Subject, firstValueFrom, switchMap, takeUntil, tap } from "rxjs";
|
||||||
|
|
||||||
import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
|
import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
|
||||||
import { LoginEmailServiceAbstraction, RegisterRouteService } from "@bitwarden/auth/common";
|
import { LoginEmailServiceAbstraction, RegisterRouteService } from "@bitwarden/auth/common";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { ToastService } from "@bitwarden/components";
|
import { ToastService } from "@bitwarden/components";
|
||||||
|
@ -38,9 +40,13 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||||
private accountSwitcherService: AccountSwitcherService,
|
private accountSwitcherService: AccountSwitcherService,
|
||||||
private registerRouteService: RegisterRouteService,
|
private registerRouteService: RegisterRouteService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
|
private configService: ConfigService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
this.listenForUnauthUiRefreshFlagChanges();
|
||||||
|
|
||||||
const email = await firstValueFrom(this.loginEmailService.loginEmail$);
|
const email = await firstValueFrom(this.loginEmailService.loginEmail$);
|
||||||
const rememberEmail = this.loginEmailService.getRememberEmail();
|
const rememberEmail = this.loginEmailService.getRememberEmail();
|
||||||
|
|
||||||
|
@ -70,6 +76,29 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||||
this.destroyed$.complete();
|
this.destroyed$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private listenForUnauthUiRefreshFlagChanges() {
|
||||||
|
this.configService
|
||||||
|
.getFeatureFlag$(FeatureFlag.UnauthenticatedExtensionUIRefresh)
|
||||||
|
.pipe(
|
||||||
|
tap(async (flag) => {
|
||||||
|
// If the flag is turned ON, we must force a reload to ensure the correct UI is shown
|
||||||
|
if (flag) {
|
||||||
|
const uniqueQueryParams = {
|
||||||
|
...this.route.queryParams,
|
||||||
|
// adding a unique timestamp to the query params to force a reload
|
||||||
|
t: new Date().getTime().toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.router.navigate(["/login"], {
|
||||||
|
queryParams: uniqueQueryParams,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
takeUntil(this.destroyed$),
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
get availableAccounts$() {
|
get availableAccounts$() {
|
||||||
return this.accountSwitcherService.availableAccounts$;
|
return this.accountSwitcherService.availableAccounts$;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Component, NgZone, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
import { Component, NgZone, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder } from "@angular/forms";
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { Subject, takeUntil } from "rxjs";
|
import { Subject, takeUntil, tap } from "rxjs";
|
||||||
|
|
||||||
import { LoginComponentV1 as BaseLoginComponent } from "@bitwarden/angular/auth/components/login-v1.component";
|
import { LoginComponentV1 as BaseLoginComponent } from "@bitwarden/angular/auth/components/login-v1.component";
|
||||||
import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstractions/form-validation-errors.service";
|
import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstractions/form-validation-errors.service";
|
||||||
|
@ -14,8 +14,10 @@ import {
|
||||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -76,6 +78,7 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||||
registerRouteService: RegisterRouteService,
|
registerRouteService: RegisterRouteService,
|
||||||
toastService: ToastService,
|
toastService: ToastService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
devicesApiService,
|
devicesApiService,
|
||||||
|
@ -105,6 +108,8 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
this.listenForUnauthUiRefreshFlagChanges();
|
||||||
|
|
||||||
await super.ngOnInit();
|
await super.ngOnInit();
|
||||||
await this.getLoginWithDevice(this.loggedEmail);
|
await this.getLoginWithDevice(this.loggedEmail);
|
||||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
||||||
|
@ -137,6 +142,29 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||||
this.componentDestroyed$.complete();
|
this.componentDestroyed$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private listenForUnauthUiRefreshFlagChanges() {
|
||||||
|
this.configService
|
||||||
|
.getFeatureFlag$(FeatureFlag.UnauthenticatedExtensionUIRefresh)
|
||||||
|
.pipe(
|
||||||
|
tap(async (flag) => {
|
||||||
|
// If the flag is turned ON, we must force a reload to ensure the correct UI is shown
|
||||||
|
if (flag) {
|
||||||
|
const uniqueQueryParams = {
|
||||||
|
...this.route.queryParams,
|
||||||
|
// adding a unique timestamp to the query params to force a reload
|
||||||
|
t: new Date().getTime().toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.router.navigate(["/"], {
|
||||||
|
queryParams: uniqueQueryParams,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
takeUntil(this.destroy$),
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
async settings() {
|
async settings() {
|
||||||
const [modal, childComponent] = await this.modalService.openViewRef(
|
const [modal, childComponent] = await this.modalService.openViewRef(
|
||||||
EnvironmentComponent,
|
EnvironmentComponent,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common";
|
||||||
import { Component, ElementRef, Input, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
import { Component, ElementRef, Input, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||||
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms";
|
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||||
import { ActivatedRoute, Router, RouterModule } from "@angular/router";
|
import { ActivatedRoute, Router, RouterModule } from "@angular/router";
|
||||||
import { firstValueFrom, Subject, take, takeUntil } from "rxjs";
|
import { firstValueFrom, Subject, take, takeUntil, tap } from "rxjs";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import {
|
import {
|
||||||
|
@ -19,9 +19,11 @@ import { CaptchaIFrame } from "@bitwarden/common/auth/captcha-iframe";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { ClientType, HttpStatusCode } from "@bitwarden/common/enums";
|
import { ClientType, HttpStatusCode } from "@bitwarden/common/enums";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -139,12 +141,16 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private validationService: ValidationService,
|
private validationService: ValidationService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
this.clientType = this.platformUtilsService.getClientType();
|
this.clientType = this.platformUtilsService.getClientType();
|
||||||
this.loginViaAuthRequestSupported = this.loginComponentService.isLoginViaAuthRequestSupported();
|
this.loginViaAuthRequestSupported = this.loginComponentService.isLoginViaAuthRequestSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
// TODO: remove this when the UnauthenticatedExtensionUIRefresh feature flag is removed.
|
||||||
|
this.listenForUnauthUiRefreshFlagChanges();
|
||||||
|
|
||||||
await this.defaultOnInit();
|
await this.defaultOnInit();
|
||||||
|
|
||||||
if (this.clientType === ClientType.Desktop) {
|
if (this.clientType === ClientType.Desktop) {
|
||||||
|
@ -162,6 +168,29 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private listenForUnauthUiRefreshFlagChanges() {
|
||||||
|
this.configService
|
||||||
|
.getFeatureFlag$(FeatureFlag.UnauthenticatedExtensionUIRefresh)
|
||||||
|
.pipe(
|
||||||
|
tap(async (flag) => {
|
||||||
|
// If the flag is turned OFF, we must force a reload to ensure the correct UI is shown
|
||||||
|
if (!flag) {
|
||||||
|
const uniqueQueryParams = {
|
||||||
|
...this.activatedRoute.queryParams,
|
||||||
|
// adding a unique timestamp to the query params to force a reload
|
||||||
|
t: new Date().getTime().toString(), // Adding a unique timestamp as a query parameter
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.router.navigate(["/"], {
|
||||||
|
queryParams: uniqueQueryParams,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
takeUntil(this.destroy$),
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
submit = async (): Promise<void> => {
|
submit = async (): Promise<void> => {
|
||||||
if (this.clientType === ClientType.Desktop) {
|
if (this.clientType === ClientType.Desktop) {
|
||||||
if (this.loginUiState !== LoginUiState.MASTER_PASSWORD_ENTRY) {
|
if (this.loginUiState !== LoginUiState.MASTER_PASSWORD_ENTRY) {
|
||||||
|
|
Loading…
Reference in New Issue