From fcad492a25a5f31492a3d36e54d7da180deae95a Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 7 Jul 2022 14:38:10 +0530 Subject: [PATCH] [UXP-10] token passing in header --- .../data/eperson-registration.service.spec.ts | 19 ++++++++++++- .../core/data/eperson-registration.service.ts | 14 +++++++--- .../google-recaptcha.service.ts | 28 ++++++++++++++----- src/app/core/shared/registration.model.ts | 5 ---- .../register-email-form.component.ts | 8 +++--- 5 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/app/core/data/eperson-registration.service.spec.ts b/src/app/core/data/eperson-registration.service.spec.ts index dc13fff3a0..c7785302ef 100644 --- a/src/app/core/data/eperson-registration.service.spec.ts +++ b/src/app/core/data/eperson-registration.service.spec.ts @@ -9,6 +9,8 @@ import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils import { of as observableOf } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { RequestEntry } from './request-entry.model'; +import { HttpHeaders } from '@angular/common/http'; +import { HttpOptions } from '../dspace-rest/dspace-rest.service'; describe('EpersonRegistrationService', () => { let testScheduler; @@ -79,8 +81,23 @@ describe('EpersonRegistrationService', () => { it('should send an email registration', () => { const expected = service.registerEmail('test@mail.org'); + let headers = new HttpHeaders(); + const options: HttpOptions = Object.create({}); + options.headers = headers; - expect(requestService.send).toHaveBeenCalledWith(new PostRequest('request-id', 'rest-url/registrations', registration)); + expect(requestService.send).toHaveBeenCalledWith(new PostRequest('request-id', 'rest-url/registrations', registration, options)); + expect(expected).toBeObservable(cold('(a|)', { a: rd })); + }); + + it('should send an email registration with captcha', () => { + + const expected = service.registerEmail('test@mail.org', 'afreshcaptchatoken'); + let headers = new HttpHeaders(); + const options: HttpOptions = Object.create({}); + headers = headers.append('X-Recaptcha-Token', 'afreshcaptchatoken'); + options.headers = headers; + + expect(requestService.send).toHaveBeenCalledWith(new PostRequest('request-id', 'rest-url/registrations', registration, options)); expect(expected).toBeObservable(cold('(a|)', { a: rd })); }); }); diff --git a/src/app/core/data/eperson-registration.service.ts b/src/app/core/data/eperson-registration.service.ts index b667d87e04..6f64879e0b 100644 --- a/src/app/core/data/eperson-registration.service.ts +++ b/src/app/core/data/eperson-registration.service.ts @@ -12,6 +12,8 @@ import { GenericConstructor } from '../shared/generic-constructor'; import { RegistrationResponseParsingService } from './registration-response-parsing.service'; import { RemoteData } from './remote-data'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { HttpOptions } from '../dspace-rest/dspace-rest.service'; +import { HttpHeaders } from '@angular/common/http'; @Injectable( { @@ -57,18 +59,22 @@ export class EpersonRegistrationService { registerEmail(email: string, captchaToken: string = null): Observable> { const registration = new Registration(); registration.email = email; - if (captchaToken) { - registration.captchaToken = captchaToken; - } const requestId = this.requestService.generateRequestId(); const href$ = this.getRegistrationEndpoint(); + const options: HttpOptions = Object.create({}); + let headers = new HttpHeaders(); + if (captchaToken) { + headers = headers.append('X-Recaptcha-Token', captchaToken); + } + options.headers = headers; + href$.pipe( find((href: string) => hasValue(href)), map((href: string) => { - const request = new PostRequest(requestId, href, registration); + const request = new PostRequest(requestId, href, registration, options); this.requestService.send(request); }) ).subscribe(); diff --git a/src/app/core/google-recaptcha/google-recaptcha.service.ts b/src/app/core/google-recaptcha/google-recaptcha.service.ts index 168e385597..46611e5ebb 100644 --- a/src/app/core/google-recaptcha/google-recaptcha.service.ts +++ b/src/app/core/google-recaptcha/google-recaptcha.service.ts @@ -5,6 +5,8 @@ import { isNotEmpty } from '../../shared/empty.util'; import { DOCUMENT } from '@angular/common'; import { ConfigurationDataService } from '../data/configuration-data.service'; import { RemoteData } from '../data/remote-data'; +import { map } from 'rxjs/operators'; +import { combineLatest } from 'rxjs'; /** * A GoogleRecaptchaService used to send action and get a token from REST @@ -13,6 +15,9 @@ import { RemoteData } from '../data/remote-data'; export class GoogleRecaptchaService { private renderer: Renderer2; + /** + * A Google Recaptcha site key + */ captchaSiteKey: string; constructor( @@ -21,12 +26,21 @@ export class GoogleRecaptchaService { private configService: ConfigurationDataService, ) { this.renderer = rendererFactory.createRenderer(null, null); - this.configService.findByPropertyName('google.recaptcha.key').pipe( + const registrationVerification$ = this.configService.findByPropertyName('registration.verification.enabled').pipe( getFirstCompletedRemoteData(), - ).subscribe((res: RemoteData) => { - if (res.hasSucceeded && isNotEmpty(res?.payload?.values[0])) { - this.captchaSiteKey = res?.payload?.values[0]; - this.loadScript(this.buildCaptchaUrl(res?.payload?.values[0])); + map((res: RemoteData) => { + return res.hasSucceeded && res.payload && isNotEmpty(res.payload.values) && res.payload.values[0].toLowerCase() === 'true'; + }) + ); + const recaptchaKey$ = this.configService.findByPropertyName('google.recaptcha.key.site').pipe( + getFirstCompletedRemoteData(), + ); + combineLatest(registrationVerification$, recaptchaKey$).subscribe(([registrationVerification, recaptchaKey]) => { + if (registrationVerification) { + if (recaptchaKey.hasSucceeded && isNotEmpty(recaptchaKey?.payload?.values[0])) { + this.captchaSiteKey = recaptchaKey?.payload?.values[0]; + this.loadScript(this.buildCaptchaUrl(recaptchaKey?.payload?.values[0])); + } } }); } @@ -45,7 +59,7 @@ export class GoogleRecaptchaService { * @param key contains a secret key of a google captchas * @returns string which has google captcha url with google captchas key */ - buildCaptchaUrl(key: string) { + buildCaptchaUrl(key: string) { return `https://www.google.com/recaptcha/api.js?render=${key}`; } @@ -55,7 +69,7 @@ export class GoogleRecaptchaService { * @param url contains a script url which will be loaded into page * @returns A promise */ - private loadScript(url) { + private loadScript(url) { return new Promise((resolve, reject) => { const script = this.renderer.createElement('script'); script.type = 'text/javascript'; diff --git a/src/app/core/shared/registration.model.ts b/src/app/core/shared/registration.model.ts index 8521bb126e..bc4488964f 100644 --- a/src/app/core/shared/registration.model.ts +++ b/src/app/core/shared/registration.model.ts @@ -33,9 +33,4 @@ export class Registration implements UnCacheableObject { * The token linked to the registration */ groups: string[]; - - /** - * The captcha token linked to the registration - */ - captchaToken: string; } diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index c53fbd993d..04081dc7ff 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -76,21 +76,21 @@ export class RegisterEmailFormComponent implements OnInit { if (this.registrationVerification) { const token = await this.googleRecaptchaService.getRecaptchaToken('register_email'); if (isNotEmpty(token)) { - this.registeration(token); + this.registration(token); } else { this.notificationService.error(this.translateService.get(`${this.MESSAGE_PREFIX}.error.head`), this.translateService.get(`${this.MESSAGE_PREFIX}.error.recaptcha`, {email: this.email.value})); } } else { - this.registeration(); + this.registration(); } } } /** - * Register an email address + * Registration of an email address */ - registeration(captchaToken = null) { + registration(captchaToken = null) { let registerEmail$; if (captchaToken) { registerEmail$ = this.epersonRegistrationService.registerEmail(this.email.value, captchaToken);