Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions SUPPORTED_BROWSERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
| ---------------- | --------------- |
| Android WebView | 145 or newer |
| Apple Safari | 17 or newer |
| Google Chrome | 117 or newer |
| Microsoft Edge | 117 or newer |
| Mozilla Firefox | 116 or newer |
| Opera | 103 or newer |
| Google Chrome | 119 or newer |
| Microsoft Edge | 119 or newer |
| Mozilla Firefox | 119 or newer |
| Opera | 105 or newer |
| Opera Mobile | 80 or newer |
| Samsung Internet | 24 or newer |
| Samsung Internet | 25 or newer |
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
mat-raised-button
color="primary"
id="cy-two-factor-enable"
class="two-factor-panel__enable-button"
(click)="twoFactor()"
i18n="@@account.enableTwoFactorAuth"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
:host {
display: block;
width: 100%;
}

.two-factor-panel {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -78,3 +83,8 @@
border-color: var(--orcid-color-state-warning-dark, #d32f2f) !important;
color: #fff !important;
}

.two-factor-panel__enable-button {
align-self: flex-start;
width: auto;
}
10 changes: 5 additions & 5 deletions src/app/cdk/platform-info/supported-browsers.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"chrome": {
"major": 117,
"major": 119,
"minor": 0
},
"firefox": {
"major": 116,
"major": 119,
"minor": 0
},
"android": {
"major": 145,
"minor": 0
},
"edge": {
"major": 117,
"major": 119,
"minor": 0
},
"safari": {
Expand All @@ -24,11 +24,11 @@
"minor": 0
},
"opera": {
"major": 103,
"major": 105,
"minor": 0
},
"samsung": {
"major": 24,
"major": 25,
"minor": 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ export class ModalWebsitesComponent implements OnInit, OnDestroy {
websites: [],
visibility: this.originalBackendWebsites.visibility,
}
this._changeDetectorRef.detach()
this.websites.reverse()
this.websites
.map((value) => value.putCode)
Expand All @@ -178,15 +177,15 @@ export class ModalWebsitesComponent implements OnInit, OnDestroy {
}

saveEvent() {
if (this.isSavingWebsites) {
if (this.loadingWebsites || this.isSavingWebsites) {
return
}

this.isSavingWebsites = true
this.websitesForm.markAllAsTouched()
this.websitesForm.updateValueAndValidity()

if (this.websitesForm.valid) {
this.isSavingWebsites = true
this._recordWebsitesService
.postWebsites(this.formToBackend(this.websitesForm))
.pipe(
Expand All @@ -201,6 +200,7 @@ export class ModalWebsitesComponent implements OnInit, OnDestroy {
() => {}
)
} else {
this.isSavingWebsites = false
this._snackBar.showValidationError()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import { OauthService } from '../../../core/oauth/oauth.service'

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'
import { ReactiveFormsModule } from '@angular/forms'
import { Router } from '@angular/router'

describe('FormSignInComponent', () => {
let component: FormSignInComponent
let fixture: ComponentFixture<FormSignInComponent>
let router: Router

beforeEach(() => {
TestBed.configureTestingModule({
Expand Down Expand Up @@ -48,10 +50,25 @@ describe('FormSignInComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(FormSignInComponent)
component = fixture.componentInstance
router = TestBed.inject(Router)
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})

it('only triggers oauth redirect once per successful flow', () => {
component.isOauthAuthorizationTogglzEnable = false
component.platform = { social: false, institutional: false } as any
component.signInLocal = { params: {} } as any
const routerNavigateSpy = spyOn(router, 'navigate').and.returnValue(
Promise.resolve(true)
)

component.oauthAuthorize('https://qa.orcid.org/oauth/authorize')
component.oauthAuthorize('https://qa.orcid.org/oauth/authorize')

expect(routerNavigateSpy).toHaveBeenCalledTimes(1)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class FormSignInComponent implements OnInit, OnDestroy {
backendErrorsMatcher = new ErrorStateMatcherForPasswordField()
emailVerified: boolean
invalidVerifyUrl: boolean
private oauthRedirectTriggered = false

placeholderUsername = $localize`:@@ngOrcid.signin.username:Email or 16-digit ORCID iD`
placeholderPassword = $localize`:@@ngOrcid.signin.yourOrcidPassword:Your ORCID password`
Expand Down Expand Up @@ -386,9 +387,15 @@ export class FormSignInComponent implements OnInit, OnDestroy {
}

oauthAuthorize(urlRedirect) {
if (this.oauthRedirectTriggered) {
return
}
this.oauthRedirectTriggered = true

if (this.isOauthAuthorizationTogglzEnable) {
if (this._oauthUrlSessionManager.get()) {
urlRedirect = this._oauthUrlSessionManager.get()
const storedOauthRedirectUrl = this._oauthUrlSessionManager.get()
if (storedOauthRedirectUrl) {
urlRedirect = storedOauthRedirectUrl
this._oauthUrlSessionManager.clear()
}
//add http if not present
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@
type="button"
class="textarea-copy-action"
[cdkCopyToClipboard]="textCodeClipboard"
matTooltip="{{ textCodeCopiedTooltip }}"
#textCodeTooltip="matTooltip"
(click)="textCodeTooltip.toggle()"
matTooltip="{{ textCodeTooltip }}"
i18n-aria-label="@@account.copySetupCode"
aria-label="Copy setup code"
>
Expand Down Expand Up @@ -86,7 +84,7 @@
i18n="@@ngOrcid.signin.2fa.verificationCodeRequired"
class="error-message"
>
Authentication code is required
A verification code is required
</p>
<p class="error-length">
{{ inputVerificationCode.value?.length || 0 }}/6
Expand All @@ -103,7 +101,7 @@
i18n="@@ngOrcid.signin.2fa.badVerificationCodeLength"
class="error-message"
>
Invalid authentication code length
Invalid verification code length
</p>
<p class="error-length">
{{ inputVerificationCode.value?.length || 0 }}/6
Expand All @@ -117,7 +115,7 @@
i18n="@@ngOrcid.signin.2fa.badVerificationCode"
class="error-message"
>
Invalid authentication code
Invalid verification code
</p>
<p class="error-length">
{{ inputVerificationCode.value?.length || 0 }}/6
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ textarea.text-code {
}

mat-error {
display: block;
margin-top: var(--orcid-space-s, 8px);

p {
margin: 0 !important;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ describe('TwoFactorEnableComponent', () => {
})

it('should call register method when input is filled and submit is triggered', async () => {
component.twoFactorForm.get('verificationCode').setValue('123456')
component.twoFactorForm.get('verificationCode')?.setValue('123456')

fixture.detectChanges()
await fixture.whenStable()
Expand All @@ -132,4 +132,8 @@ describe('TwoFactorEnableComponent', () => {
component.twoFactorForm.get('verificationCode')?.hasError('invalidCode')
).toBeFalse()
})

it('should expose static setup code tooltip text', () => {
expect(component.textCodeTooltip).toBe('Copy setup code to clipboard')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class TwoFactorEnableComponent implements OnInit {
twoFactorForm: UntypedFormGroup
showTextCode = false
loading = false
textCodeCopiedTooltip = $localize`:@@account.setupCodeClipboard:Setup code has been copied to the clipboard`
textCodeTooltip = $localize`:@@account.copySetupCodeToClipboard:Copy setup code to clipboard`

constructor(
private _twoFactorService: TwoFactorAuthenticationService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
<div class="copy-block__intro">
<h4 i18n="@@account.yourRecoveryCodesTitle">Your 2FA recovery codes</h4>
<p i18n="@@account.recoveryCodes">
Recovery codes can be used to access your account when you can’t
receive 2FA codes (for example, if you lose your device). Each code
can only be used once.
Recovery codes can be used to access your ORCID account when you
aren’t able to use your authentication app. Each recovery code can
only be used once.
</p>
</div>
<a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,19 @@ describe('TwoFactorRecoveryCodesComponent', () => {

it('should only allow complete when copy/download and checkbox are done', () => {
expect(component.canCompleteSetup).toBeFalse()
expect(component.twoFactorForm.get('confirmCodes')?.disabled).toBeTrue()

component.markCodesCopied()
expect(component.twoFactorForm.get('confirmCodes')?.enabled).toBeTrue()
expect(component.canCompleteSetup).toBeFalse()

component.twoFactorForm.get('confirmCodes').setValue(true)
component.twoFactorForm.get('confirmCodes')?.setValue(true)
expect(component.canCompleteSetup).toBeTrue()
})

it('should record click and completion events when setup is completed', async () => {
component.markCodesCopied()
component.twoFactorForm.get('confirmCodes').setValue(true)
component.twoFactorForm.get('confirmCodes')?.setValue(true)

component.completeSetup()
await fixture.whenStable()
Expand All @@ -91,4 +93,10 @@ describe('TwoFactorRecoveryCodesComponent', () => {
)
expect(router.navigate).toHaveBeenCalled()
})

it('should enable confirm checkbox after downloading recovery codes', () => {
expect(component.twoFactorForm.get('confirmCodes')?.disabled).toBeTrue()
component.downloadRecoveryCodes()
expect(component.twoFactorForm.get('confirmCodes')?.enabled).toBeTrue()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export class TwoFactorRecoveryCodesComponent implements OnInit {

this.twoFactorForm = new UntypedFormGroup({
backupCodes: new UntypedFormControl(this.backupCodes, []),
confirmCodes: new UntypedFormControl(false, [Validators.requiredTrue]),
confirmCodes: new UntypedFormControl({ value: false, disabled: true }, [
Validators.requiredTrue,
]),
})
}

Expand All @@ -55,11 +57,11 @@ export class TwoFactorRecoveryCodesComponent implements OnInit {
this.window.document.body.appendChild(link)
link.click()
this.window.document.body.removeChild(link)
this.hasDownloadedOrCopied = true
this.enableConfirmation()
}

markCodesCopied() {
this.hasDownloadedOrCopied = true
this.enableConfirmation()
}

get canCompleteSetup() {
Expand All @@ -86,4 +88,9 @@ export class TwoFactorRecoveryCodesComponent implements OnInit {
}
})
}

private enableConfirmation() {
this.hasDownloadedOrCopied = true
this.twoFactorForm.get('confirmCodes')?.enable({ emitEvent: false })
}
}
Loading
Loading