diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 2675e38ee8c..0e8ffb1151d 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" diff --git a/apps/cli/src/locales/en/messages.json b/apps/cli/src/locales/en/messages.json index 3f753781127..f8a49c6e923 100644 --- a/apps/cli/src/locales/en/messages.json +++ b/apps/cli/src/locales/en/messages.json @@ -5,8 +5,8 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "emailTitle": { "message": "Email" diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 333a1c0e7bc..4781042413d 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html index 4e447bd8921..e796fd39a8e 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html @@ -5,13 +5,6 @@ {{ "authenticatorAppTitle" | i18n }} - - Authenticator app logo -

{{ "twoStepAuthenticatorDesc" | i18n }}

-

- 1. {{ "twoStepAuthenticatorDownloadApp" | i18n }} -

-

{{ "twoStepLoginProviderEnabled" | i18n }}

@@ -20,42 +13,64 @@ Authenticator app logo

{{ "twoStepAuthenticatorNeedApp" | i18n }}

- -

{{ "twoStepAuthenticatorAppsRecommended" | i18n }}

-

- 2. {{ "twoStepAuthenticatorScanCode" | i18n }} -

+ {{ "twoStepAuthenticatorInstructionSuffix" | i18n }} +

+ +

+ + Download on App Store + + + + + Get it on Google Play + +

+ {{ "twoStepAuthenticatorScanCodeV2" | i18n }} +


@@ -63,7 +78,7 @@

- 3. {{ "twoStepAuthenticatorEnterCode" | i18n }} + {{ "twoStepAuthenticatorEnterCodeV2" | i18n }} diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts index 17cdbb595f7..0a53f0f3c6a 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts @@ -148,4 +148,29 @@ export class TwoFactorAuthenticatorComponent ) { return dialogService.open(TwoFactorAuthenticatorComponent, config); } + + async launchExternalUrl(url: string) { + const hostname = new URL(url).hostname; + const confirmed = await this.dialogService.openSimpleDialog({ + title: this.i18nService.t("continueToExternalUrlTitle", hostname), + content: this.i18nService.t("continueToExternalUrlDesc"), + type: "info", + acceptButtonText: { key: "continue" }, + }); + if (confirmed) { + this.platformUtilsService.launchUri(url); + } + } + + async launchBitwardenUrl(url: string) { + const confirmed = await this.dialogService.openSimpleDialog({ + title: this.i18nService.t("twoStepContinueToBitwardenUrlTitle"), + content: this.i18nService.t("twoStepContinueToBitwardenUrlDesc"), + type: "info", + acceptButtonText: { key: "continue" }, + }); + if (confirmed) { + this.platformUtilsService.launchUri(url); + } + } } diff --git a/apps/web/src/app/auth/settings/two-factor-setup.component.html b/apps/web/src/app/auth/settings/two-factor-setup.component.html index 28baf72f885..33265e91f78 100644 --- a/apps/web/src/app/auth/settings/two-factor-setup.component.html +++ b/apps/web/src/app/auth/settings/two-factor-setup.component.html @@ -48,11 +48,16 @@ - YubiKey OTP security key logo + Yubico OTP security key logo

