From 20b24e3d6385b449d784c0a475cf221c9311bc2f Mon Sep 17 00:00:00 2001 From: Daniel Palafox Date: Mon, 18 Mar 2024 14:31:59 -0600 Subject: [PATCH 1/2] fix: Update 2FA error conditions and styling (#2200) Co-authored-by: Daniel Palafox --- ...-factor-authentication-form.component.html | 487 ++++++++++-------- ...-factor-authentication-form.component.scss | 188 +++---- ...hentication-form.component.scss-theme.scss | 34 +- ...wo-factor-authentication-form.component.ts | 268 +++++----- .../form-sign-in/form-sign-in.component.html | 2 +- .../components/social/social.component.html | 140 ++--- .../institutional-access-no-background.svg | 11 + 7 files changed, 628 insertions(+), 502 deletions(-) create mode 100644 src/assets/vectors/institutional-access-no-background.svg diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html index ab93f2ac42..62a449b443 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html @@ -1,202 +1,285 @@ -
-

- Two-factor authentication -

-
- Two-factor authentication code - - - - Two-factor authentication code - - - {{ inputVerificationCode.value?.length || 0 }}/6 - -

- Authentication code is required -

-

- {{ inputVerificationCode.value?.length || 0 }}/6 -

-
- - -

- Invalid authentication code length -

-

- {{ inputVerificationCode.value?.length || 0 }}/6 -

-
-
-
-

- Enter a code - - - from your two-factor authentication app - -

-

- - Don't have your device? - - Enter a recovery code - -

-

- - Don't have your device or recovery code? - - ORCID Help Center - -

-
- Recovery code - - - - Recovery code - - - {{ inputRecoveryCode.value?.length || 0 }}/10 - -

- Recovery code is required -

-

- {{ inputRecoveryCode.value?.length || 0 }}/10 -

-
- - -

- Invalid recovery code length -

-

- {{ inputRecoveryCode.value?.length || 0 }}/10 -

-
-
-
- - -
- - error - - Invalid authentication code - - - - error - - Invalid recovery code - - +
+

+ Two-factor authentication +

+
+ Two-factor authentication code + + + + Two-factor authentication code + + + + {{ inputVerificationCode.value?.length || 0 }}/6 + +

+ Authentication code is required +

+

+ {{ inputVerificationCode.value?.length || 0 }}/6 +

+
+ + +

+ Invalid authentication code length +

+

+ {{ inputVerificationCode.value?.length || 0 }}/6 +

+
+
+
+ + {{ verificationFormControl.value?.length || 0 }}/6 + +

+ Authentication code is required +

+

+ {{ verificationFormControl.value?.length || 0 }}/6 +

+
+ + +

+ Invalid authentication code length +

+

+ {{ verificationFormControl.value?.length || 0 }}/6 +

+
+
+
+

+ Enter a code + + + from your two-factor authentication app + +

+

+ + Don't have your device? + + Enter a recovery code + +

+

+ + Don't have your device or recovery code? + + ORCID Help Center + +

+
+ Recovery code + + + + Recovery code + + + + {{ inputRecoveryCode.value?.length || 0 }}/10 + +

+ Recovery code is required +

+

+ {{ inputRecoveryCode.value?.length || 0 }}/10 +

+
+ + +

+ Invalid recovery code length +

+

+ {{ inputRecoveryCode.value?.length || 0 }}/10 +

+
+
+
+ + {{ recoveryCodeFormControl.value?.length || 0 }}/10 + +

+ Recovery code is required +

+

+ {{ recoveryCodeFormControl.value?.length || 0 }}/10 +

+
+ + +

+ Invalid recovery code length +

+

+ {{ recoveryCodeFormControl.value?.length || 0 }}/10 +

+
+
+
+ + +
+ + error + + Invalid authentication code + + + + error + + Invalid recovery code + + diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss index c9b74ad4e1..9ef870a7b2 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss @@ -1,92 +1,96 @@ -:host { - width: 100%; -} - -.mat-button-font { - margin: auto; -} - -.two-factor { - margin-top: 12px; -} - -.error-message { - float: left; - margin: 0; - [dir='rtl'] :host & { - float: right; - } -} - -.error-length { - float: right; - margin: 0; - [dir='rtl'] :host & { - float: left; - } -} - -.orcid-error { - margin-top: 20px !important; -} - -.input-container { - margin-bottom: 20px; - ::ng-deep { - mat-error { - margin-top: 8px !important; - font-size: 12px; - } - - mat-form-field { - padding-top: 8px; - - .mat-form-field-subscript-wrapper { - padding: 0; - } - - .mat-form-field-wrapper { - padding-bottom: 2px; - } - } - - .mat-form-field-appearance-outline { - .mat-form-field-wrapper { - margin: 0; - - .mat-form-field-outline { - top: 0px; - } - - .mat-form-field-prefix { - top: 0.35em; - - mat-icon { - margin-inline-end: 8px; - } - } - - .mat-form-field-flex { - .mat-form-field-infix { - border-top: 0px; - padding: 10px 0 10px 0; - } - } - } - } - - mat-form-field.mat-form-field.mat-primary.mat-form-field-type-mat-input.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-invalid { - margin-bottom: 0px; - } - } -} - -mat-label.orc-font-small-print { - font-weight: bold; - display: block; - margin-bottom: 4px; - - label { - font-weight: normal; - } -} +:host { + width: 100%; +} + +.mat-button-font { + margin: auto; +} + +.two-factor { + margin-top: 12px; +} + +.error-message { + float: left; + margin: 0; + [dir='rtl'] :host & { + float: right; + } +} + +.error-length { + float: right; + margin: 0; + [dir='rtl'] :host & { + float: left; + } +} + +.orcid-error { + margin-top: 20px !important; +} + +.input-container { + margin-bottom: 20px; + ::ng-deep { + mat-error { + margin-top: 8px !important; + font-size: 12px; + } + + mat-form-field { + padding-top: 8px; + + .mat-form-field-subscript-wrapper { + padding: 0; + } + + .mat-form-field-wrapper { + padding-bottom: 2px; + } + } + + .mat-form-field-appearance-outline { + .mat-form-field-wrapper { + margin: 0; + + .mat-form-field-outline { + top: 0px; + } + + .mat-form-field-prefix { + top: 0.35em; + + mat-icon { + margin-inline-end: 8px; + } + } + + .mat-form-field-flex { + .mat-form-field-infix { + border-top: 0px; + padding: 10px 0 10px 0; + } + } + } + } + + mat-form-field.mat-form-field.mat-primary.mat-form-field-type-mat-input.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-invalid { + margin-bottom: 0px; + } + } +} + +p.enter-code { + margin-top: 28px; +} + +mat-label.orc-font-small-print { + font-weight: bold; + display: block; + margin-bottom: 4px; + + label { + font-weight: normal; + } +} diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss index c2cb366e91..73a51f868f 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss @@ -1,15 +1,19 @@ -@use '@angular/material' as mat; -@import 'src/assets/scss/material.orcid-theme.scss'; - -@mixin two-factor-authentication-form-theme($theme) { - $primary: map-get($theme, primary); - $background: map-get($theme, background); - $foreground: map-get($theme, foreground); - - .authenticate-button { - color: $orcid-light-primary-text; - background: mat.get-color-from-palette($primary, 700); - } -} - -@include two-factor-authentication-form-theme($orcid-app-theme); +@use '@angular/material' as mat; +@import 'src/assets/scss/material.orcid-theme.scss'; + +@mixin two-factor-authentication-form-theme($theme) { + $primary: map-get($theme, primary); + $background: map-get($theme, background); + $foreground: map-get($theme, foreground); + + .authenticate-button { + color: $orcid-light-primary-text; + background: mat.get-color-from-palette($primary, 700); + } + + .error { + color: map-get($foreground, 'state-warning-dark'); + } +} + +@include two-factor-authentication-form-theme($orcid-app-theme); diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts index bdcdc952fc..4f7b7ffe45 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts @@ -1,122 +1,146 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, - ElementRef, - EventEmitter, - Inject, - Input, - Output, - ViewChild, -} from '@angular/core' -import { - UntypedFormControl, - UntypedFormGroup, - Validators, -} from '@angular/forms' -import { WINDOW } from '../../window' - -@Component({ - selector: 'app-two-factor-authentication-form', - templateUrl: './two-factor-authentication-form.component.html', - styleUrls: [ - './two-factor-authentication-form.component.scss', - './two-factor-authentication-form.component.scss-theme.scss', - ], - preserveWhitespaces: true, -}) -export class TwoFactorAuthenticationFormComponent implements AfterViewInit { - @Input() showBadVerificationCode: boolean - @Input() showBadRecoveryCode: boolean - @Input() signInUpdatesV1Togglz: boolean - @Output() authenticate = new EventEmitter<{ - verificationCode?: string - recoveryCode?: string - }>() - - @ViewChild('inputVerificationCode') - inputVerificationCode: ElementRef - @ViewChild('inputRecoveryCode') - inputRecoveryCode: ElementRef - - recoveryCode = false - - verificationFormControl = new UntypedFormControl('', [ - Validators.required, - Validators.minLength(6), - Validators.maxLength(6), - ]) - - recoveryCodeFormControl = new UntypedFormControl('', [ - Validators.required, - Validators.maxLength(10), - Validators.minLength(10), - ]) - - twoFactorForm = new UntypedFormGroup({ - verificationCode: this.verificationFormControl, - recoveryCode: this.recoveryCodeFormControl, - }) - - constructor( - private cdref: ChangeDetectorRef, - @Inject(WINDOW) private window: Window - ) {} - - ngAfterViewInit() { - this.inputVerificationCode.nativeElement.focus() - this.cdref.detectChanges() - } - - onSubmit() { - this.hideErrorMessages() - this.disableValidators() - - if (this.twoFactorForm.valid) { - this.authenticate.emit({ - verificationCode: this.twoFactorForm.value.verificationCode, - recoveryCode: this.twoFactorForm.value.recoveryCode, - }) - - this.enableValidators() - } - } - - disableValidators() { - if (!this.recoveryCode) { - this.recoveryCodeFormControl.disable() - } else { - this.verificationFormControl.disable() - } - } - - enableValidators() { - this.verificationFormControl.enable() - this.recoveryCodeFormControl.enable() - } - - showRecoveryCode() { - this.hideErrorMessages() - this.recoveryCode = true - setTimeout(() => { - this.inputRecoveryCode.nativeElement.focus() - }) - } - - showAuthenticationCode() { - this.hideErrorMessages() - this.recoveryCode = false - setTimeout(() => { - this.inputVerificationCode.nativeElement.focus() - }) - } - - hideErrorMessages() { - this.showBadRecoveryCode = false - this.showBadRecoveryCode = false - } - - navigateTo(val) { - this.window.location.href = val - } -} +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + EventEmitter, + Inject, + Input, + Output, + ViewChild, +} from '@angular/core' +import { + UntypedFormControl, + UntypedFormGroup, + Validators, +} from '@angular/forms' +import { WINDOW } from '../../window' + +@Component({ + selector: 'app-two-factor-authentication-form', + templateUrl: './two-factor-authentication-form.component.html', + styleUrls: [ + './two-factor-authentication-form.component.scss', + './two-factor-authentication-form.component.scss-theme.scss', + ], + preserveWhitespaces: true, +}) +export class TwoFactorAuthenticationFormComponent implements AfterViewInit { + @Input() showBadVerificationCode: boolean + @Input() showBadRecoveryCode: boolean + @Input() signInUpdatesV1Togglz: boolean + @Output() authenticate = new EventEmitter<{ + verificationCode?: string + recoveryCode?: string + }>() + + @ViewChild('inputVerificationCode') + inputVerificationCode: ElementRef + @ViewChild('inputRecoveryCode') + inputRecoveryCode: ElementRef + + recoveryCode = false + + twoFactorForm = new UntypedFormGroup({ + verificationCode: new UntypedFormControl('', [ + Validators.required, + Validators.minLength(6), + Validators.maxLength(6), + ]), + recoveryCode: new UntypedFormControl('', [ + Validators.required, + Validators.maxLength(10), + Validators.minLength(10), + ]), + }) + + get verificationFormControl() { + return this.twoFactorForm.controls.verificationCode + } + + get recoveryCodeFormControl() { + return this.twoFactorForm.controls.recoveryCode + } + + get verificationWasTouched() { + return this.verificationFormControl.dirty || this.verificationFormControl.touched + } + + get recoveryCodeWasTouched() { + return this.recoveryCodeFormControl.dirty || this.recoveryCodeFormControl.touched + } + + get isVerificationCodeInvalid() { + return (this.verificationWasTouched && this.verificationFormControl.hasError('required')) || + this.verificationFormControl.hasError('minlength') || + this.verificationFormControl.hasError('maxlength') + } + + get isRecoveryCodeInvalid() { + return (this. recoveryCodeWasTouched && this.verificationFormControl.hasError('required')) || + this.verificationFormControl.hasError('minlength') || + this.verificationFormControl.hasError('maxlength') + } + + constructor( + private cdref: ChangeDetectorRef, + @Inject(WINDOW) private window: Window + ) {} + + ngAfterViewInit() { + this.inputVerificationCode.nativeElement.focus() + this.cdref.detectChanges() + } + + onSubmit() { + this.hideErrorMessages() + this.disableValidators() + + if (this.twoFactorForm.valid) { + this.authenticate.emit({ + verificationCode: this.twoFactorForm.value.verificationCode, + recoveryCode: this.twoFactorForm.value.recoveryCode, + }) + + this.enableValidators() + } + } + + disableValidators() { + if (!this.recoveryCode) { + this.recoveryCodeFormControl.disable() + } else { + this.verificationFormControl.disable() + } + } + + enableValidators() { + this.verificationFormControl.enable() + this.recoveryCodeFormControl.enable() + } + + showRecoveryCode() { + this.hideErrorMessages() + this.recoveryCode = true + setTimeout(() => { + this.inputRecoveryCode.nativeElement.focus() + }) + } + + showAuthenticationCode() { + this.hideErrorMessages() + this.recoveryCode = false + setTimeout(() => { + this.inputVerificationCode.nativeElement.focus() + }) + } + + hideErrorMessages() { + this.showBadRecoveryCode = false + this.showBadRecoveryCode = false + } + + navigateTo(val) { + this.window.location.href = val + } +} diff --git a/src/app/sign-in/components/form-sign-in/form-sign-in.component.html b/src/app/sign-in/components/form-sign-in/form-sign-in.component.html index ffb043a98c..794a319ead 100644 --- a/src/app/sign-in/components/form-sign-in/form-sign-in.component.html +++ b/src/app/sign-in/components/form-sign-in/form-sign-in.component.html @@ -114,7 +114,7 @@ - Institutional - - Access through your institution - - - Sign in through your institution - - -
- - - -
-
- - - -
+ +
+ + + +
+
+ + + +
diff --git a/src/assets/vectors/institutional-access-no-background.svg b/src/assets/vectors/institutional-access-no-background.svg new file mode 100644 index 0000000000..261bea3b9f --- /dev/null +++ b/src/assets/vectors/institutional-access-no-background.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + From b313505010001f56d06774acbff6872b7e298267 Mon Sep 17 00:00:00 2001 From: amontenegro Date: Mon, 18 Mar 2024 20:33:27 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A4=96=20GITHUB=20ACTIONS=20format=5F?= =?UTF-8?q?prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form-authorize.component.html | 9 +- ...-factor-authentication-form.component.html | 574 +++++++++--------- ...-factor-authentication-form.component.scss | 192 +++--- ...hentication-form.component.scss-theme.scss | 38 +- ...wo-factor-authentication-form.component.ts | 302 ++++----- .../form-sign-in/form-sign-in.component.html | 7 +- .../components/social/social.component.html | 140 ++--- 7 files changed, 639 insertions(+), 623 deletions(-) diff --git a/src/app/authorize/components/form-authorize/form-authorize.component.html b/src/app/authorize/components/form-authorize/form-authorize.component.html index 6e6bd48607..f753ae9ae1 100644 --- a/src/app/authorize/components/form-authorize/form-authorize.component.html +++ b/src/app/authorize/components/form-authorize/form-authorize.component.html @@ -177,10 +177,11 @@

