mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 15:33:04 +00:00
[UXP-10] Code refactoring
This commit is contained in:
@@ -15,7 +15,8 @@ import {
|
|||||||
ActivationEnd,
|
ActivationEnd,
|
||||||
NavigationCancel,
|
NavigationCancel,
|
||||||
NavigationEnd,
|
NavigationEnd,
|
||||||
NavigationStart, ResolveEnd,
|
NavigationStart,
|
||||||
|
ResolveEnd,
|
||||||
Router,
|
Router,
|
||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
|
|
||||||
@@ -48,8 +49,7 @@ import { BASE_THEME_NAME } from './shared/theme-support/theme.constants';
|
|||||||
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
||||||
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||||
import { getDefaultThemeConfig } from '../config/config.util';
|
import { getDefaultThemeConfig } from '../config/config.util';
|
||||||
import { AppConfig, APP_CONFIG } from '../config/app-config.interface';
|
import { APP_CONFIG, AppConfig } from '../config/app-config.interface';
|
||||||
import { GoogleRecaptchaService } from './core/google-recaptcha/google-recaptcha.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-app',
|
selector: 'ds-app',
|
||||||
@@ -110,7 +110,6 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
private modalConfig: NgbModalConfig,
|
private modalConfig: NgbModalConfig,
|
||||||
@Optional() private cookiesService: KlaroService,
|
@Optional() private cookiesService: KlaroService,
|
||||||
@Optional() private googleAnalyticsService: GoogleAnalyticsService,
|
@Optional() private googleAnalyticsService: GoogleAnalyticsService,
|
||||||
@Optional() private googleRecaptchaService: GoogleRecaptchaService,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if (!isEqual(environment, this.appConfig)) {
|
if (!isEqual(environment, this.appConfig)) {
|
||||||
|
@@ -5,8 +5,8 @@ import { isNotEmpty } from '../../shared/empty.util';
|
|||||||
import { DOCUMENT } from '@angular/common';
|
import { DOCUMENT } from '@angular/common';
|
||||||
import { ConfigurationDataService } from '../data/configuration-data.service';
|
import { ConfigurationDataService } from '../data/configuration-data.service';
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, switchMap, take } from 'rxjs/operators';
|
||||||
import { combineLatest, Observable, of } from 'rxjs';
|
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
|
||||||
import { CookieService } from '../services/cookie.service';
|
import { CookieService } from '../services/cookie.service';
|
||||||
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
||||||
|
|
||||||
@@ -20,25 +20,33 @@ export const CAPTCHA_NAME = 'google-recaptcha';
|
|||||||
export class GoogleRecaptchaService {
|
export class GoogleRecaptchaService {
|
||||||
|
|
||||||
private renderer: Renderer2;
|
private renderer: Renderer2;
|
||||||
/**
|
|
||||||
* A Google Recaptcha site key
|
|
||||||
*/
|
|
||||||
captchaSiteKeyStr: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Google Recaptcha site key
|
|
||||||
*/
|
|
||||||
captchaSiteKey$: Observable<string>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Google Recaptcha mode
|
|
||||||
*/
|
|
||||||
captchaMode$: Observable<string> = of('invisible');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Google Recaptcha version
|
* A Google Recaptcha version
|
||||||
*/
|
*/
|
||||||
captchaVersion$: Observable<string> = of('');
|
private captchaVersionSubject$ = new BehaviorSubject<string>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Google Recaptcha Key
|
||||||
|
*/
|
||||||
|
private captchaKeySubject$ = new BehaviorSubject<string>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Google Recaptcha mode
|
||||||
|
*/
|
||||||
|
private captchaModeSubject$ = new BehaviorSubject<string>(null);
|
||||||
|
|
||||||
|
captchaKey(): Observable<string> {
|
||||||
|
return this.captchaKeySubject$.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
captchaMode(): Observable<string> {
|
||||||
|
return this.captchaModeSubject$.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
captchaVersion(): Observable<string> {
|
||||||
|
return this.captchaVersionSubject$.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private cookieService: CookieService,
|
private cookieService: CookieService,
|
||||||
@@ -66,36 +74,46 @@ export class GoogleRecaptchaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadRecaptchaProperties() {
|
loadRecaptchaProperties() {
|
||||||
const recaptchaKey$ = this.configService.findByPropertyName('google.recaptcha.key.site').pipe(
|
const recaptchaKeyRD$ = this.configService.findByPropertyName('google.recaptcha.key.site').pipe(
|
||||||
take(1),
|
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
);
|
);
|
||||||
const recaptchaVersion$ = this.configService.findByPropertyName('google.recaptcha.version').pipe(
|
const recaptchaVersionRD$ = this.configService.findByPropertyName('google.recaptcha.version').pipe(
|
||||||
take(1),
|
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
);
|
);
|
||||||
const recaptchaMode$ = this.configService.findByPropertyName('google.recaptcha.mode').pipe(
|
const recaptchaModeRD$ = this.configService.findByPropertyName('google.recaptcha.mode').pipe(
|
||||||
take(1),
|
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
);
|
);
|
||||||
combineLatest(recaptchaVersion$, recaptchaMode$, recaptchaKey$).subscribe(([recaptchaVersion, recaptchaMode, recaptchaKey]) => {
|
combineLatest([recaptchaVersionRD$, recaptchaModeRD$, recaptchaKeyRD$]).subscribe(([recaptchaVersionRD, recaptchaModeRD, recaptchaKeyRD]) => {
|
||||||
if (this.cookieService.get('klaro-anonymous') && this.cookieService.get('klaro-anonymous')[CAPTCHA_NAME]) {
|
|
||||||
if (recaptchaKey.hasSucceeded && isNotEmpty(recaptchaKey?.payload?.values[0])) {
|
if (
|
||||||
this.captchaSiteKeyStr = recaptchaKey?.payload?.values[0];
|
this.cookieService.get('klaro-anonymous') && this.cookieService.get('klaro-anonymous')[CAPTCHA_NAME] &&
|
||||||
this.captchaSiteKey$ = of(recaptchaKey?.payload?.values[0]);
|
recaptchaKeyRD.hasSucceeded && recaptchaVersionRD.hasSucceeded &&
|
||||||
|
isNotEmpty(recaptchaVersionRD.payload?.values) && isNotEmpty(recaptchaKeyRD.payload?.values)
|
||||||
|
) {
|
||||||
|
const key = recaptchaKeyRD.payload?.values[0];
|
||||||
|
const version = recaptchaVersionRD.payload?.values[0];
|
||||||
|
this.captchaKeySubject$.next(key);
|
||||||
|
this.captchaVersionSubject$.next(version);
|
||||||
|
|
||||||
|
let captchaUrl;
|
||||||
|
switch (version) {
|
||||||
|
case 'v3':
|
||||||
|
if (recaptchaKeyRD.hasSucceeded && isNotEmpty(recaptchaKeyRD.payload?.values)) {
|
||||||
|
captchaUrl = this.buildCaptchaUrl(key);
|
||||||
|
this.captchaModeSubject$.next('invisible');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'v2':
|
||||||
|
if (recaptchaModeRD.hasSucceeded && isNotEmpty(recaptchaModeRD.payload?.values)) {
|
||||||
|
captchaUrl = 'https://www.google.com/recaptcha/api.js';
|
||||||
|
this.captchaModeSubject$.next(recaptchaModeRD.payload?.values[0]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO handle error
|
||||||
}
|
}
|
||||||
if (recaptchaVersion.hasSucceeded && isNotEmpty(recaptchaVersion?.payload?.values[0]) && recaptchaVersion?.payload?.values[0] === 'v3') {
|
if (captchaUrl) {
|
||||||
this.captchaVersion$ = of('v3');
|
this.loadScript(captchaUrl);
|
||||||
if (recaptchaKey.hasSucceeded && isNotEmpty(recaptchaKey?.payload?.values[0])) {
|
|
||||||
this.loadScript(this.buildCaptchaUrl(recaptchaKey?.payload?.values[0]));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.captchaVersion$ = of('v2');
|
|
||||||
const captchaUrl = 'https://www.google.com/recaptcha/api.js';
|
|
||||||
if (recaptchaMode.hasSucceeded && isNotEmpty(recaptchaMode?.payload?.values[0])) {
|
|
||||||
this.captchaMode$ = of(recaptchaMode?.payload?.values[0]);
|
|
||||||
this.loadScript(captchaUrl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -105,23 +123,21 @@ export class GoogleRecaptchaService {
|
|||||||
* Returns an observable of string
|
* Returns an observable of string
|
||||||
* @param action action is the process type in which used to protect multiple spam REST calls
|
* @param action action is the process type in which used to protect multiple spam REST calls
|
||||||
*/
|
*/
|
||||||
public async getRecaptchaToken (action) {
|
public getRecaptchaToken(action) {
|
||||||
return await grecaptcha.execute(this.captchaSiteKeyStr, {action: action});
|
return this.captchaKey().pipe(
|
||||||
|
switchMap((key) => grecaptcha.execute(key, {action: action}))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an observable of string
|
* Returns an observable of string
|
||||||
*/
|
*/
|
||||||
public async executeRecaptcha () {
|
public executeRecaptcha() {
|
||||||
return await grecaptcha.execute();
|
return of(grecaptcha.execute());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public getRecaptchaTokenResponse () {
|
||||||
* Returns an observable of string
|
return grecaptcha.getResponse();
|
||||||
* @param action action is the process type in which used to protect multiple spam REST calls
|
|
||||||
*/
|
|
||||||
public async getRecaptchaTokenResponse () {
|
|
||||||
return await grecaptcha.getResponse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,8 +24,8 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
{{MESSAGE_PREFIX + '.email.hint' |translate}}
|
{{MESSAGE_PREFIX + '.email.hint' |translate}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12" *ngIf="(googleRecaptchaService.captchaVersion$ | async) === 'v2'">
|
<div class="col-12" *ngIf="(googleRecaptchaService.captchaVersion() | async) === 'v2'">
|
||||||
<ds-google-recaptcha [captchaMode]="(googleRecaptchaService.captchaMode$ | async)" (executeRecaptcha)="register($event)"></ds-google-recaptcha>
|
<ds-google-recaptcha [captchaMode]="(googleRecaptchaService.captchaMode() | async)" (executeRecaptcha)="register($event)"></ds-google-recaptcha>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -33,14 +33,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<button *ngIf="(googleRecaptchaService.captchaVersion$ | async) === 'v2' && (googleRecaptchaService.captchaMode$ | async) === 'invisible'"
|
<button *ngIf="(googleRecaptchaService.captchaVersion() | async) === 'v2' && (googleRecaptchaService.captchaMode() | async) === 'invisible'"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
[disabled]="form.invalid"
|
[disabled]="form.invalid"
|
||||||
(click)="executeRecaptcha()">
|
(click)="executeRecaptcha()">
|
||||||
{{MESSAGE_PREFIX + '.submit'| translate}}</button>
|
{{ MESSAGE_PREFIX + '.submit' | translate }}</button>
|
||||||
<button *ngIf="!((googleRecaptchaService.captchaVersion$ | async) === 'v2' && (googleRecaptchaService.captchaMode$ | async) === 'invisible')"
|
<button *ngIf="!((googleRecaptchaService.captchaVersion() | async) === 'v2' && (googleRecaptchaService.captchaMode() | async) === 'invisible')"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
[disabled]="form.invalid"
|
[disabled]="form.invalid"
|
||||||
(click)="register()">
|
(click)="register()">
|
||||||
{{MESSAGE_PREFIX + '.submit'| translate}}</button>
|
{{ MESSAGE_PREFIX + '.submit' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -7,12 +7,12 @@ import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'
|
|||||||
import { Registration } from '../core/shared/registration.model';
|
import { Registration } from '../core/shared/registration.model';
|
||||||
import { RemoteData } from '../core/data/remote-data';
|
import { RemoteData } from '../core/data/remote-data';
|
||||||
import { ConfigurationDataService } from '../core/data/configuration-data.service';
|
import { ConfigurationDataService } from '../core/data/configuration-data.service';
|
||||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../core/shared/operators';
|
import { getFirstSucceededRemoteDataPayload } from '../core/shared/operators';
|
||||||
import { ConfigurationProperty } from '../core/shared/configuration-property.model';
|
import { ConfigurationProperty } from '../core/shared/configuration-property.model';
|
||||||
import { isNotEmpty } from '../shared/empty.util';
|
import { isNotEmpty } from '../shared/empty.util';
|
||||||
|
import { combineLatest, Observable, of, switchMap } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { GoogleRecaptchaService } from '../core/google-recaptcha/google-recaptcha.service';
|
import { GoogleRecaptchaService } from '../core/google-recaptcha/google-recaptcha.service';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-register-email-form',
|
selector: 'ds-register-email-form',
|
||||||
@@ -39,9 +39,16 @@ export class RegisterEmailFormComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
registrationVerification = false;
|
registrationVerification = false;
|
||||||
|
|
||||||
recaptchaKey$: Observable<any>;
|
captchaVersion(): Observable<string> {
|
||||||
|
return this.googleRecaptchaService.captchaVersion();
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
captchaMode(): Observable<string> {
|
||||||
|
return this.googleRecaptchaService.captchaMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
private epersonRegistrationService: EpersonRegistrationService,
|
private epersonRegistrationService: EpersonRegistrationService,
|
||||||
private notificationService: NotificationsService,
|
private notificationService: NotificationsService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
@@ -61,14 +68,9 @@ export class RegisterEmailFormComponent implements OnInit {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
this.recaptchaKey$ = this.configService.findByPropertyName('google.recaptcha.key.site').pipe(
|
|
||||||
getFirstSucceededRemoteDataPayload(),
|
|
||||||
);
|
|
||||||
this.configService.findByPropertyName('registration.verification.enabled').pipe(
|
this.configService.findByPropertyName('registration.verification.enabled').pipe(
|
||||||
getFirstCompletedRemoteData(),
|
getFirstSucceededRemoteDataPayload(),
|
||||||
map((res: RemoteData<ConfigurationProperty>) => {
|
map((res: ConfigurationProperty) => res?.values[0].toLowerCase() === 'true')
|
||||||
return res.hasSucceeded && res.payload && isNotEmpty(res.payload.values) && res.payload.values[0].toLowerCase() === 'true';
|
|
||||||
})
|
|
||||||
).subscribe((res: boolean) => {
|
).subscribe((res: boolean) => {
|
||||||
this.registrationVerification = res;
|
this.registrationVerification = res;
|
||||||
});
|
});
|
||||||
@@ -77,38 +79,36 @@ export class RegisterEmailFormComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* execute the captcha function for v2 invisible
|
* execute the captcha function for v2 invisible
|
||||||
*/
|
*/
|
||||||
async executeRecaptcha() {
|
executeRecaptcha() {
|
||||||
await this.googleRecaptchaService.executeRecaptcha();
|
console.log('executeRecaptcha');
|
||||||
|
this.googleRecaptchaService.executeRecaptcha();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an email address
|
* Register an email address
|
||||||
*/
|
*/
|
||||||
async register(tokenV2 = null) {
|
register(tokenV2 = null) {
|
||||||
if (!this.form.invalid) {
|
if (!this.form.invalid) {
|
||||||
if (this.registrationVerification) {
|
if (this.registrationVerification) {
|
||||||
let token;
|
combineLatest([this.captchaVersion(), this.captchaMode()]).pipe(
|
||||||
let captchaVersion;
|
switchMap(([captchaVersion, captchaMode]) => {
|
||||||
let captchaMode;
|
if (captchaVersion === 'v3') {
|
||||||
this.googleRecaptchaService.captchaVersion$.subscribe(res => {
|
return this.googleRecaptchaService.getRecaptchaToken('register_email');
|
||||||
captchaVersion = res;
|
} else if (captchaMode === 'checkbox') {
|
||||||
});
|
return this.googleRecaptchaService.getRecaptchaTokenResponse();
|
||||||
this.googleRecaptchaService.captchaMode$.subscribe(res => {
|
} else {
|
||||||
captchaMode = res;
|
return of(tokenV2);
|
||||||
});
|
}
|
||||||
if (captchaVersion === 'v3') {
|
}),
|
||||||
token = await this.googleRecaptchaService.getRecaptchaToken('register_email');
|
).subscribe((token) => {
|
||||||
} else if (captchaMode === 'checkbox') {
|
if (isNotEmpty(token)) {
|
||||||
token = await this.googleRecaptchaService.getRecaptchaTokenResponse();
|
this.registration(token);
|
||||||
} else {
|
} else {
|
||||||
token = tokenV2;
|
this.notificationService.error(this.translateService.get(`${this.MESSAGE_PREFIX}.error.head`),
|
||||||
}
|
this.translateService.get(`${this.MESSAGE_PREFIX}.error.recaptcha`));
|
||||||
if (isNotEmpty(token)) {
|
}
|
||||||
this.registration(token);
|
}
|
||||||
} else {
|
);
|
||||||
this.notificationService.error(this.translateService.get(`${this.MESSAGE_PREFIX}.error.head`),
|
|
||||||
this.translateService.get(`${this.MESSAGE_PREFIX}.error.recaptcha`));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.registration();
|
this.registration();
|
||||||
}
|
}
|
||||||
@@ -119,12 +119,9 @@ export class RegisterEmailFormComponent implements OnInit {
|
|||||||
* Registration of an email address
|
* Registration of an email address
|
||||||
*/
|
*/
|
||||||
registration(captchaToken = null) {
|
registration(captchaToken = null) {
|
||||||
let registerEmail$;
|
let registerEmail$ = captchaToken ?
|
||||||
if (captchaToken) {
|
this.epersonRegistrationService.registerEmail(this.email.value, captchaToken) :
|
||||||
registerEmail$ = this.epersonRegistrationService.registerEmail(this.email.value, captchaToken);
|
this.epersonRegistrationService.registerEmail(this.email.value);
|
||||||
} else {
|
|
||||||
registerEmail$ = this.epersonRegistrationService.registerEmail(this.email.value);
|
|
||||||
}
|
|
||||||
registerEmail$.subscribe((response: RemoteData<Registration>) => {
|
registerEmail$.subscribe((response: RemoteData<Registration>) => {
|
||||||
if (response.hasSucceeded) {
|
if (response.hasSucceeded) {
|
||||||
this.notificationService.success(this.translateService.get(`${this.MESSAGE_PREFIX}.success.head`),
|
this.notificationService.success(this.translateService.get(`${this.MESSAGE_PREFIX}.success.head`),
|
||||||
|
Reference in New Issue
Block a user