From 4de5ab0f563a2090d28f03852b0322b6043b6305 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 27 Jun 2022 13:47:19 +0200 Subject: [PATCH 1/4] 92701: Disable user agreement feature --- ...-user-agreement-current-user.guard.spec.ts | 20 +++++++++ .../end-user-agreement-current-user.guard.ts | 7 ++- src/app/info/info-routing.module.ts | 44 ++++++++++++------- src/config/global-config.interface.ts | 2 + src/config/info-config.interface.ts | 6 +++ src/environments/environment.common.ts | 4 ++ src/environments/mock-environment.ts | 4 ++ 7 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 src/config/info-config.interface.ts diff --git a/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts b/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts index 75b8f6089e..b280ef798c 100644 --- a/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts +++ b/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts @@ -2,6 +2,7 @@ import { EndUserAgreementCurrentUserGuard } from './end-user-agreement-current-u import { EndUserAgreementService } from './end-user-agreement.service'; import { Router, UrlTree } from '@angular/router'; import { of as observableOf } from 'rxjs'; +import { environment } from '../../../environments/mock-environment'; describe('EndUserAgreementGuard', () => { let guard: EndUserAgreementCurrentUserGuard; @@ -44,5 +45,24 @@ describe('EndUserAgreementGuard', () => { }); }); }); + + describe('when the end user agreement is disabled', () => { + it('should return true', (done) => { + environment.info.enableEndUserAgreement = false; + guard.canActivate(undefined, Object.assign({ url: 'redirect' })).subscribe((result) => { + console.log(result); + expect(result).toEqual(true); + done(); + }); + }); + + it('should not resolve to the end user agreement page', (done) => { + environment.info.enableEndUserAgreement = false; + guard.canActivate(undefined, Object.assign({ url: 'redirect' })).subscribe((result) => { + expect(router.navigateByUrl).not.toHaveBeenCalled(); + done(); + }); + }); + }); }); }); diff --git a/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.ts b/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.ts index 2c04186f34..a79e12cc32 100644 --- a/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.ts +++ b/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.ts @@ -1,8 +1,9 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Observable, of as observableOf } from 'rxjs'; import { AbstractEndUserAgreementGuard } from './abstract-end-user-agreement.guard'; import { EndUserAgreementService } from './end-user-agreement.service'; import { Router } from '@angular/router'; +import { environment } from '../../../environments/environment'; /** * A guard redirecting logged in users to the end agreement page when they haven't accepted the latest user agreement @@ -19,6 +20,10 @@ export class EndUserAgreementCurrentUserGuard extends AbstractEndUserAgreementGu * True when the currently logged in user has accepted the agreements or when the user is not currently authenticated */ hasAccepted(): Observable { + if (!environment.info.enableEndUserAgreement) { + return observableOf(true); + } + return this.endUserAgreementService.hasCurrentUserAcceptedAgreement(true); } diff --git a/src/app/info/info-routing.module.ts b/src/app/info/info-routing.module.ts index f76fb47ff0..e15ae521b2 100644 --- a/src/app/info/info-routing.module.ts +++ b/src/app/info/info-routing.module.ts @@ -4,25 +4,37 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso import { PRIVACY_PATH, END_USER_AGREEMENT_PATH } from './info-routing-paths'; import { ThemedEndUserAgreementComponent } from './end-user-agreement/themed-end-user-agreement.component'; import { ThemedPrivacyComponent } from './privacy/themed-privacy.component'; +import { environment } from '../../environments/environment'; + + +const imports = []; + + if (environment.info.enableEndUserAgreement) { + imports.push( + RouterModule.forChild([ + { + path: END_USER_AGREEMENT_PATH, + component: ThemedEndUserAgreementComponent, + resolve: { breadcrumb: I18nBreadcrumbResolver }, + data: { title: 'info.end-user-agreement.title', breadcrumbKey: 'info.end-user-agreement' } + } + ])); + } + if (environment.info.enablePrivacyStatement) { + imports.push( + RouterModule.forChild([ + { + path: PRIVACY_PATH, + component: ThemedPrivacyComponent, + resolve: { breadcrumb: I18nBreadcrumbResolver }, + data: { title: 'info.privacy.title', breadcrumbKey: 'info.privacy' } + } + ])); + } @NgModule({ imports: [ - RouterModule.forChild([ - { - path: END_USER_AGREEMENT_PATH, - component: ThemedEndUserAgreementComponent, - resolve: { breadcrumb: I18nBreadcrumbResolver }, - data: { title: 'info.end-user-agreement.title', breadcrumbKey: 'info.end-user-agreement' } - } - ]), - RouterModule.forChild([ - { - path: PRIVACY_PATH, - component: ThemedPrivacyComponent, - resolve: { breadcrumb: I18nBreadcrumbResolver }, - data: { title: 'info.privacy.title', breadcrumbKey: 'info.privacy' } - } - ]) + ...imports ] }) /** diff --git a/src/config/global-config.interface.ts b/src/config/global-config.interface.ts index d46822eb61..8218682d8a 100644 --- a/src/config/global-config.interface.ts +++ b/src/config/global-config.interface.ts @@ -13,6 +13,7 @@ import { ThemeConfig } from './theme.model'; import { AuthConfig } from './auth-config.interfaces'; import { UIServerConfig } from './ui-server-config.interface'; import { MediaViewerConfig } from './media-viewer-config.interface'; +import { InfoConfig } from './info-config.interface'; export interface GlobalConfig extends Config { ui: UIServerConfig; @@ -32,4 +33,5 @@ export interface GlobalConfig extends Config { collection: CollectionPageConfig; themes: ThemeConfig[]; mediaViewer: MediaViewerConfig; + info: InfoConfig; } diff --git a/src/config/info-config.interface.ts b/src/config/info-config.interface.ts new file mode 100644 index 0000000000..b1831962b5 --- /dev/null +++ b/src/config/info-config.interface.ts @@ -0,0 +1,6 @@ +import { Config } from './config.interface'; + +export interface InfoConfig extends Config { + enableEndUserAgreement: boolean; + enablePrivacyStatement: boolean; +} diff --git a/src/environments/environment.common.ts b/src/environments/environment.common.ts index 9091773041..2570759151 100644 --- a/src/environments/environment.common.ts +++ b/src/environments/environment.common.ts @@ -285,4 +285,8 @@ export const environment: GlobalConfig = { image: false, video: false, }, + info: { + enableEndUserAgreement: false, + enablePrivacyStatement: false + }, }; diff --git a/src/environments/mock-environment.ts b/src/environments/mock-environment.ts index 824c8c8a83..a5fa44b115 100644 --- a/src/environments/mock-environment.ts +++ b/src/environments/mock-environment.ts @@ -235,4 +235,8 @@ export const environment: Partial = { image: true, video: true }, + info: { + enableEndUserAgreement: true, + enablePrivacyStatement: true, + } }; From 1b5c801d0665f0c9fa39c3b63e45dfa01d4e59d2 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 27 Jun 2022 16:24:16 +0200 Subject: [PATCH 2/4] 92701: Disable user agreement feature --- config/config.example.yml | 7 +++++++ config/config.yml | 4 ++++ .../end-user-agreement-current-user.guard.spec.ts | 2 +- src/config/default-app-config.ts | 7 ++++--- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/config/config.example.yml b/config/config.example.yml index 898b47784f..723568c020 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -246,3 +246,10 @@ bundle: mediaViewer: image: false video: false + +# Whether the end user agreement is required before users use the repository. +# If enabled, the user will be required to accept the agreement before they can use the repository. +# And whether the privacy statement should exist or not. +info: + enableEndUserAgreement: true + enablePrivacyStatement: true diff --git a/config/config.yml b/config/config.yml index b5eecd112f..2b5ac3b52e 100644 --- a/config/config.yml +++ b/config/config.yml @@ -3,3 +3,7 @@ rest: host: api7.dspace.org port: 443 nameSpace: /server + +info: + enableEndUserAgreement: true + enablePrivacyStatement: true diff --git a/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts b/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts index b280ef798c..40728ab601 100644 --- a/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts +++ b/src/app/core/end-user-agreement/end-user-agreement-current-user.guard.spec.ts @@ -2,7 +2,7 @@ import { EndUserAgreementCurrentUserGuard } from './end-user-agreement-current-u import { EndUserAgreementService } from './end-user-agreement.service'; import { Router, UrlTree } from '@angular/router'; import { of as observableOf } from 'rxjs'; -import { environment } from '../../../environments/mock-environment'; +import { environment } from '../../../environments/environment.test'; describe('EndUserAgreementGuard', () => { let guard: EndUserAgreementCurrentUserGuard; diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 886f1598fd..4108444443 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -16,6 +16,7 @@ import { ThemeConfig } from './theme.model'; import { UIServerConfig } from './ui-server-config.interface'; import { BundleConfig } from './bundle-config.interface'; import { ActuatorsConfig } from './actuators.config'; +import { InfoConfig } from './info-config.interface'; export class DefaultAppConfig implements AppConfig { production = false; @@ -324,8 +325,8 @@ export class DefaultAppConfig implements AppConfig { image: false, video: false }; - info: { - enableEndUserAgreement: false, - enablePrivacyStatement: false + info: InfoConfig = { + enableEndUserAgreement: true, + enablePrivacyStatement: true }; } From f2e977c402a299735d3c646db3d8e7264a163973 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Wed, 3 Aug 2022 15:15:45 +0200 Subject: [PATCH 3/4] 92701: Redirect / dead link fixes --- config/config.yml | 4 ++-- .../end-user-agreement/abstract-end-user-agreement.guard.ts | 6 +++++- src/app/footer/footer.component.html | 4 ++-- src/app/footer/footer.component.ts | 3 +++ src/app/shared/cookies/browser-klaro.service.ts | 4 ++++ 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/config/config.yml b/config/config.yml index 2b5ac3b52e..8b1966b100 100644 --- a/config/config.yml +++ b/config/config.yml @@ -5,5 +5,5 @@ rest: nameSpace: /server info: - enableEndUserAgreement: true - enablePrivacyStatement: true + enableEndUserAgreement: false + enablePrivacyStatement: false diff --git a/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts b/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts index b9f134f946..076df8ebc9 100644 --- a/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts +++ b/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts @@ -1,6 +1,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; -import { Observable } from 'rxjs'; +import { Observable, of as observableOf } from 'rxjs'; import { returnEndUserAgreementUrlTreeOnFalse } from '../shared/authorized.operators'; +import { environment } from '../../../environments/environment'; /** * An abstract guard for redirecting users to the user agreement page if a certain condition is met @@ -18,6 +19,9 @@ export abstract class AbstractEndUserAgreementGuard implements CanActivate { * when they're finished accepting the agreement */ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + if (!environment.info.enableEndUserAgreement) { + return observableOf(true); + } return this.hasAccepted().pipe( returnEndUserAgreementUrlTreeOnFalse(this.router, state.url) ); diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index 2c1a34ccae..88236d381e 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -67,11 +67,11 @@ {{ 'footer.link.cookies' | translate}} -
  • +
  • {{ 'footer.link.privacy-policy' | translate}}
  • -
  • +
  • {{ 'footer.link.end-user-agreement' | translate}}
  • diff --git a/src/app/footer/footer.component.ts b/src/app/footer/footer.component.ts index c43a0ae85d..c4195c8eb3 100644 --- a/src/app/footer/footer.component.ts +++ b/src/app/footer/footer.component.ts @@ -1,6 +1,7 @@ import { Component, Optional } from '@angular/core'; import { hasValue } from '../shared/empty.util'; import { KlaroService } from '../shared/cookies/klaro.service'; +import { environment } from '../../environments/environment'; @Component({ selector: 'ds-footer', @@ -14,6 +15,8 @@ export class FooterComponent { * A boolean representing if to show or not the top footer container */ showTopFooter = false; + showPrivacyPolicy = environment.info.enablePrivacyStatement; + showEndUserAgreement = environment.info.enableEndUserAgreement; constructor(@Optional() private cookies: KlaroService) { } diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index 4e6370f179..e65b7c8b86 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -91,6 +91,10 @@ export class BrowserKlaroService extends KlaroService { Klaro.setup(this.klaroConfig); }); + if (!environment.info.enablePrivacyStatement) { + delete this.klaroConfig.privacyPolicy; + } + } /** From 4dcf6a345a0ddb749234c301978f7a9beb754480 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Fri, 5 Aug 2022 13:12:52 +0200 Subject: [PATCH 4/4] 92701: Fix privacy string for klaro and add documentation --- config/config.yml | 4 ---- src/app/shared/cookies/browser-klaro.service.ts | 10 +++++----- src/assets/i18n/en.json5 | 2 ++ src/config/default-app-config.ts | 8 ++++++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/config/config.yml b/config/config.yml index 8b1966b100..b5eecd112f 100644 --- a/config/config.yml +++ b/config/config.yml @@ -3,7 +3,3 @@ rest: host: api7.dspace.org port: 443 nameSpace: /server - -info: - enableEndUserAgreement: false - enablePrivacyStatement: false diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index e65b7c8b86..638d465864 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -63,6 +63,11 @@ export class BrowserKlaroService extends KlaroService { * - Add and translate klaro configuration messages */ initialize() { + if (!environment.info.enablePrivacyStatement) { + delete this.klaroConfig.privacyPolicy; + this.klaroConfig.translations.en.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; + } + this.translateService.setDefaultLang(environment.defaultLanguage); const user$: Observable = this.getUser$(); @@ -90,11 +95,6 @@ export class BrowserKlaroService extends KlaroService { this.translateConfiguration(); Klaro.setup(this.klaroConfig); }); - - if (!environment.info.enablePrivacyStatement) { - delete this.klaroConfig.privacyPolicy; - } - } /** diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 5d7be2a681..bf2d37fbf9 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1225,6 +1225,8 @@ "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
    To learn more, please read our {privacyPolicy}.", + "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.", + "cookies.consent.content-notice.learnMore": "Customize", "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 4108444443..11761af49a 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -325,6 +325,14 @@ export class DefaultAppConfig implements AppConfig { image: false, video: false }; + // Whether the end-user-agreement and privacy policy feature should be enabled or not. + // Disabling the end user agreement feature will result in: + // - Users no longer being forced to accept the end-user-agreement before they can access the repository + // - A 404 page if you manually try to navigate to the end-user-agreement page at info/end-user-agreement + // - All end-user-agreement related links and pages will be removed from the UI (e.g. in the footer) + // Disabling the privacy policy feature will result in: + // - A 404 page if you manually try to navigate to the privacy policy page at info/privacy + // - All mentions of the privacy policy being removed from the UI (e.g. in the footer) info: InfoConfig = { enableEndUserAgreement: true, enablePrivacyStatement: true