- profile icon + profile icon
diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html index 62a449b443..edf4e9003c 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.html @@ -1,285 +1,289 @@ -
-

- Two-factor authentication -

-
- Two-factor authentication code - - - - Two-factor authentication code - - - - {{ inputVerificationCode.value?.length || 0 }}/6 - -

- Authentication code is required -

-

- {{ inputVerificationCode.value?.length || 0 }}/6 -

-
- - -

- Invalid authentication code length -

-

- {{ inputVerificationCode.value?.length || 0 }}/6 -

-
-
-
- - {{ verificationFormControl.value?.length || 0 }}/6 - -

- Authentication code is required -

-

- {{ verificationFormControl.value?.length || 0 }}/6 -

-
- - -

- Invalid authentication code length -

-

- {{ verificationFormControl.value?.length || 0 }}/6 -

-
-
-
-

- Enter a code - - - from your two-factor authentication app - -

-

- - Don't have your device? - - Enter a recovery code - -

-

- - Don't have your device or recovery code? - - ORCID Help Center - -

-
- Recovery code - - - - Recovery code - - - - {{ inputRecoveryCode.value?.length || 0 }}/10 - -

- Recovery code is required -

-

- {{ inputRecoveryCode.value?.length || 0 }}/10 -

-
- - -

- Invalid recovery code length -

