1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 16:53:34 +00:00

Merge branch 'master' into PM-2135-beeep-refactor-and-refresh-web-user-verification-components

This commit is contained in:
Andreas Coroiu
2023-05-26 10:26:20 +02:00
422 changed files with 14868 additions and 6143 deletions

View File

@@ -0,0 +1,87 @@
<label class="environment-selector-btn">
{{ "region" | i18n }}:
<a
(click)="toggle(null)"
cdkOverlayOrigin
#trigger="cdkOverlayOrigin"
aria-haspopup="menu"
aria-controls="cdk-overlay-container"
[ngSwitch]="selectedEnvironment"
>
<label *ngSwitchCase="ServerEnvironmentType.US" class="text-primary">{{ "us" | i18n }}</label>
<label *ngSwitchCase="ServerEnvironmentType.EU" class="text-primary">{{ "eu" | i18n }}</label>
<label *ngSwitchCase="ServerEnvironmentType.SelfHosted" class="text-primary">{{
"selfHosted" | i18n
}}</label>
<i class="bwi bwi-fw bwi-sm bwi-angle-down" aria-hidden="true"></i>
</a>
</label>
<ng-template
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="trigger"
(backdropClick)="close()"
(detach)="close()"
[cdkConnectedOverlayOpen]="isOpen"
[cdkConnectedOverlayPositions]="overlayPostition"
>
<div class="box-content">
<div class="environment-selector-dialog" [@transformPanel]="'open'" role="dialog">
<button
type="button"
class="environment-selector-dialog-item"
(click)="toggle(ServerEnvironmentType.US)"
>
<i
class="bwi bwi-fw bwi-sm bwi-check"
style="padding-bottom: 1px"
aria-hidden="true"
[style.visibility]="
selectedEnvironment === ServerEnvironmentType.US ? 'visible' : 'hidden'
"
></i>
<img class="img-us" alt="" />
<span>{{ "us" | i18n }}</span>
</button>
<br />
<button
type="button"
class="environment-selector-dialog-item"
(click)="toggle(ServerEnvironmentType.EU)"
*ngIf="euServerFlagEnabled"
>
<i
class="bwi bwi-fw bwi-sm bwi-check"
style="padding-bottom: 1px"
aria-hidden="true"
[style.visibility]="
selectedEnvironment === ServerEnvironmentType.EU ? 'visible' : 'hidden'
"
></i>
<img class="img-eu" alt="" />
<span>{{ "eu" | i18n }}</span>
</button>
<br *ngIf="euServerFlagEnabled" />
<button
type="button"
class="environment-selector-dialog-item"
(click)="toggle(ServerEnvironmentType.SelfHosted)"
>
<i
class="bwi bwi-fw bwi-sm bwi-check"
style="padding-bottom: 1px"
aria-hidden="true"
[style.visibility]="
selectedEnvironment === ServerEnvironmentType.SelfHosted ? 'visible' : 'hidden'
"
></i>
<i
class="bwi bwi-fw bwi-sm bwi-pencil-square"
style="padding-bottom: 1px"
aria-hidden="true"
></i>
<span>{{ "selfHosted" | i18n }}</span>
</button>
</div>
</div>
</ng-template>

View File

@@ -0,0 +1,109 @@
import { animate, state, style, transition, trigger } from "@angular/animations";
import { ConnectedPosition } from "@angular/cdk/overlay";
import { Component, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Subject, takeUntil } from "rxjs";
import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction";
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
@Component({
selector: "environment-selector",
templateUrl: "environment-selector.component.html",
animations: [
trigger("transformPanel", [
state(
"void",
style({
opacity: 0,
})
),
transition(
"void => open",
animate(
"100ms linear",
style({
opacity: 1,
})
)
),
transition("* => void", animate("100ms linear", style({ opacity: 0 }))),
]),
],
})
export class EnvironmentSelectorComponent implements OnInit, OnDestroy {
@Output() onOpenSelfHostedSettings = new EventEmitter();
euServerFlagEnabled: boolean;
isOpen = false;
showingModal = false;
selectedEnvironment: ServerEnvironment;
ServerEnvironmentType = ServerEnvironment;
overlayPostition: ConnectedPosition[] = [
{
originX: "start",
originY: "bottom",
overlayX: "start",
overlayY: "top",
},
];
protected componentDestroyed$: Subject<void> = new Subject();
constructor(
protected environmentService: EnvironmentService,
protected configService: ConfigServiceAbstraction,
protected router: Router
) {}
async ngOnInit() {
this.configService.serverConfig$.pipe(takeUntil(this.componentDestroyed$)).subscribe(() => {
this.updateEnvironmentInfo();
});
this.updateEnvironmentInfo();
}
ngOnDestroy(): void {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}
async toggle(option: ServerEnvironment) {
this.isOpen = !this.isOpen;
if (option === null) {
return;
}
if (option === ServerEnvironment.EU) {
await this.environmentService.setUrls({ base: "https://vault.bitwarden.eu" });
} else if (option === ServerEnvironment.US) {
await this.environmentService.setUrls({ base: "https://vault.bitwarden.com" });
} else if (option === ServerEnvironment.SelfHosted) {
this.onOpenSelfHostedSettings.emit();
}
this.updateEnvironmentInfo();
}
async updateEnvironmentInfo() {
this.euServerFlagEnabled = await this.configService.getFeatureFlagBool(
FeatureFlag.DisplayEuEnvironmentFlag
);
const webvaultUrl = this.environmentService.getWebVaultUrl();
if (this.environmentService.isSelfHosted()) {
this.selectedEnvironment = ServerEnvironment.SelfHosted;
} else if (webvaultUrl != null && webvaultUrl.includes("bitwarden.eu")) {
this.selectedEnvironment = ServerEnvironment.EU;
} else {
this.selectedEnvironment = ServerEnvironment.US;
}
}
close() {
this.isOpen = false;
this.updateEnvironmentInfo();
}
}
enum ServerEnvironment {
US = "US",
EU = "EU",
SelfHosted = "Self-hosted",
}

View File

@@ -3,9 +3,9 @@ import { FormBuilder, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { take } from "rxjs/operators";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AppIdService } from "@bitwarden/common/abstractions/appId.service";
import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/abstractions/devices/devices-api.service.abstraction";
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
import {
AllValidationErrors,
@@ -55,7 +55,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
}
constructor(
protected apiService: ApiService,
protected devicesApiService: DevicesApiServiceAbstraction,
protected appIdService: AppIdService,
protected authService: AuthService,
protected router: Router,
@@ -295,7 +295,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
async getLoginWithDevice(email: string) {
try {
const deviceIdentifier = await this.appIdService.getAppId();
const res = await this.apiService.getKnownDevice(email, deviceIdentifier);
const res = await this.devicesApiService.getKnownDevice(email, deviceIdentifier);
//ensure the application is not self-hosted
this.showLoginWithDevice = res && !this.selfHosted;
} catch (e) {

View File

@@ -202,7 +202,9 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
}
if (this.onSuccessfulLogin != null) {
this.loginService.clearValues();
await this.onSuccessfulLogin();
// Note: awaiting this will currently cause a hang on desktop & browser as they will wait for a full sync to complete
// before nagivating to the success route.
this.onSuccessfulLogin();
}
if (response.resetMasterPassword) {
this.successRoute = "set-password";