diff --git a/apps/browser/src/popup/images/two-factor/0.png b/apps/browser/src/popup/images/two-factor/0.png new file mode 100644 index 0000000000..307ff4fd60 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/0.png differ diff --git a/apps/browser/src/popup/images/two-factor/1-w.png b/apps/browser/src/popup/images/two-factor/1-w.png new file mode 100644 index 0000000000..a4e39b3f46 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/1-w.png differ diff --git a/apps/browser/src/popup/images/two-factor/1.png b/apps/browser/src/popup/images/two-factor/1.png new file mode 100644 index 0000000000..37fb7bc432 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/1.png differ diff --git a/apps/browser/src/popup/images/two-factor/2.png b/apps/browser/src/popup/images/two-factor/2.png new file mode 100644 index 0000000000..d069bdab99 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/2.png differ diff --git a/apps/browser/src/popup/images/two-factor/3.png b/apps/browser/src/popup/images/two-factor/3.png new file mode 100644 index 0000000000..c543343f53 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/3.png differ diff --git a/apps/browser/src/popup/images/two-factor/4.png b/apps/browser/src/popup/images/two-factor/4.png new file mode 100644 index 0000000000..058671ea37 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/4.png differ diff --git a/apps/browser/src/popup/images/two-factor/6.png b/apps/browser/src/popup/images/two-factor/6.png new file mode 100644 index 0000000000..d069bdab99 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/6.png differ diff --git a/apps/browser/src/popup/images/two-factor/7-w.png b/apps/browser/src/popup/images/two-factor/7-w.png new file mode 100644 index 0000000000..89fdd8a2a0 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/7-w.png differ diff --git a/apps/browser/src/popup/images/two-factor/7.png b/apps/browser/src/popup/images/two-factor/7.png new file mode 100644 index 0000000000..2a38bdcd3e Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/7.png differ diff --git a/apps/browser/src/popup/images/two-factor/rc-w.png b/apps/browser/src/popup/images/two-factor/rc-w.png new file mode 100644 index 0000000000..e83b8db132 Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/rc-w.png differ diff --git a/apps/browser/src/popup/images/two-factor/rc.png b/apps/browser/src/popup/images/two-factor/rc.png new file mode 100644 index 0000000000..4bebdf936c Binary files /dev/null and b/apps/browser/src/popup/images/two-factor/rc.png differ diff --git a/apps/browser/src/popup/scss/plugins.scss b/apps/browser/src/popup/scss/plugins.scss new file mode 100644 index 0000000000..b8ac8697b7 --- /dev/null +++ b/apps/browser/src/popup/scss/plugins.scss @@ -0,0 +1,31 @@ +@import "variables.scss"; + +@each $mfaType in $mfaTypes { + .mfaType#{$mfaType} { + content: url("../images/two-factor/" + $mfaType + ".png"); + max-width: 100px; + } +} + +.mfaType1 { + @include themify($themes) { + content: url("../images/two-factor/1" + themed("mfaLogoSuffix")); + max-width: 100px; + max-height: 45px; + } +} + +.mfaType7 { + @include themify($themes) { + content: url("../images/two-factor/7" + themed("mfaLogoSuffix")); + max-width: 100px; + } +} + +.recovery-code-img { + @include themify($themes) { + content: url("../images/two-factor/rc" + themed("mfaLogoSuffix")); + max-width: 100px; + max-height: 45px; + } +} diff --git a/apps/browser/src/popup/scss/popup.scss b/apps/browser/src/popup/scss/popup.scss index 850ef96c64..8dc2c206f8 100644 --- a/apps/browser/src/popup/scss/popup.scss +++ b/apps/browser/src/popup/scss/popup.scss @@ -10,5 +10,6 @@ @import "modal.scss"; @import "environment.scss"; @import "pages.scss"; +@import "plugins.scss"; @import "@angular/cdk/overlay-prebuilt.css"; @import "../../../../../libs/components/src/multi-select/scss/bw.theme"; diff --git a/apps/browser/src/popup/scss/variables.scss b/apps/browser/src/popup/scss/variables.scss index d8891cf620..a4366a7415 100644 --- a/apps/browser/src/popup/scss/variables.scss +++ b/apps/browser/src/popup/scss/variables.scss @@ -19,6 +19,8 @@ $border-radius: 6px; $line-height-base: 1.42857143; $icon-hover-color: lighten($text-color, 50%); +$mfaTypes: 0, 2, 3, 4, 6; + $gray: #555; $gray-light: #777; $text-muted: $gray-light; @@ -111,6 +113,7 @@ $themes: ( infoColor: $brand-info, warningColor: $brand-warning, logoSuffix: "dark", + mfaLogoSuffix: ".png", passwordNumberColor: #007fde, passwordSpecialColor: #c40800, passwordCountText: #212529, @@ -174,6 +177,7 @@ $themes: ( infoColor: #a4b0c6, warningColor: #ffeb66, logoSuffix: "white", + mfaLogoSuffix: "-w.png", passwordNumberColor: #6f9df1, passwordSpecialColor: #ff8d85, passwordCountText: #ffffff, @@ -236,6 +240,7 @@ $themes: ( infoColor: $nord9, warningColor: $nord12, logoSuffix: "white", + mfaLogoSuffix: "-w.png", passwordNumberColor: $nord8, passwordSpecialColor: $nord12, passwordCountText: $nord5, @@ -298,6 +303,7 @@ $themes: ( infoColor: $solarizedDarkGreen, warningColor: $solarizedDarkYellow, logoSuffix: "white", + mfaLogoSuffix: "-w.png", passwordNumberColor: $solarizedDarkCyan, passwordSpecialColor: $solarizedDarkYellow, passwordCountText: $solarizedDarkBase2, diff --git a/apps/desktop/src/images/two-factor/0.png b/apps/desktop/src/images/two-factor/0.png index f37e3f17b4..307ff4fd60 100644 Binary files a/apps/desktop/src/images/two-factor/0.png and b/apps/desktop/src/images/two-factor/0.png differ diff --git a/apps/desktop/src/images/two-factor/1-w.png b/apps/desktop/src/images/two-factor/1-w.png new file mode 100644 index 0000000000..a4e39b3f46 Binary files /dev/null and b/apps/desktop/src/images/two-factor/1-w.png differ diff --git a/apps/desktop/src/images/two-factor/1.png b/apps/desktop/src/images/two-factor/1.png index b47a12b1db..37fb7bc432 100644 Binary files a/apps/desktop/src/images/two-factor/1.png and b/apps/desktop/src/images/two-factor/1.png differ diff --git a/apps/desktop/src/images/two-factor/2.png b/apps/desktop/src/images/two-factor/2.png index ab2e434036..d069bdab99 100644 Binary files a/apps/desktop/src/images/two-factor/2.png and b/apps/desktop/src/images/two-factor/2.png differ diff --git a/apps/desktop/src/images/two-factor/3.png b/apps/desktop/src/images/two-factor/3.png index 21aac2da67..c543343f53 100644 Binary files a/apps/desktop/src/images/two-factor/3.png and b/apps/desktop/src/images/two-factor/3.png differ diff --git a/apps/desktop/src/images/two-factor/4.png b/apps/desktop/src/images/two-factor/4.png index ae7d7b55e4..058671ea37 100644 Binary files a/apps/desktop/src/images/two-factor/4.png and b/apps/desktop/src/images/two-factor/4.png differ diff --git a/apps/desktop/src/images/two-factor/6.png b/apps/desktop/src/images/two-factor/6.png index ab2e434036..d069bdab99 100644 Binary files a/apps/desktop/src/images/two-factor/6.png and b/apps/desktop/src/images/two-factor/6.png differ diff --git a/apps/desktop/src/images/two-factor/7-w.png b/apps/desktop/src/images/two-factor/7-w.png new file mode 100644 index 0000000000..89fdd8a2a0 Binary files /dev/null and b/apps/desktop/src/images/two-factor/7-w.png differ diff --git a/apps/desktop/src/images/two-factor/7.png b/apps/desktop/src/images/two-factor/7.png new file mode 100644 index 0000000000..2a38bdcd3e Binary files /dev/null and b/apps/desktop/src/images/two-factor/7.png differ diff --git a/apps/desktop/src/images/two-factor/rc-w.png b/apps/desktop/src/images/two-factor/rc-w.png new file mode 100644 index 0000000000..e83b8db132 Binary files /dev/null and b/apps/desktop/src/images/two-factor/rc-w.png differ diff --git a/apps/desktop/src/images/two-factor/rc.png b/apps/desktop/src/images/two-factor/rc.png new file mode 100644 index 0000000000..4bebdf936c Binary files /dev/null and b/apps/desktop/src/images/two-factor/rc.png differ diff --git a/apps/desktop/src/scss/plugins.scss b/apps/desktop/src/scss/plugins.scss new file mode 100644 index 0000000000..b8ac8697b7 --- /dev/null +++ b/apps/desktop/src/scss/plugins.scss @@ -0,0 +1,31 @@ +@import "variables.scss"; + +@each $mfaType in $mfaTypes { + .mfaType#{$mfaType} { + content: url("../images/two-factor/" + $mfaType + ".png"); + max-width: 100px; + } +} + +.mfaType1 { + @include themify($themes) { + content: url("../images/two-factor/1" + themed("mfaLogoSuffix")); + max-width: 100px; + max-height: 45px; + } +} + +.mfaType7 { + @include themify($themes) { + content: url("../images/two-factor/7" + themed("mfaLogoSuffix")); + max-width: 100px; + } +} + +.recovery-code-img { + @include themify($themes) { + content: url("../images/two-factor/rc" + themed("mfaLogoSuffix")); + max-width: 100px; + max-height: 45px; + } +} diff --git a/apps/desktop/src/scss/styles.scss b/apps/desktop/src/scss/styles.scss index 54c1385dcf..187b4bf23c 100644 --- a/apps/desktop/src/scss/styles.scss +++ b/apps/desktop/src/scss/styles.scss @@ -15,5 +15,6 @@ @import "header.scss"; @import "left-nav.scss"; @import "loading.scss"; +@import "plugins.scss"; @import "../../../../libs/angular/src/scss/icons.scss"; @import "../../../../libs/components/src/multi-select/scss/bw.theme"; diff --git a/apps/desktop/src/scss/variables.scss b/apps/desktop/src/scss/variables.scss index e4a2f12476..6f8112b1ca 100644 --- a/apps/desktop/src/scss/variables.scss +++ b/apps/desktop/src/scss/variables.scss @@ -15,6 +15,8 @@ $list-icon-color: #c7c7cd; $border-radius: 3px; $line-height-base: 1.42857143; +$mfaTypes: 0, 2, 3, 4, 6; + $gray: #555; $gray-light: #777; $text-muted: $gray-light; @@ -92,6 +94,7 @@ $themes: ( infoColor: $brand-info, warningColor: $brand-warning, logoSuffix: "dark", + mfaLogoSuffix: ".png", passwordNumberColor: #007fde, passwordSpecialColor: #c40800, passwordCountText: #212529, @@ -150,6 +153,7 @@ $themes: ( infoColor: #a4b0c6, warningColor: #ffeb66, logoSuffix: "white", + mfaLogoSuffix: "-w.png", passwordNumberColor: #6f9df1, passwordSpecialColor: #ff8d85, passwordCountText: #ffffff, @@ -208,6 +212,7 @@ $themes: ( infoColor: $nord9, warningColor: $nord12, logoSuffix: "white", + mfaLogoSuffix: "-w.png", passwordNumberColor: $nord8, passwordSpecialColor: $nord12, passwordCountText: $nord5, diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-options.component.html b/libs/angular/src/auth/components/two-factor-auth/two-factor-options.component.html new file mode 100644 index 0000000000..bd19c4cd0b --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-options.component.html @@ -0,0 +1,51 @@ + + + {{ "twoStepOptions" | i18n }} + + + + + + + + + {{ p.name }} + {{ p.description }} + + + + {{ "select" | i18n }} + + + + + + + + + + + + {{ "recoveryCodeTitle" | i18n }} + {{ "recoveryCodeDesc" | i18n }} + + + + {{ "select" | i18n }} + + + + + + + + {{ "close" | i18n }} + + + diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-options.component.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-options.component.ts new file mode 100644 index 0000000000..61f225cc21 --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-options.component.ts @@ -0,0 +1,74 @@ +import { DialogRef } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component, EventEmitter, OnInit, Output } from "@angular/core"; +import { firstValueFrom } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe"; +import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; +import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; +import { ClientType } from "@bitwarden/common/enums"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ButtonModule, DialogModule, DialogService, TypographyModule } from "@bitwarden/components"; + +export enum TwoFactorOptionsDialogResult { + Provider = "Provider selected", + Recover = "Recover selected", +} + +export type TwoFactorOptionsDialogResultType = { + result: TwoFactorOptionsDialogResult; + type: TwoFactorProviderType; +}; + +@Component({ + standalone: true, + selector: "app-two-factor-options", + templateUrl: "two-factor-options.component.html", + imports: [CommonModule, JslibModule, DialogModule, ButtonModule, TypographyModule], + providers: [I18nPipe], +}) +export class TwoFactorOptionsComponent implements OnInit { + @Output() onProviderSelected = new EventEmitter(); + @Output() onRecoverSelected = new EventEmitter(); + + providers: any[] = []; + + // todo: remove after porting to two-factor-options-v2 + // icons cause the layout to break on browser extensions + areIconsDisabled = false; + + constructor( + private twoFactorService: TwoFactorService, + private environmentService: EnvironmentService, + private dialogRef: DialogRef, + private platformUtilsService: PlatformUtilsService, + ) { + // todo: remove after porting to two-factor-options-v2 + if (this.platformUtilsService.getClientType() == ClientType.Browser) { + this.areIconsDisabled = true; + } + } + + async ngOnInit() { + this.providers = await this.twoFactorService.getSupportedProviders(window); + } + + async choose(p: any) { + this.onProviderSelected.emit(p.type); + this.dialogRef.close({ result: TwoFactorOptionsDialogResult.Provider, type: p.type }); + } + + async recover() { + const env = await firstValueFrom(this.environmentService.environment$); + const webVault = env.getWebVaultUrl(); + this.platformUtilsService.launchUri(webVault + "/#/recover-2fa"); + this.onRecoverSelected.emit(); + this.dialogRef.close({ result: TwoFactorOptionsDialogResult.Recover }); + } + + static open(dialogService: DialogService) { + return dialogService.open(TwoFactorOptionsComponent); + } +}
{{ p.description }}
{{ "recoveryCodeDesc" | i18n }}