-

- {{ inputRecoveryCode.value?.length || 0 }}/10 -

-
-
-
- - {{ recoveryCodeFormControl.value?.length || 0 }}/10 - -

- Recovery code is required -

-

- {{ recoveryCodeFormControl.value?.length || 0 }}/10 -

-
- - -

- Invalid recovery code length -

-

- {{ recoveryCodeFormControl.value?.length || 0 }}/10 -

-
-
-
- - -
- - error - - Invalid authentication code - - - - error - - Invalid recovery code - - +
+

+ Two-factor authentication +

+
+ Two-factor authentication code + + + + Two-factor authentication code + + + + {{ inputVerificationCode.value?.length || 0 }}/6 + +

+ Authentication code is required +

+

+ {{ inputVerificationCode.value?.length || 0 }}/6 +

+
+ + +

+ Invalid authentication code length +

+

+ {{ inputVerificationCode.value?.length || 0 }}/6 +

+
+
+
+ + {{ verificationFormControl.value?.length || 0 }}/6 + +

+ Authentication code is required +

+

+ {{ verificationFormControl.value?.length || 0 }}/6 +

+
+ + +

+ Invalid authentication code length +

+

+ {{ verificationFormControl.value?.length || 0 }}/6 +

+
+
+
+

+ Enter a code + + + from your two-factor authentication app + +

