Skip to content

Commit

Permalink
Merge pull request #2094 from ORCID/feature/register2
Browse files Browse the repository at this point in the history
Feature/register2
  • Loading branch information
leomendoza123 authored Nov 27, 2023
2 parents fe329a5 + c583bb7 commit a347303
Show file tree
Hide file tree
Showing 88 changed files with 4,743 additions and 27 deletions.
13 changes: 9 additions & 4 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router'
import { LoadChildrenCallback, RouterModule, Routes } from '@angular/router'

import {
ApplicationRoutes,
Expand All @@ -17,6 +17,7 @@ import { LanguageGuard } from './guards/language.guard'
import { ThirdPartySigninCompletedGuard } from './guards/third-party-signin-completed.guard'
import { TwoFactorSigninGuard } from './guards/two-factor-signin.guard'
import { AuthenticatedNoDelegatorGuard } from './guards/authenticated-no-delagator.guard'
import { RegisterTogglGuard } from './guards/register-toggl.guard'

const routes: Routes = [
{
Expand Down Expand Up @@ -89,9 +90,13 @@ const routes: Routes = [
},
{
path: ApplicationRoutes.register,
canMatch: [RegisterTogglGuard],
canActivateChild: [LanguageGuard, RegisterGuard],
loadChildren: () =>
import('./register/register.module').then((m) => m.RegisterModule),
loadChildren: () => {
return localStorage.getItem('REGISTRATION_2_0') !== 'enable'
? import('./register/register.module').then((m) => m.RegisterModuleLegacy)
: import('./register2/register.module').then((m) => m.Register2Module)
},
},
{
path: ApplicationRoutes.search,
Expand Down Expand Up @@ -151,7 +156,7 @@ const routes: Routes = [
matcher: routerReactivation,
canActivateChild: [LanguageGuard, RegisterGuard],
loadChildren: () =>
import('./register/register.module').then((m) => m.RegisterModule),
import('./register/register.module').then((m) => m.RegisterModuleLegacy),
},
{
path: ApplicationRoutes.selfService,
Expand Down
15 changes: 7 additions & 8 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ import { Component, HostBinding, HostListener, Inject } from '@angular/core'
import { NavigationEnd, NavigationStart, Router } from '@angular/router'
import { catchError, tap } from 'rxjs/operators'

import {
finishPerformanceMeasurement,
reportNavigationStart,
} from './analytics-utils'
import { PlatformInfo } from './cdk/platform-info'
import { PlatformInfoService } from './cdk/platform-info/platform-info.service'
import { WINDOW } from './cdk/window'
import { HeadlessOnOauthRoutes } from './constants'
import { UserService } from './core'
import { ZendeskService } from './core/zendesk/zendesk.service'
import { GoogleTagManagerService } from './core/google-tag-manager/google-tag-manager.service'
import {
finishPerformanceMeasurement,
reportNavigationStart,
} from './analytics-utils'
import { ERROR_REPORT } from './errors'
import { ErrorHandlerService } from './core/error-handler/error-handler.service'
import { environment } from 'src/environments/environment'
import { GoogleTagManagerService } from './core/google-tag-manager/google-tag-manager.service'
import { TitleService } from './core/title-service/title.service'
import { ZendeskService } from './core/zendesk/zendesk.service'
import { ERROR_REPORT } from './errors'

@Component({
selector: 'app-root',
Expand Down
2 changes: 1 addition & 1 deletion src/app/core/oauth/oauth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class OauthService {
.post<RequestInfoForm>(
environment.BASE_URL + 'oauth/custom/authorize.json',
value,
{ headers: this.headers }
{ headers: this.headers, withCredentials: true }
)
.pipe(
retry(3),
Expand Down
253 changes: 253 additions & 0 deletions src/app/core/register2/register2.backend-validators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
import { HttpClient } from '@angular/common/http'
import {
AbstractControl,
AsyncValidatorFn,
UntypedFormGroup,
ValidationErrors,
} from '@angular/forms'
import { Observable, of } from 'rxjs'
import { catchError, map, retry } from 'rxjs/operators'
import { Constructor } from 'src/app/types'
import { RegisterForm } from 'src/app/types/register.endpoint'
import { environment } from 'src/environments/environment'
import { ErrorHandlerService } from '../error-handler/error-handler.service'

interface HasHttpClientAndErrorHandler {
_http: HttpClient
_errorHandler: ErrorHandlerService
}

interface HasFormAdapters {
formGroupToEmailRegisterForm(formGroup: UntypedFormGroup): RegisterForm
formGroupToPasswordRegisterForm(formGroup: UntypedFormGroup): RegisterForm
formGroupToFullRegistrationForm(
StepA: UntypedFormGroup,
StepB: UntypedFormGroup,
StepC: UntypedFormGroup,
StepD: UntypedFormGroup
): RegisterForm
}

export function Register2BackendValidatorMixin<
T extends Constructor<HasHttpClientAndErrorHandler & HasFormAdapters>
>(base: T) {
return class RegisterBackendValidator extends base {
constructor(...args: any[]) {
super(...args)
}
formInputs = {
givenNames: {
validationEndpoint: 'validateGivenNames',
},
familyNames: {
validationEndpoint: 'validateFamilyNames',
},
email: {
validationEndpoint: 'validateEmail',
},
emailsAdditional: {
validationEndpoint: 'validateEmailsAdditional',
},
passwordConfirm: {
validationEndpoint: 'validatePasswordConfirm',
},
password: {
validationEndpoint: 'validatePassword',
},
}

validateRegisterValue(
controlName: string,
value: RegisterForm
): Observable<RegisterForm> {
return this._http
.post<RegisterForm>(
environment.API_WEB +
`oauth/custom/register/${this.formInputs[controlName].validationEndpoint}.json`,
value
)
.pipe(
retry(3),
catchError((error) => this._errorHandler.handleError(error))
)
}

validateAdditionalEmailsReactivation(
value: RegisterForm
): Observable<RegisterForm> {
return this._http
.post(
`${environment.API_WEB}reactivateAdditionalEmailsValidate.json`,
value
)
.pipe(
retry(3),
catchError((error) => this._errorHandler.handleError(error))
)
}

backendValueValidate(
controlName: 'givenNames' | 'familyNames' | 'email' | 'password'
): AsyncValidatorFn {
return (
control: AbstractControl
): Observable<ValidationErrors | null> => {
if (control.value === '') {
return of(null)
}
const value = {}
value[controlName] = { value: control.value }

return this.validateRegisterValue(controlName, value).pipe(
map((res) => {
if (res[controlName].errors && res[controlName].errors.length > 0) {
const error = {
backendError: res[controlName].errors,
}
return error
}
return null
})
)
}
}

backendAdditionalEmailsValidate(reactivate: boolean): AsyncValidatorFn {
return (
formGroup: UntypedFormGroup
): Observable<ValidationErrors | null> => {
const value: RegisterForm = this.formGroupToEmailRegisterForm(formGroup)
if (!value.emailsAdditional || value.emailsAdditional.length === 0) {
return of(null)
}

if (reactivate) {
return this.validateAdditionalEmailsReactivation(value).pipe(
map((response) => {
// Add errors to additional emails controls
return this.setFormGroupEmailErrors(response, 'backendErrors')
})
)
}

return this.validateRegisterValue('emailsAdditional', value).pipe(
map((response) => {
// Add errors to additional emails controls
return this.setFormGroupEmailErrors(response, 'backendErrors')
})
)
}
}

backendPasswordValidate(): AsyncValidatorFn {
return (
formGroup: UntypedFormGroup
): Observable<ValidationErrors | null> => {
const value: RegisterForm =
this.formGroupToPasswordRegisterForm(formGroup)
if (value.password.value === '' || value.passwordConfirm.value === '') {
return of(null)
}
return this.validateRegisterValue('password', value).pipe(
map((response) => {
// Add errors to additional emails controls
return this.setFormGroupPasswordErrors(response, 'backendErrors')
})
)
}
}

backendRegisterFormValidate(
StepA: UntypedFormGroup,
StepB: UntypedFormGroup,
StepC: UntypedFormGroup,
StepD: UntypedFormGroup,

type?: 'shibboleth'
): Observable<RegisterForm> {
const registerForm = this.formGroupToFullRegistrationForm(
StepA,
StepB,
StepC,
StepD
)
return this._http
.post<RegisterForm>(`${environment.API_WEB}register.json`, registerForm)
.pipe(
retry(3),
catchError((error) => this._errorHandler.handleError(error))
)
}

public setFormGroupEmailErrors(
registerForm: RegisterForm,
errorGroup: string
) {
let hasErrors = false
const error = {}
error[errorGroup] = {
additionalEmails: {},
email: [],
}

registerForm.emailsAdditional.forEach((responseControl) => {
if (responseControl.errors && responseControl.errors.length > 0) {
hasErrors = true
error[errorGroup]['additionalEmails'][responseControl.value] =
responseControl.errors
}
})

if (
registerForm.email &&
registerForm.email.errors &&
registerForm.email.errors.length > 0
) {
hasErrors = true
error[errorGroup]['email'].push({
value: registerForm.email.value,
errors: registerForm.email.errors,
})
}

return hasErrors ? error : null
}

public setFormGroupPasswordErrors(
registerForm: RegisterForm,
errorGroup: string
) {
let hasErrors = false
const error = {}
error[errorGroup] = {
password: [],
passwordConfirm: [],
}

if (
registerForm.password &&
registerForm.password.errors &&
registerForm.password.errors.length > 0
) {
hasErrors = true
error[errorGroup]['password'].push({
value: registerForm.email.value,
errors: registerForm.email.errors,
})
}
if (
registerForm.passwordConfirm &&
registerForm.passwordConfirm.errors &&
registerForm.passwordConfirm.errors.length > 0
) {
hasErrors = true
error[errorGroup]['passwordConfirm'].push({
value: registerForm.passwordConfirm.value,
errors: registerForm.passwordConfirm.errors,
})
}

return hasErrors ? error : null
}
}
}
Loading

0 comments on commit a347303

Please sign in to comment.