mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[PM-1019] Environment selection clients (#5480)
* [PM-169][PM-142][PM-191] Add Environments to Web and Desktop (#5294) * [PM-1351] Add property to server-config.response. Change config to be able to fetch without being authed. * [PM-1351] fetch every hour. * [PM-1351] fetch on vault sync. * [PM-1351] browser desktop fetch configs on sync complete. * [PM-1351] Add methods to retrieve feature flags * [PM-1351] Add enum to use as key to get values feature flag values * [PM-1351] Remove debug code * [PM-1351] Get flags when unauthed. Add enums as params. Hourly always fetch. * [PM-1351] add check for authed user using auth service * [PM-169] Web: add drop down to select environment * [PM-169] Fix pop up menu margins. Add DisplayEuEnvironmentFlag. * [PM-169] Change menu name. * [PM-169] Add environment selector ts and html. Add declaration and import on login.module * [PM-169] Add environment selector to desktop. * [PM-169] Ignore lint error. * [PM-169] add takeUntil to subscribes * [PM-191] PR Fixes, code format * [PM-168] Add Environments to extension login/registration (#5434)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { EnvironmentComponent as BaseEnvironmentComponent } from "@bitwarden/angular/components/environment.component";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
@@ -13,8 +14,9 @@ export class EnvironmentComponent extends BaseEnvironmentComponent {
|
||||
constructor(
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
environmentService: EnvironmentService,
|
||||
i18nService: I18nService
|
||||
i18nService: I18nService,
|
||||
modalService: ModalService
|
||||
) {
|
||||
super(platformUtilsService, environmentService, i18nService);
|
||||
super(platformUtilsService, environmentService, i18nService, modalService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,4 @@
|
||||
<div id="login-page">
|
||||
<div class="login-header">
|
||||
<button
|
||||
type="button"
|
||||
appStopClick
|
||||
(click)="settings()"
|
||||
class="environment-urls-settings-icon"
|
||||
attr.aria-label="{{ 'settings' | i18n }}"
|
||||
>
|
||||
<i class="bwi bwi-cog bwi-lg" aria-hidden="true"></i>
|
||||
{{ "settings" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
<div id="login-page" class="page-top-padding">
|
||||
<form
|
||||
id="login-page"
|
||||
#form
|
||||
@@ -19,7 +7,7 @@
|
||||
[formGroup]="formGroup"
|
||||
attr.aria-hidden="{{ showingModal }}"
|
||||
>
|
||||
<div id="content" class="content">
|
||||
<div id="content" class="content" style="padding-top: 50px">
|
||||
<img class="logo-image" alt="Bitwarden" />
|
||||
<p class="lead">{{ "loginOrCreateNewAccount" | i18n }}</p>
|
||||
<!-- start email -->
|
||||
@@ -37,9 +25,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer" *ngIf="selfHostedDomain">
|
||||
{{ "loggingInTo" | i18n : selfHostedDomain }}
|
||||
</div>
|
||||
<environment-selector></environment-selector>
|
||||
</div>
|
||||
<div class="checkbox remember-email">
|
||||
<label for="rememberEmail">
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Component, NgZone, OnDestroy, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
|
||||
import { LoginComponent as BaseLoginComponent } from "@bitwarden/angular/auth/components/login.component";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -31,7 +33,10 @@ const BroadcasterSubscriptionId = "LoginComponent";
|
||||
export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
||||
@ViewChild("environment", { read: ViewContainerRef, static: true })
|
||||
environmentModal: ViewContainerRef;
|
||||
@ViewChild(EnvironmentSelectorComponent)
|
||||
environmentSelector!: EnvironmentSelectorComponent;
|
||||
|
||||
protected componentDestroyed$: Subject<void> = new Subject();
|
||||
webVaultHostname = "";
|
||||
|
||||
showingModal = false;
|
||||
@@ -116,10 +121,17 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
||||
});
|
||||
});
|
||||
this.messagingService.send("getWindowIsFocused");
|
||||
this.environmentSelector.onOpenSelfHostedSettings
|
||||
.pipe(takeUntil(this.componentDestroyed$))
|
||||
.subscribe(() => {
|
||||
this.settings();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
||||
this.componentDestroyed$.next();
|
||||
this.componentDestroyed$.complete();
|
||||
}
|
||||
|
||||
async settings() {
|
||||
@@ -128,17 +140,16 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
||||
this.environmentModal
|
||||
);
|
||||
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
modal.onShown.subscribe(() => {
|
||||
modal.onShown.pipe(takeUntil(this.componentDestroyed$)).subscribe(() => {
|
||||
this.showingModal = true;
|
||||
});
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
modal.onClosed.subscribe(() => {
|
||||
|
||||
modal.onClosed.pipe(takeUntil(this.componentDestroyed$)).subscribe(() => {
|
||||
this.showingModal = false;
|
||||
});
|
||||
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
|
||||
childComponent.onSaved.subscribe(async () => {
|
||||
// eslint-disable-next-line rxjs/no-async-subscribe
|
||||
childComponent.onSaved.pipe(takeUntil(this.componentDestroyed$)).subscribe(async () => {
|
||||
modal.close();
|
||||
await this.checkSelfHosted();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
|
||||
import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
|
||||
|
||||
import { SharedModule } from "../../app/shared/shared.module";
|
||||
|
||||
import { LoginWithDeviceComponent } from "./login-with-device.component";
|
||||
@@ -8,7 +10,7 @@ import { LoginComponent } from "./login.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [SharedModule, RouterModule],
|
||||
declarations: [LoginComponent, LoginWithDeviceComponent],
|
||||
declarations: [LoginComponent, LoginWithDeviceComponent, EnvironmentSelectorComponent],
|
||||
exports: [LoginComponent, LoginWithDeviceComponent],
|
||||
})
|
||||
export class LoginModule {}
|
||||
|
||||
BIN
apps/desktop/src/images/eu-flag.png
Normal file
BIN
apps/desktop/src/images/eu-flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
BIN
apps/desktop/src/images/us-flag.png
Normal file
BIN
apps/desktop/src/images/us-flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -2251,5 +2251,19 @@
|
||||
},
|
||||
"windowsBiometricUpdateWarningTitle": {
|
||||
"message": "Recommended Settings Update"
|
||||
},
|
||||
"region": {
|
||||
"message": "Region"
|
||||
},
|
||||
"eu": {
|
||||
"message": "EU",
|
||||
"description": "European Union"
|
||||
},
|
||||
"us": {
|
||||
"message": "US",
|
||||
"description": "United States"
|
||||
},
|
||||
"selfHosted": {
|
||||
"message": "Self-hosted"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,3 +38,63 @@
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.environment-selector-btn {
|
||||
font-size: $font-size-small;
|
||||
color: $text-muted;
|
||||
line-height: 25px;
|
||||
font-weight: 400;
|
||||
padding-left: 5px;
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a,
|
||||
a label:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.environment-selector-dialog {
|
||||
@include themify($themes) {
|
||||
background-color: themed("boxBackgroundColor");
|
||||
}
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12),
|
||||
0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.environment-selector-dialog-item {
|
||||
@include themify($themes) {
|
||||
color: themed("textColor") !important;
|
||||
}
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 0px 15px 0px 5px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid transparent;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
@include themify($themes) {
|
||||
background-color: themed("listItemBackgroundHoverColor") !important;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
margin-bottom: -2px;
|
||||
width: 22px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.img-us {
|
||||
content: url("../images/us-flag.png");
|
||||
}
|
||||
|
||||
.img-eu {
|
||||
content: url("../images/eu-flag.png");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,6 +421,10 @@ app-root > #loading,
|
||||
}
|
||||
}
|
||||
|
||||
.page-top-padding {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
@include themify($themes) {
|
||||
content: url("../images/logo-" + themed("logoSuffix") + "@2x.png");
|
||||
|
||||
Reference in New Issue
Block a user