+

+ + Don't have your device? + + Enter a recovery code + +

+

+ + Don't have your device or recovery code? + + ORCID Help Center + +

+
+ Recovery code + + + + Recovery code + + + + {{ inputRecoveryCode.value?.length || 0 }}/10 + +

+ Recovery code is required +

+

+ {{ inputRecoveryCode.value?.length || 0 }}/10 +

+
+ + +

+ Invalid recovery code length +

+

+ {{ inputRecoveryCode.value?.length || 0 }}/10 +

+
+
+
+ + {{ recoveryCodeFormControl.value?.length || 0 }}/10 + +

+ Recovery code is required +

+

+ {{ recoveryCodeFormControl.value?.length || 0 }}/10 +

+
+ + +

+ Invalid recovery code length +

+

+ {{ recoveryCodeFormControl.value?.length || 0 }}/10 +

+
+
+
+ + +
+ + error + + Invalid authentication code + + + + error + + Invalid recovery code + + diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss index 9ef870a7b2..9e9c321fc6 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss @@ -1,96 +1,96 @@ -:host { - width: 100%; -} - -.mat-button-font { - margin: auto; -} - -.two-factor { - margin-top: 12px; -} - -.error-message { - float: left; - margin: 0; - [dir='rtl'] :host & { - float: right; - } -} - -.error-length { - float: right; - margin: 0; - [dir='rtl'] :host & { - float: left; - } -} - -.orcid-error { - margin-top: 20px !important; -} - -.input-container { - margin-bottom: 20px; - ::ng-deep { - mat-error { - margin-top: 8px !important; - font-size: 12px; - } - - mat-form-field { - padding-top: 8px; - - .mat-form-field-subscript-wrapper { - padding: 0; - } - - .mat-form-field-wrapper { - padding-bottom: 2px; - } - } - - .mat-form-field-appearance-outline { - .mat-form-field-wrapper { - margin: 0; - - .mat-form-field-outline { - top: 0px; - } - - .mat-form-field-prefix { - top: 0.35em; - - mat-icon { - margin-inline-end: 8px; - } - } - - .mat-form-field-flex { - .mat-form-field-infix { - border-top: 0px; - padding: 10px 0 10px 0; - } - } - } - } - - mat-form-field.mat-form-field.mat-primary.mat-form-field-type-mat-input.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-invalid { - margin-bottom: 0px; - } - } -} - -p.enter-code { - margin-top: 28px; -} - -mat-label.orc-font-small-print { - font-weight: bold; - display: block; - margin-bottom: 4px; - - label { - font-weight: normal; - } -} +:host { + width: 100%; +} + +.mat-button-font { + margin: auto; +} + +.two-factor { + margin-top: 12px; +} + +.error-message { + float: left; + margin: 0; + [dir='rtl'] :host & { + float: right; + } +} + +.error-length { + float: right; + margin: 0; + [dir='rtl'] :host & { + float: left; + } +} + +.orcid-error { + margin-top: 20px !important; +} + +.input-container { + margin-bottom: 20px; + ::ng-deep { + mat-error { + margin-top: 8px !important; + font-size: 12px; + } + + mat-form-field { + padding-top: 8px; + + .mat-form-field-subscript-wrapper { + padding: 0; + } + + .mat-form-field-wrapper { + padding-bottom: 2px; + } + } + + .mat-form-field-appearance-outline { + .mat-form-field-wrapper { + margin: 0; + + .mat-form-field-outline { + top: 0px; + } + + .mat-form-field-prefix { + top: 0.35em; + + mat-icon { + margin-inline-end: 8px; + } + } + + .mat-form-field-flex { + .mat-form-field-infix { + border-top: 0px; + padding: 10px 0 10px 0; + } + } + } + } + + mat-form-field.mat-form-field.mat-primary.mat-form-field-type-mat-input.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-invalid { + margin-bottom: 0px; + } + } +} + +p.enter-code { + margin-top: 28px; +} + +mat-label.orc-font-small-print { + font-weight: bold; + display: block; + margin-bottom: 4px; + + label { + font-weight: normal; + } +} diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss index 73a51f868f..d50c78394b 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.scss-theme.scss @@ -1,19 +1,19 @@ -@use '@angular/material' as mat; -@import 'src/assets/scss/material.orcid-theme.scss'; - -@mixin two-factor-authentication-form-theme($theme) { - $primary: map-get($theme, primary); - $background: map-get($theme, background); - $foreground: map-get($theme, foreground); - - .authenticate-button { - color: $orcid-light-primary-text; - background: mat.get-color-from-palette($primary, 700); - } - - .error { - color: map-get($foreground, 'state-warning-dark'); - } -} - -@include two-factor-authentication-form-theme($orcid-app-theme); +@use '@angular/material' as mat; +@import 'src/assets/scss/material.orcid-theme.scss'; + +@mixin two-factor-authentication-form-theme($theme) { + $primary: map-get($theme, primary); + $background: map-get($theme, background); + $foreground: map-get($theme, foreground); + + .authenticate-button { + color: $orcid-light-primary-text; + background: mat.get-color-from-palette($primary, 700); + } + + .error { + color: map-get($foreground, 'state-warning-dark'); + } +} + +@include two-factor-authentication-form-theme($orcid-app-theme); diff --git a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts index 4f7b7ffe45..0c4fc22f25 100644 --- a/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts +++ b/src/app/cdk/two-factor-authentication-form/two-factor/two-factor-authentication-form.component.ts @@ -1,146 +1,156 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, - ElementRef, - EventEmitter, - Inject, - Input, - Output, - ViewChild, -} from '@angular/core' -import { - UntypedFormControl, - UntypedFormGroup, - Validators, -} from '@angular/forms' -import { WINDOW } from '../../window' - -@Component({ - selector: 'app-two-factor-authentication-form', - templateUrl: './two-factor-authentication-form.component.html', - styleUrls: [ - './two-factor-authentication-form.component.scss', - './two-factor-authentication-form.component.scss-theme.scss', - ], - preserveWhitespaces: true, -}) -export class TwoFactorAuthenticationFormComponent implements AfterViewInit { - @Input() showBadVerificationCode: boolean - @Input() showBadRecoveryCode: boolean - @Input() signInUpdatesV1Togglz: boolean - @Output() authenticate = new EventEmitter<{ - verificationCode?: string - recoveryCode?: string - }>() - - @ViewChild('inputVerificationCode') - inputVerificationCode: ElementRef - @ViewChild('inputRecoveryCode') - inputRecoveryCode: ElementRef - - recoveryCode = false - - twoFactorForm = new UntypedFormGroup({ - verificationCode: new UntypedFormControl('', [ - Validators.required, - Validators.minLength(6), - Validators.maxLength(6), - ]), - recoveryCode: new UntypedFormControl('', [ - Validators.required, - Validators.maxLength(10), - Validators.minLength(10), - ]), - }) - - get verificationFormControl() { - return this.twoFactorForm.controls.verificationCode - } - - get recoveryCodeFormControl() { - return this.twoFactorForm.controls.recoveryCode - } - - get verificationWasTouched() { - return this.verificationFormControl.dirty || this.verificationFormControl.touched - } - - get recoveryCodeWasTouched() { - return this.recoveryCodeFormControl.dirty || this.recoveryCodeFormControl.touched - } - - get isVerificationCodeInvalid() { - return (this.verificationWasTouched && this.verificationFormControl.hasError('required')) || - this.verificationFormControl.hasError('minlength') || - this.verificationFormControl.hasError('maxlength') - } - - get isRecoveryCodeInvalid() { - return (this. recoveryCodeWasTouched && this.verificationFormControl.hasError('required')) || - this.verificationFormControl.hasError('minlength') || - this.verificationFormControl.hasError('maxlength') - } - - constructor( - private cdref: ChangeDetectorRef, - @Inject(WINDOW) private window: Window - ) {} - - ngAfterViewInit() { - this.inputVerificationCode.nativeElement.focus() - this.cdref.detectChanges() - } - - onSubmit() { - this.hideErrorMessages() - this.disableValidators() - - if (this.twoFactorForm.valid) { - this.authenticate.emit({ - verificationCode: this.twoFactorForm.value.verificationCode, - recoveryCode: this.twoFactorForm.value.recoveryCode, - }) - - this.enableValidators() - } - } - - disableValidators() { - if (!this.recoveryCode) { - this.recoveryCodeFormControl.disable() - } else { - this.verificationFormControl.disable() - } - } - - enableValidators() { - this.verificationFormControl.enable() - this.recoveryCodeFormControl.enable() - } - - showRecoveryCode() { - this.hideErrorMessages() - this.recoveryCode = true - setTimeout(() => { - this.inputRecoveryCode.nativeElement.focus() - }) - } - - showAuthenticationCode() { - this.hideErrorMessages() - this.recoveryCode = false - setTimeout(() => { - this.inputVerificationCode.nativeElement.focus() - }) - } - - hideErrorMessages() { - this.showBadRecoveryCode = false - this.showBadRecoveryCode = false - } - - navigateTo(val) { - this.window.location.href = val - } -} +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + EventEmitter, + Inject, + Input, + Output, + ViewChild, +} from '@angular/core' +import { + UntypedFormControl, + UntypedFormGroup, + Validators, +} from '@angular/forms' +import { WINDOW } from '../../window' + +@Component({ + selector: 'app-two-factor-authentication-form', + templateUrl: './two-factor-authentication-form.component.html', + styleUrls: [ + './two-factor-authentication-form.component.scss', + './two-factor-authentication-form.component.scss-theme.scss', + ], + preserveWhitespaces: true, +}) +export class TwoFactorAuthenticationFormComponent implements AfterViewInit { + @Input() showBadVerificationCode: boolean + @Input() showBadRecoveryCode: boolean + @Input() signInUpdatesV1Togglz: boolean + @Output() authenticate = new EventEmitter<{ + verificationCode?: string + recoveryCode?: string + }>() + + @ViewChild('inputVerificationCode') + inputVerificationCode: ElementRef + @ViewChild('inputRecoveryCode') + inputRecoveryCode: ElementRef + + recoveryCode = false + + twoFactorForm = new UntypedFormGroup({ + verificationCode: new UntypedFormControl('', [ + Validators.required, + Validators.minLength(6), + Validators.maxLength(6), + ]), + recoveryCode: new UntypedFormControl('', [ + Validators.required, + Validators.maxLength(10), + Validators.minLength(10), + ]), + }) + + get verificationFormControl() { + return this.twoFactorForm.controls.verificationCode + } + + get recoveryCodeFormControl() { + return this.twoFactorForm.controls.recoveryCode + } + + get verificationWasTouched() { + return ( + this.verificationFormControl.dirty || this.verificationFormControl.touched + ) + } + + get recoveryCodeWasTouched() { + return ( + this.recoveryCodeFormControl.dirty || this.recoveryCodeFormControl.touched + ) + } + + get isVerificationCodeInvalid() { + return ( + (this.verificationWasTouched && + this.verificationFormControl.hasError('required')) || + this.verificationFormControl.hasError('minlength') || + this.verificationFormControl.hasError('maxlength') + ) + } + + get isRecoveryCodeInvalid() { + return ( + (this.recoveryCodeWasTouched && + this.verificationFormControl.hasError('required')) || + this.verificationFormControl.hasError('minlength') || + this.verificationFormControl.hasError('maxlength') + ) + } + + constructor( + private cdref: ChangeDetectorRef, + @Inject(WINDOW) private window: Window + ) {} + + ngAfterViewInit() { + this.inputVerificationCode.nativeElement.focus() + this.cdref.detectChanges() + } + + onSubmit() { + this.hideErrorMessages() + this.disableValidators() + + if (this.twoFactorForm.valid) { + this.authenticate.emit({ + verificationCode: this.twoFactorForm.value.verificationCode, + recoveryCode: this.twoFactorForm.value.recoveryCode, + }) + + this.enableValidators() + } + } + + disableValidators() { + if (!this.recoveryCode) { + this.recoveryCodeFormControl.disable() + } else { + this.verificationFormControl.disable() + } + } + + enableValidators() { + this.verificationFormControl.enable() + this.recoveryCodeFormControl.enable() + } + + showRecoveryCode() { + this.hideErrorMessages() + this.recoveryCode = true + setTimeout(() => { + this.inputRecoveryCode.nativeElement.focus() + }) + } + + showAuthenticationCode() { + this.hideErrorMessages() + this.recoveryCode = false + setTimeout(() => { + this.inputVerificationCode.nativeElement.focus() + }) + } + + hideErrorMessages() { + this.showBadRecoveryCode = false + this.showBadRecoveryCode = false + } + + navigateTo(val) { + this.window.location.href = val + } +} diff --git a/src/app/sign-in/components/form-sign-in/form-sign-in.component.html b/src/app/sign-in/components/form-sign-in/form-sign-in.component.html index 794a319ead..520fddf023 100644 --- a/src/app/sign-in/components/form-sign-in/form-sign-in.component.html +++ b/src/app/sign-in/components/form-sign-in/form-sign-in.component.html @@ -62,8 +62,7 @@ - Institutional - - Access through your institution - - - Sign in through your institution - - -
- - - -
-
- - - -
+ +
+ + + +
+
+ + + +