{{ "twoFactorYubikeyAdd" | i18n }}:

  1. {{ "twoFactorYubikeyPlugIn" | i18n }}
  2. diff --git a/apps/web/src/app/auth/two-factor-options.component.html b/apps/web/src/app/auth/two-factor-options.component.html index e99c848a8d0..43c054060ea 100644 --- a/apps/web/src/app/auth/two-factor-options.component.html +++ b/apps/web/src/app/auth/two-factor-options.component.html @@ -5,8 +5,8 @@
    -
    - +
    +

    {{ p.name }}

    @@ -22,8 +22,8 @@
    -
    - rc logo +
    +

    {{ "recoveryCodeTitle" | i18n }}

    diff --git a/apps/web/src/images/download_apple_appstore.svg b/apps/web/src/images/download_apple_appstore.svg new file mode 100755 index 00000000000..072b425a1ab --- /dev/null +++ b/apps/web/src/images/download_apple_appstore.svg @@ -0,0 +1,46 @@ + + Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/images/download_google_playstore.svg b/apps/web/src/images/download_google_playstore.svg new file mode 100644 index 00000000000..35ee731b222 --- /dev/null +++ b/apps/web/src/images/download_google_playstore.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 7a129f04e61..b0a638ad972 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." diff --git a/apps/web/src/scss/plugins.scss b/apps/web/src/scss/plugins.scss index 2f466484765..40ba692c463 100644 --- a/apps/web/src/scss/plugins.scss +++ b/apps/web/src/scss/plugins.scss @@ -32,29 +32,37 @@ .list-group-2fa { .logo-2fa { - min-width: 100px; + min-width: 120px; } } @each $mfaType in $mfaTypes { .mfaType#{$mfaType} { content: url("../images/two-factor/" + $mfaType + ".png"); - max-width: 100px; + max-width: 120px; + } +} + +.mfaType0 { + @include themify($themes) { + content: url("../images/two-factor/0.png"); + max-width: 120px; + max-height: 62px; } } .mfaType1 { @include themify($themes) { content: url("../images/two-factor/1" + themed("mfaLogoSuffix")); - max-width: 100px; - max-height: 45px; + max-width: 120px; + max-height: 62px; } } .mfaType7 { @include themify($themes) { content: url("../images/two-factor/7" + themed("mfaLogoSuffix")); - max-width: 100px; + max-width: 120px; } } diff --git a/libs/angular/src/auth/components/two-factor-icon.component.html b/libs/angular/src/auth/components/two-factor-icon.component.html new file mode 100644 index 00000000000..46d5211ca0a --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-icon.component.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/libs/angular/src/auth/components/two-factor-icon.component.ts b/libs/angular/src/auth/components/two-factor-icon.component.ts new file mode 100644 index 00000000000..338ea25a3f3 --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-icon.component.ts @@ -0,0 +1,24 @@ +import { Component, Input } from "@angular/core"; + +import { EmailIcon } from "../icons/email.icon"; +import { RecoveryCodeIcon } from "../icons/recovery.icon"; +import { TOTPIcon } from "../icons/totp.icon"; +import { WebAuthnIcon } from "../icons/webauthn.icon"; + +@Component({ + selector: "auth-two-factor-icon", + templateUrl: "./two-factor-icon.component.html", +}) +export class TwoFactorIconComponent { + @Input() provider: any; + @Input() name: string; + + protected readonly Icons = { + TOTPIcon, + EmailIcon, + WebAuthnIcon, + RecoveryCodeIcon, + }; + + constructor() {} +} diff --git a/libs/angular/src/auth/icons/email.icon.ts b/libs/angular/src/auth/icons/email.icon.ts new file mode 100644 index 00000000000..7b5163898fd --- /dev/null +++ b/libs/angular/src/auth/icons/email.icon.ts @@ -0,0 +1,44 @@ +import { svgIcon } from "@bitwarden/components"; + +export const EmailIcon = svgIcon` + + Email + + + + + + + + + + + + +`; diff --git a/libs/angular/src/auth/icons/recovery.icon.ts b/libs/angular/src/auth/icons/recovery.icon.ts new file mode 100644 index 00000000000..e23b46bebe1 --- /dev/null +++ b/libs/angular/src/auth/icons/recovery.icon.ts @@ -0,0 +1,51 @@ +import { svgIcon } from "@bitwarden/components"; + +export const RecoveryCodeIcon = svgIcon` + + Recovery Code + + + + + + + + + + + + +`; diff --git a/libs/angular/src/auth/icons/totp.icon.ts b/libs/angular/src/auth/icons/totp.icon.ts new file mode 100644 index 00000000000..1754e77b308 --- /dev/null +++ b/libs/angular/src/auth/icons/totp.icon.ts @@ -0,0 +1,61 @@ +import { svgIcon } from "@bitwarden/components"; + +export const TOTPIcon = svgIcon` + + TOTP Authenticator + + + + + + + + + + + + + + + + + +`; diff --git a/libs/angular/src/auth/icons/webauthn.icon.ts b/libs/angular/src/auth/icons/webauthn.icon.ts new file mode 100644 index 00000000000..a72692233d8 --- /dev/null +++ b/libs/angular/src/auth/icons/webauthn.icon.ts @@ -0,0 +1,42 @@ +import { svgIcon } from "@bitwarden/components"; + +export const WebAuthnIcon = svgIcon` + + Webauthn + + + + + + + + + + +`; diff --git a/libs/angular/src/jslib.module.ts b/libs/angular/src/jslib.module.ts index b03dde3a34a..f547799496e 100644 --- a/libs/angular/src/jslib.module.ts +++ b/libs/angular/src/jslib.module.ts @@ -17,6 +17,7 @@ import { DialogModule, FormFieldModule, IconButtonModule, + IconModule, LinkModule, MenuModule, RadioButtonModule, @@ -26,6 +27,7 @@ import { TypographyModule, } from "@bitwarden/components"; +import { TwoFactorIconComponent } from "./auth/components/two-factor-icon.component"; import { CalloutComponent } from "./components/callout.component"; import { A11yInvalidDirective } from "./directives/a11y-invalid.directive"; import { A11yTitleDirective } from "./directives/a11y-title.directive"; @@ -74,6 +76,7 @@ import { IconComponent } from "./vault/components/icon.component"; TableModule, MenuModule, IconButtonModule, + IconModule, LinkModule, ], declarations: [ @@ -109,6 +112,7 @@ import { IconComponent } from "./vault/components/icon.component"; ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, + TwoFactorIconComponent, ], exports: [ A11yInvalidDirective, @@ -144,6 +148,7 @@ import { IconComponent } from "./vault/components/icon.component"; ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, + TwoFactorIconComponent, ], providers: [ CreditCardNumberPipe, diff --git a/libs/common/src/auth/services/two-factor.service.ts b/libs/common/src/auth/services/two-factor.service.ts index 50d25561577..d67929c46f0 100644 --- a/libs/common/src/auth/services/two-factor.service.ts +++ b/libs/common/src/auth/services/two-factor.service.ts @@ -18,7 +18,7 @@ export const TwoFactorProviders: Partial