mirror of
https://github.com/bitwarden/web
synced 2025-12-06 00:03:28 +00:00
[End User Vault Refresh] Security sub-page (#1538)
* [End User Vault Refresh] Security section * Updated routing module * Update routing for change-password * Updated buttons of all modified classes // imported button module * Converted modified class to use bit-callout * removed comments * Update small button to current cl button
This commit is contained in:
@@ -58,9 +58,9 @@ import { EmergencyAccessComponent } from "./settings/emergency-access.component"
|
||||
import { OrganizationsComponent } from "./settings/organizations.component";
|
||||
import { PreferencesComponent } from "./settings/preferences.component";
|
||||
import { PremiumComponent } from "./settings/premium.component";
|
||||
import { SecurityComponent } from "./settings/security.component";
|
||||
import { SettingsComponent } from "./settings/settings.component";
|
||||
import { SponsoredFamiliesComponent } from "./settings/sponsored-families.component";
|
||||
import { TwoFactorSetupComponent } from "./settings/two-factor-setup.component";
|
||||
import { UserBillingComponent } from "./settings/user-billing.component";
|
||||
import { UserSubscriptionComponent } from "./settings/user-subscription.component";
|
||||
import { BreachReportComponent } from "./tools/breach-report.component";
|
||||
@@ -183,16 +183,15 @@ const routes: Routes = [
|
||||
component: PreferencesComponent,
|
||||
data: { titleId: "preferences" },
|
||||
},
|
||||
{
|
||||
path: "security",
|
||||
loadChildren: async () => (await import("./settings/security.module")).SecurityModule,
|
||||
},
|
||||
{
|
||||
path: "domain-rules",
|
||||
component: DomainRulesComponent,
|
||||
data: { titleId: "domainRules" },
|
||||
},
|
||||
{
|
||||
path: "two-factor",
|
||||
component: TwoFactorSetupComponent,
|
||||
data: { titleId: "twoStepLogin" },
|
||||
},
|
||||
{ path: "premium", component: PremiumComponent, data: { titleId: "goPremium" } },
|
||||
{ path: "billing", component: UserBillingComponent, data: { titleId: "billing" } },
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ import localeZhTw from "@angular/common/locales/zh-Hant";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { BadgeModule } from "@bitwarden/components";
|
||||
import { BadgeModule, ButtonModule, CalloutModule } from "@bitwarden/components";
|
||||
import { InfiniteScrollModule } from "ngx-infinite-scroll";
|
||||
import { ToastrModule } from "ngx-toastr";
|
||||
|
||||
@@ -191,6 +191,8 @@ import { PreferencesComponent } from "./settings/preferences.component";
|
||||
import { PremiumComponent } from "./settings/premium.component";
|
||||
import { ProfileComponent } from "./settings/profile.component";
|
||||
import { PurgeVaultComponent } from "./settings/purge-vault.component";
|
||||
import { SecurityKeysComponent } from "./settings/security-keys.component";
|
||||
import { SecurityComponent } from "./settings/security.component";
|
||||
import { SettingsComponent } from "./settings/settings.component";
|
||||
import { SponsoredFamiliesComponent } from "./settings/sponsored-families.component";
|
||||
import { SponsoringOrgRowComponent } from "./settings/sponsoring-org-row.component";
|
||||
@@ -296,6 +298,8 @@ registerLocaleData(localeZhTw, "zh-TW");
|
||||
ReactiveFormsModule,
|
||||
RouterModule,
|
||||
BadgeModule,
|
||||
ButtonModule,
|
||||
CalloutModule,
|
||||
],
|
||||
declarations: [
|
||||
A11yInvalidDirective,
|
||||
@@ -431,6 +435,8 @@ registerLocaleData(localeZhTw, "zh-TW");
|
||||
ReusedPasswordsReportComponent,
|
||||
SearchCiphersPipe,
|
||||
SearchPipe,
|
||||
SecurityComponent,
|
||||
SecurityKeysComponent,
|
||||
SelectCopyDirective,
|
||||
SendAddEditComponent,
|
||||
SendComponent,
|
||||
|
||||
@@ -8,43 +8,19 @@
|
||||
</div>
|
||||
<app-change-email></app-change-email>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="showChangePassword">
|
||||
<div class="secondary-header">
|
||||
<h1>{{ "changeMasterPassword" | i18n }}</h1>
|
||||
</div>
|
||||
<app-change-password></app-change-password>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="showChangeKdf">
|
||||
<div class="secondary-header">
|
||||
<h1>{{ "encKeySettings" | i18n }}</h1>
|
||||
</div>
|
||||
<app-change-kdf></app-change-kdf>
|
||||
</ng-container>
|
||||
<div class="secondary-header border-0 mb-0">
|
||||
<h1>{{ "apiKey" | i18n }}</h1>
|
||||
</div>
|
||||
<p>
|
||||
{{ "userApiKeyDesc" | i18n }}
|
||||
</p>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="viewUserApiKey()">
|
||||
{{ "viewApiKey" | i18n }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="rotateUserApiKey()">
|
||||
{{ "rotateApiKey" | i18n }}
|
||||
</button>
|
||||
<div class="secondary-header text-danger border-0 mb-0">
|
||||
<h1>{{ "dangerZone" | i18n }}</h1>
|
||||
</div>
|
||||
<div class="card border-danger">
|
||||
<div class="card-body">
|
||||
<p>{{ "dangerZoneDesc" | i18n }}</p>
|
||||
<button type="button" class="btn btn-outline-danger" (click)="deauthorizeSessions()">
|
||||
<button bit-button buttonType="danger" (click)="deauthorizeSessions()">
|
||||
{{ "deauthorizeSessions" | i18n }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger" (click)="purgeVault()">
|
||||
<button bit-button buttonType="danger" (click)="purgeVault()">
|
||||
{{ "purgeVault" | i18n }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger" (click)="deleteAccount()">
|
||||
<button bit-button buttonType="danger" (click)="deleteAccount()">
|
||||
{{ "deleteAccount" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,6 @@ import { ApiService } from "jslib-common/abstractions/api.service";
|
||||
import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
|
||||
import { StateService } from "jslib-common/abstractions/state.service";
|
||||
|
||||
import { ApiKeyComponent } from "./api-key.component";
|
||||
import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component";
|
||||
import { DeleteAccountComponent } from "./delete-account.component";
|
||||
import { PurgeVaultComponent } from "./purge-vault.component";
|
||||
@@ -21,13 +20,7 @@ export class AccountComponent {
|
||||
purgeModalRef: ViewContainerRef;
|
||||
@ViewChild("deleteAccountTemplate", { read: ViewContainerRef, static: true })
|
||||
deleteModalRef: ViewContainerRef;
|
||||
@ViewChild("viewUserApiKeyTemplate", { read: ViewContainerRef, static: true })
|
||||
viewUserApiKeyModalRef: ViewContainerRef;
|
||||
@ViewChild("rotateUserApiKeyTemplate", { read: ViewContainerRef, static: true })
|
||||
rotateUserApiKeyModalRef: ViewContainerRef;
|
||||
|
||||
showChangePassword = true;
|
||||
showChangeKdf = true;
|
||||
showChangeEmail = true;
|
||||
|
||||
constructor(
|
||||
@@ -38,10 +31,7 @@ export class AccountComponent {
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.showChangeEmail =
|
||||
this.showChangeKdf =
|
||||
this.showChangePassword =
|
||||
!(await this.keyConnectorService.getUsesKeyConnector());
|
||||
this.showChangeEmail = !(await this.keyConnectorService.getUsesKeyConnector());
|
||||
}
|
||||
|
||||
async deauthorizeSessions() {
|
||||
@@ -55,33 +45,4 @@ export class AccountComponent {
|
||||
async deleteAccount() {
|
||||
await this.modalService.openViewRef(DeleteAccountComponent, this.deleteModalRef);
|
||||
}
|
||||
|
||||
async viewUserApiKey() {
|
||||
const entityId = await this.stateService.getUserId();
|
||||
await this.modalService.openViewRef(ApiKeyComponent, this.viewUserApiKeyModalRef, (comp) => {
|
||||
comp.keyType = "user";
|
||||
comp.entityId = entityId;
|
||||
comp.postKey = this.apiService.postUserApiKey.bind(this.apiService);
|
||||
comp.scope = "api";
|
||||
comp.grantType = "client_credentials";
|
||||
comp.apiKeyTitle = "apiKey";
|
||||
comp.apiKeyWarning = "userApiKeyWarning";
|
||||
comp.apiKeyDescription = "userApiKeyDesc";
|
||||
});
|
||||
}
|
||||
|
||||
async rotateUserApiKey() {
|
||||
const entityId = await this.stateService.getUserId();
|
||||
await this.modalService.openViewRef(ApiKeyComponent, this.rotateUserApiKeyModalRef, (comp) => {
|
||||
comp.keyType = "user";
|
||||
comp.isRotation = true;
|
||||
comp.entityId = entityId;
|
||||
comp.postKey = this.apiService.postUserRotateApiKey.bind(this.apiService);
|
||||
comp.scope = "api";
|
||||
comp.grantType = "client_credentials";
|
||||
comp.apiKeyTitle = "apiKey";
|
||||
comp.apiKeyWarning = "userApiKeyWarning";
|
||||
comp.apiKeyDescription = "apiKeyRotateDesc";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<app-callout type="warning">{{ "loggedOutWarning" | i18n }}</app-callout>
|
||||
<div class="tabbed-header">
|
||||
<h1>{{ "encKeySettings" | i18n }}</h1>
|
||||
</div>
|
||||
<bit-callout type="warning">{{ "loggedOutWarning" | i18n }}</bit-callout>
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate autocomplete="off">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
@@ -68,7 +71,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
||||
<button bit-button buttonType="primary" class="btn-submit" [disabled]="form.loading">
|
||||
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
|
||||
<span>{{ "changeKdf" | i18n }}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
<app-callout type="warning">{{ "loggedOutWarning" | i18n }}</app-callout>
|
||||
<div class="tabbed-header">
|
||||
<h1>{{ "changeMasterPassword" | i18n }}</h1>
|
||||
</div>
|
||||
|
||||
<bit-callout type="warning">{{ "loggedOutWarning" | i18n }}</bit-callout>
|
||||
<app-callout
|
||||
type="info"
|
||||
[enforcedPolicyOptions]="enforcedPolicyOptions"
|
||||
@@ -83,7 +87,7 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
||||
<button bit-button buttonType="primary" class="btn-submit" [disabled]="form.loading">
|
||||
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
|
||||
<span>{{ "changeMasterPassword" | i18n }}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ChangePasswordComponent as BaseChangePasswordComponent } from "jslib-angular/components/change-password.component";
|
||||
import { ApiService } from "jslib-common/abstractions/api.service";
|
||||
@@ -6,6 +7,7 @@ import { CipherService } from "jslib-common/abstractions/cipher.service";
|
||||
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
||||
import { FolderService } from "jslib-common/abstractions/folder.service";
|
||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||
import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
|
||||
import { MessagingService } from "jslib-common/abstractions/messaging.service";
|
||||
import { OrganizationService } from "jslib-common/abstractions/organization.service";
|
||||
import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
|
||||
@@ -47,7 +49,9 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
||||
private syncService: SyncService,
|
||||
private apiService: ApiService,
|
||||
private sendService: SendService,
|
||||
private organizationService: OrganizationService
|
||||
private organizationService: OrganizationService,
|
||||
private keyConnectorService: KeyConnectorService,
|
||||
private router: Router
|
||||
) {
|
||||
super(
|
||||
i18nService,
|
||||
@@ -60,6 +64,12 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
||||
);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
if (await this.keyConnectorService.getUsesKeyConnector()) {
|
||||
this.router.navigate(["/settings/security/two-factor"]);
|
||||
}
|
||||
}
|
||||
|
||||
async rotateEncKeyClicked() {
|
||||
if (this.rotateEncKey) {
|
||||
const ciphers = await this.cipherService.getAllDecrypted();
|
||||
|
||||
18
src/app/settings/security-keys.component.html
Normal file
18
src/app/settings/security-keys.component.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<app-change-kdf *ngIf="showChangeKdf"></app-change-kdf>
|
||||
<div
|
||||
[ngClass]="{ 'tabbed-header': !showChangeKdf, 'secondary-header': showChangeKdf }"
|
||||
class="border-0 mb-0"
|
||||
>
|
||||
<h1>{{ "apiKey" | i18n }}</h1>
|
||||
</div>
|
||||
<p>
|
||||
{{ "userApiKeyDesc" | i18n }}
|
||||
</p>
|
||||
<button bit-button buttonType="secondary" (click)="viewUserApiKey()">
|
||||
{{ "viewApiKey" | i18n }}
|
||||
</button>
|
||||
<button bit-button buttonType="secondary" (click)="rotateUserApiKey()">
|
||||
{{ "rotateApiKey" | i18n }}
|
||||
</button>
|
||||
<ng-template #viewUserApiKeyTemplate></ng-template>
|
||||
<ng-template #rotateUserApiKeyTemplate></ng-template>
|
||||
61
src/app/settings/security-keys.component.ts
Normal file
61
src/app/settings/security-keys.component.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
|
||||
import { ModalService } from "jslib-angular/services/modal.service";
|
||||
import { ApiService } from "jslib-common/abstractions/api.service";
|
||||
import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
|
||||
import { StateService } from "jslib-common/abstractions/state.service";
|
||||
|
||||
import { ApiKeyComponent } from "./api-key.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-security-keys",
|
||||
templateUrl: "security-keys.component.html",
|
||||
})
|
||||
export class SecurityKeysComponent implements OnInit {
|
||||
@ViewChild("viewUserApiKeyTemplate", { read: ViewContainerRef, static: true })
|
||||
viewUserApiKeyModalRef: ViewContainerRef;
|
||||
@ViewChild("rotateUserApiKeyTemplate", { read: ViewContainerRef, static: true })
|
||||
rotateUserApiKeyModalRef: ViewContainerRef;
|
||||
|
||||
showChangeKdf = true;
|
||||
|
||||
constructor(
|
||||
private keyConnectorService: KeyConnectorService,
|
||||
private stateService: StateService,
|
||||
private modalService: ModalService,
|
||||
private apiService: ApiService
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.showChangeKdf = !(await this.keyConnectorService.getUsesKeyConnector());
|
||||
}
|
||||
|
||||
async viewUserApiKey() {
|
||||
const entityId = await this.stateService.getUserId();
|
||||
await this.modalService.openViewRef(ApiKeyComponent, this.viewUserApiKeyModalRef, (comp) => {
|
||||
comp.keyType = "user";
|
||||
comp.entityId = entityId;
|
||||
comp.postKey = this.apiService.postUserApiKey.bind(this.apiService);
|
||||
comp.scope = "api";
|
||||
comp.grantType = "client_credentials";
|
||||
comp.apiKeyTitle = "apiKey";
|
||||
comp.apiKeyWarning = "userApiKeyWarning";
|
||||
comp.apiKeyDescription = "userApiKeyDesc";
|
||||
});
|
||||
}
|
||||
|
||||
async rotateUserApiKey() {
|
||||
const entityId = await this.stateService.getUserId();
|
||||
await this.modalService.openViewRef(ApiKeyComponent, this.rotateUserApiKeyModalRef, (comp) => {
|
||||
comp.keyType = "user";
|
||||
comp.isRotation = true;
|
||||
comp.entityId = entityId;
|
||||
comp.postKey = this.apiService.postUserRotateApiKey.bind(this.apiService);
|
||||
comp.scope = "api";
|
||||
comp.grantType = "client_credentials";
|
||||
comp.apiKeyTitle = "apiKey";
|
||||
comp.apiKeyWarning = "userApiKeyWarning";
|
||||
comp.apiKeyDescription = "apiKeyRotateDesc";
|
||||
});
|
||||
}
|
||||
}
|
||||
22
src/app/settings/security.component.html
Normal file
22
src/app/settings/security.component.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="tabbed-nav d-flex flex-column">
|
||||
<ul class="nav nav-tabs">
|
||||
<ng-container *ngIf="showChangePassword">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="change-password" routerLinkActive="active">
|
||||
{{ "masterPassword" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
</ng-container>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="two-factor" routerLinkActive="active">
|
||||
{{ "twoStepLogin" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="security-keys" routerLinkActive="active">
|
||||
{{ "keys" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<router-outlet></router-outlet>
|
||||
17
src/app/settings/security.component.ts
Normal file
17
src/app/settings/security.component.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-security",
|
||||
templateUrl: "security.component.html",
|
||||
})
|
||||
export class SecurityComponent {
|
||||
showChangePassword = true;
|
||||
|
||||
constructor(private keyConnectorService: KeyConnectorService) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.showChangePassword = !(await this.keyConnectorService.getUsesKeyConnector());
|
||||
}
|
||||
}
|
||||
39
src/app/settings/security.module.ts
Normal file
39
src/app/settings/security.module.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
|
||||
import { ChangePasswordComponent } from "./change-password.component";
|
||||
import { SecurityKeysComponent } from "./security-keys.component";
|
||||
import { SecurityComponent } from "./security.component";
|
||||
import { TwoFactorSetupComponent } from "./two-factor-setup.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: "",
|
||||
component: SecurityComponent,
|
||||
data: { titleId: "security" },
|
||||
children: [
|
||||
{ path: "", pathMatch: "full", redirectTo: "change-password" },
|
||||
{
|
||||
path: "change-password",
|
||||
component: ChangePasswordComponent,
|
||||
data: { titleId: "masterPassword" },
|
||||
},
|
||||
{
|
||||
path: "two-factor",
|
||||
component: TwoFactorSetupComponent,
|
||||
data: { titleId: "twoStepLogin" },
|
||||
},
|
||||
{
|
||||
path: "security-keys",
|
||||
component: SecurityKeysComponent,
|
||||
data: { titleId: "keys" },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class SecurityModule {}
|
||||
@@ -7,6 +7,9 @@
|
||||
<a routerLink="account" class="list-group-item" routerLinkActive="active">
|
||||
{{ "myAccount" | i18n }}
|
||||
</a>
|
||||
<a routerLink="security" class="list-group-item" routerLinkActive="active">
|
||||
{{ "security" | i18n }}
|
||||
</a>
|
||||
<a routerLink="preferences" class="list-group-item" routerLinkActive="active">
|
||||
{{ "preferences" | i18n }}
|
||||
</a>
|
||||
@@ -37,9 +40,6 @@
|
||||
>
|
||||
{{ "billing" | i18n }}
|
||||
</a>
|
||||
<a routerLink="two-factor" class="list-group-item" routerLinkActive="active">
|
||||
{{ "twoStepLogin" | i18n }}
|
||||
</a>
|
||||
<a routerLink="domain-rules" class="list-group-item" routerLinkActive="active">
|
||||
{{ "domainRules" | i18n }}
|
||||
</a>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<div class="page-header">
|
||||
<div class="tabbed-header">
|
||||
<h1>{{ "twoStepLogin" | i18n }}</h1>
|
||||
</div>
|
||||
<p *ngIf="!organizationId">{{ "twoStepLoginDesc" | i18n }}</p>
|
||||
<p *ngIf="organizationId">{{ "twoStepLoginOrganizationDesc" | i18n }}</p>
|
||||
<app-callout type="warning" *ngIf="!organizationId">
|
||||
<bit-callout type="warning" *ngIf="!organizationId">
|
||||
<p>{{ "twoStepLoginRecoveryWarning" | i18n }}</p>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="recoveryCode()">
|
||||
<button bit-button buttonType="secondary" (click)="recoveryCode()">
|
||||
{{ "viewRecoveryCode" | i18n }}
|
||||
</button>
|
||||
</app-callout>
|
||||
</bit-callout>
|
||||
<h2 [ngClass]="{ 'mt-5': !organizationId }">
|
||||
{{ "providers" | i18n }}
|
||||
<small *ngIf="loading">
|
||||
@@ -20,9 +20,9 @@
|
||||
<span class="sr-only">{{ "loading" | i18n }}</span>
|
||||
</small>
|
||||
</h2>
|
||||
<app-callout type="warning" *ngIf="showPolicyWarning">
|
||||
<bit-callout type="warning" *ngIf="showPolicyWarning">
|
||||
{{ "twoStepLoginPolicyUserWarning" | i18n }}
|
||||
</app-callout>
|
||||
</bit-callout>
|
||||
<ul class="list-group list-group-2fa">
|
||||
<li *ngFor="let p of providers" class="list-group-item d-flex align-items-center">
|
||||
<div class="logo-2fa d-flex justify-content-center">
|
||||
@@ -45,8 +45,8 @@
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm"
|
||||
bit-button
|
||||
buttonType="secondary"
|
||||
[disabled]="!canAccessPremium && p.premium"
|
||||
(click)="manage(p.type)"
|
||||
>
|
||||
|
||||
@@ -4829,5 +4829,14 @@
|
||||
"example": "My Org Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
"masterPassword": {
|
||||
"message": "Master Password"
|
||||
},
|
||||
"security": {
|
||||
"message": "Security"
|
||||
},
|
||||
"keys": {
|
||||
"message": "Keys"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ body {
|
||||
}
|
||||
|
||||
.page-header,
|
||||
.secondary-header {
|
||||
.secondary-header,
|
||||
.tabbed-header {
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.6rem;
|
||||
@include themify($themes) {
|
||||
@@ -64,6 +65,11 @@ body {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.tabbed-header {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
img.logo {
|
||||
display: block;
|
||||
height: 43px;
|
||||
|
||||
@@ -74,6 +74,27 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.org-name {
|
||||
line-height: 1;
|
||||
span {
|
||||
display: block;
|
||||
font-size: $font-size-lg;
|
||||
@include themify($themes) {
|
||||
color: themed("textHeadingColor");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabbed-nav {
|
||||
@include themify($themes) {
|
||||
border-bottom: 1px solid themed("borderColor");
|
||||
color: themed("textColor");
|
||||
}
|
||||
}
|
||||
|
||||
.org-nav,
|
||||
.tabbed-nav {
|
||||
.nav-tabs {
|
||||
border-bottom: none;
|
||||
|
||||
@@ -90,6 +111,7 @@
|
||||
padding-top: calc(#{$nav-link-padding-y} - 2px);
|
||||
@include themify($themes) {
|
||||
border-top: 3px solid themed("primary");
|
||||
border-bottom: 1px solid themed("backgroundColor");
|
||||
color: themed("linkColor");
|
||||
}
|
||||
}
|
||||
@@ -101,15 +123,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.org-name {
|
||||
line-height: 1;
|
||||
span {
|
||||
display: block;
|
||||
font-size: $font-size-lg;
|
||||
@include themify($themes) {
|
||||
color: themed("textHeadingColor");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user