mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-10 19:38:11 +01:00
[SG-416] Updates to Bitwarden Authenticator (#3045)
* [SG-416] Changed UI for TOTP codes on free plan and added link to get Premium. On browser, changed back action of premium.component in order to reuse on cipher details. * [SSG-416] PR Fix * [SSG-416] fix formatting * [SSG-416] Updated desktop free plan OTP UI * [SSG-416] noticed a bad div tag making file changes erratic * [SG-416] fixed label * [SSG-416] Fix formatting * [SSG-416] Changed bootstrap classes to tailwind * [SSG-416] Added premium and upgrade badge back. Muted placeholder totp code colors and button. * [SSG-416] Change learn more to upgrade label on get premium modal. Fixed navigation for premium. * [SSG-416] Removed unused image file. * [SG-416] Changed browser "Premium subscription required" text to be all hyperlink. * [SG-416] Fixed missing resource on browser * [SG-416] Code format with lint
This commit is contained in:
parent
31cae4390f
commit
c4f9c2cca6
@ -1967,6 +1967,9 @@
|
||||
},
|
||||
"ssoKeyConnectorError": {
|
||||
"message": "Key Connector error: make sure Key Connector is available and working correctly."
|
||||
},
|
||||
"premiumSubcriptionRequired": {
|
||||
"message": "Premium subscription required"
|
||||
},
|
||||
"organizationIsDisabled": {
|
||||
"message": "Organization is disabled."
|
||||
|
@ -1,6 +1,6 @@
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" routerLink="/tabs/settings">
|
||||
<button type="button" (click)="goBack()">
|
||||
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
|
||||
<span>{{ "back" | i18n }}</span>
|
||||
</button>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CurrencyPipe } from "@angular/common";
|
||||
import { CurrencyPipe, Location } from "@angular/common";
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/components/premium.component";
|
||||
@ -21,6 +21,7 @@ export class PremiumComponent extends BasePremiumComponent {
|
||||
apiService: ApiService,
|
||||
stateService: StateService,
|
||||
logService: LogService,
|
||||
private location: Location,
|
||||
private currencyPipe: CurrencyPipe
|
||||
) {
|
||||
super(i18nService, platformUtilsService, apiService, logService, stateService);
|
||||
@ -32,4 +33,8 @@ export class PremiumComponent extends BasePremiumComponent {
|
||||
this.priceString = this.priceString.replace("%price%", thePrice);
|
||||
}
|
||||
}
|
||||
|
||||
goBack() {
|
||||
this.location.back();
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +139,7 @@
|
||||
<div
|
||||
class="box-content-row box-content-row-flex totp"
|
||||
[ngClass]="{ low: totpLow }"
|
||||
*ngIf="cipher.login.totp && totpCode"
|
||||
*ngIf="cipher.login.totp && totpCode && canAccessPremium"
|
||||
>
|
||||
<div class="row-main">
|
||||
<span
|
||||
@ -177,6 +177,20 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="box-content-row box-content-row-flex totp"
|
||||
*ngIf="cipher.login.totp && !canAccessPremium"
|
||||
>
|
||||
<div class="row-main">
|
||||
<span class="row-label">{{ "verificationCodeTotp" | i18n }}</span>
|
||||
<span class="row-label">
|
||||
<a routerLink="/premium">
|
||||
{{ "premiumSubcriptionRequired" | i18n }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card -->
|
||||
<div *ngIf="cipher.card">
|
||||
|
@ -100,7 +100,7 @@
|
||||
<div
|
||||
class="box-content-row box-content-row-flex totp"
|
||||
[ngClass]="{ low: totpLow }"
|
||||
*ngIf="cipher.login.totp && totpCode"
|
||||
*ngIf="cipher.login.totp && totpCode && canAccessPremium"
|
||||
>
|
||||
<div class="row-main">
|
||||
<span
|
||||
@ -138,6 +138,19 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="box-content-row box-content-row-flex totp"
|
||||
*ngIf="cipher.login.totp && !canAccessPremium"
|
||||
>
|
||||
<div class="row-main">
|
||||
<span class="row-label">{{ "verificationCodeTotp" | i18n }}</span>
|
||||
<span class="row-label">
|
||||
<a [routerLink]="" (click)="showGetPremium()"
|
||||
>{{ "premiumSubcriptionRequired" | i18n }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card -->
|
||||
<div *ngIf="cipher.card">
|
||||
|
@ -115,4 +115,10 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
showGetPremium() {
|
||||
if (!this.canAccessPremium) {
|
||||
this.messagingService.send("premiumRequired");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1979,6 +1979,9 @@
|
||||
"apiKey": {
|
||||
"message": "API Key"
|
||||
},
|
||||
"premiumSubcriptionRequired": {
|
||||
"message": "Premium subscription required"
|
||||
},
|
||||
"organizationIsDisabled": {
|
||||
"message": "Organization is disabled."
|
||||
},
|
||||
|
@ -147,7 +147,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
||||
const premiumConfirmed = await this.platformUtilsService.showDialog(
|
||||
this.i18nService.t("premiumRequiredDesc"),
|
||||
this.i18nService.t("premiumRequired"),
|
||||
this.i18nService.t("learnMore"),
|
||||
this.i18nService.t("upgrade"),
|
||||
this.i18nService.t("cancel")
|
||||
);
|
||||
if (premiumConfirmed) {
|
||||
|
@ -166,8 +166,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 form-group">
|
||||
<div class="tw-flex tw-flex-row">
|
||||
<div class="tw-mb-4 tw-w-1/2">
|
||||
<label for="loginTotp">{{ "authenticatorKeyTotp" | i18n }}</label>
|
||||
<input
|
||||
id="loginTotp"
|
||||
@ -179,14 +179,41 @@
|
||||
[disabled]="cipher.isDeleted || !cipher.viewPassword || viewOnly"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6 form-group totp d-flex align-items-end" [ngClass]="{ low: totpLow }">
|
||||
<div *ngIf="!cipher.login.totp || !totpCode">
|
||||
<img
|
||||
src="../../images/totp-countdown.png"
|
||||
id="totpImage"
|
||||
<div class="tw-mb-4 tw-ml-4 tw-flex tw-w-1/2 tw-items-end" [ngClass]="{ low: totpLow }">
|
||||
<div
|
||||
class="totp tw-flex tw-flex-row tw-items-center"
|
||||
*ngIf="!cipher.login.totp || (cipher.login.totp && !canAccessPremium)"
|
||||
>
|
||||
<span class="totp-countdown">
|
||||
<span class="totp-sec tw-text-muted">15</span>
|
||||
<svg>
|
||||
<g>
|
||||
<circle
|
||||
class="totp-circle-muted inner"
|
||||
r="12.6"
|
||||
cy="16"
|
||||
cx="16"
|
||||
opacity="0.25"
|
||||
[ngStyle]="{ 'stroke-dashoffset.px': 40 }"
|
||||
></circle>
|
||||
<circle
|
||||
class="totp-circle-muted outer"
|
||||
opacity="0.25"
|
||||
r="14"
|
||||
cy="16"
|
||||
cx="16"
|
||||
></circle>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="totp-code tw-mr-3 tw-ml-2 tw-text-muted"
|
||||
title="{{ 'verificationCodeTotp' | i18n }}"
|
||||
class="ml-2"
|
||||
/>
|
||||
>--- ---</span
|
||||
>
|
||||
<i class="bwi bwi-lg bwi-clone tw-text-muted" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="tw-pb-2" *ngIf="!cipher.login.totp || !totpCode">
|
||||
<app-premium-badge
|
||||
*ngIf="!organization && !cipher.organizationId"
|
||||
class="ml-3"
|
||||
@ -209,8 +236,11 @@
|
||||
{{ "upgrade" | i18n }}
|
||||
</a>
|
||||
</div>
|
||||
<div *ngIf="cipher.login.totp && totpCode" class="d-flex align-items-center">
|
||||
<span class="totp-countdown mr-3 ml-2">
|
||||
<div
|
||||
*ngIf="cipher.login.totp && totpCode && canAccessPremium"
|
||||
class="totp tw-flex tw-flex-row tw-items-center"
|
||||
>
|
||||
<span class="totp-countdown">
|
||||
<span class="totp-sec">{{ totpSec }}</span>
|
||||
<svg>
|
||||
<g>
|
||||
@ -225,16 +255,18 @@
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="totp-code mr-2" title="{{ 'verificationCodeTotp' | i18n }}">{{
|
||||
totpCodeFormatted
|
||||
}}</span>
|
||||
<span
|
||||
class="totp-code tw-mr-2 tw-ml-2 tw-mt-1"
|
||||
title="{{ 'verificationCodeTotp' | i18n }}"
|
||||
>{{ totpCodeFormatted }}</span
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-link"
|
||||
class="tw-items-center tw-border-none tw-bg-transparent tw-text-primary-500"
|
||||
appA11yTitle="{{ 'copyVerificationCode' | i18n }}"
|
||||
(click)="copy(totpCode, 'verificationCodeTotp', 'TOTP')"
|
||||
>
|
||||
<i class="bwi bwi-clone" aria-hidden="true"></i>
|
||||
<i class="bwi bwi-lg bwi-clone" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -152,6 +152,17 @@ export class AddEditComponent extends BaseAddEditComponent {
|
||||
});
|
||||
}
|
||||
|
||||
showGetPremium() {
|
||||
if (this.canAccessPremium) {
|
||||
return;
|
||||
}
|
||||
if (this.cipher.organizationUseTotp) {
|
||||
this.upgradeOrganization();
|
||||
} else {
|
||||
this.premiumRequired();
|
||||
}
|
||||
}
|
||||
|
||||
viewHistory() {
|
||||
this.viewingPasswordHistory = !this.viewingPasswordHistory;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 950 B |
@ -5220,6 +5220,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"premiumSubcriptionRequired": {
|
||||
"message": "Premium subscription required"
|
||||
},
|
||||
"scim": {
|
||||
"message": "SCIM Provisioning",
|
||||
"description": "The text, 'SCIM', is an acronymn and should not be translated."
|
||||
|
@ -130,6 +130,25 @@
|
||||
stroke-width: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.totp-circle-muted {
|
||||
fill: none;
|
||||
@include themify($themes) {
|
||||
stroke: themed("info");
|
||||
}
|
||||
|
||||
&.inner {
|
||||
stroke-dasharray: 78.6;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
&.outer {
|
||||
stroke-dasharray: 88;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .align-items-center {
|
||||
|
Loading…
Reference in New Issue
Block a user