forked from hazza/dspace-angular
added tests
This commit is contained in:
@@ -84,7 +84,6 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
// set the current language code
|
||||
this.localeService.setCurrentLanguageCode();
|
||||
|
||||
|
||||
angulartics2GoogleAnalytics.startTracking();
|
||||
angulartics2DSpace.startTracking();
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, find, first, map, mergeMap, switchMap, take } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, filter, find, first, map, mergeMap, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
|
||||
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
@@ -378,6 +378,14 @@ export abstract class DataService<T extends CacheableObject> implements UpdateDa
|
||||
);
|
||||
}
|
||||
|
||||
createPatchFromCache(object: T): Observable<Operation[]> {
|
||||
const oldVersion$ = this.findByHref(object._links.self.href);
|
||||
return oldVersion$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((oldVersion: T) => this.comparator.diff(oldVersion, object)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request for the specified object
|
||||
*
|
||||
@@ -406,18 +414,16 @@ export abstract class DataService<T extends CacheableObject> implements UpdateDa
|
||||
* @param {DSpaceObject} object The given object
|
||||
*/
|
||||
update(object: T): Observable<RemoteData<T>> {
|
||||
const oldVersion$ = this.findByHref(object._links.self.href);
|
||||
return oldVersion$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
mergeMap((oldVersion: T) => {
|
||||
const operations = this.comparator.diff(oldVersion, object);
|
||||
if (isNotEmpty(operations)) {
|
||||
this.objectCache.addPatch(object._links.self.href, operations);
|
||||
return this.createPatchFromCache(object)
|
||||
.pipe(
|
||||
mergeMap((operations: Operation[]) => {
|
||||
if (isNotEmpty(operations)) {
|
||||
this.objectCache.addPatch(object._links.self.href, operations);
|
||||
}
|
||||
return this.findByHref(object._links.self.href);
|
||||
}
|
||||
return this.findByHref(object._links.self.href);
|
||||
}
|
||||
));
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,12 +1,206 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BrowserKlaroService } from './browser-klaro.service';
|
||||
import { BrowserKlaroService, COOKIE_MDFIELD } from './browser-klaro.service';
|
||||
import { getMockTranslateService } from '../mocks/translate.service.mock';
|
||||
import { of as observableOf } from 'rxjs'
|
||||
import { RestResponse } from '../../core/cache/response.models';
|
||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
||||
import { AuthService } from '../../core/auth/auth.service';
|
||||
import { CookieService } from '../../core/services/cookie.service';
|
||||
import { getTestScheduler } from 'jasmine-marbles';
|
||||
import { MetadataValue } from '../../core/shared/metadata.models';
|
||||
import { cloneDeep } from 'lodash';
|
||||
|
||||
describe('KlaroService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
describe('BrowserKlaroService', () => {
|
||||
let translateService;
|
||||
let ePersonService;
|
||||
let authService;
|
||||
let cookieService;
|
||||
|
||||
let user;
|
||||
let service: BrowserKlaroService;
|
||||
|
||||
let mockConfig;
|
||||
let appName;
|
||||
let purpose;
|
||||
let testKey;
|
||||
|
||||
beforeEach(() => {
|
||||
user = new EPerson();
|
||||
|
||||
translateService = getMockTranslateService();
|
||||
ePersonService = jasmine.createSpyObj('ePersonService', {
|
||||
createPatchFromCache: observableOf([]),
|
||||
patch: observableOf(new RestResponse(true, 200, 'Ok'))
|
||||
});
|
||||
authService = jasmine.createSpyObj('authService', {
|
||||
isAuthenticated: observableOf(true),
|
||||
getAuthenticatedUserFromStore: observableOf(user)
|
||||
});
|
||||
cookieService = jasmine.createSpyObj('cookieService', {
|
||||
get: '{%22token_item%22:true%2C%22impersonation%22:true%2C%22redirect%22:true%2C%22language%22:true%2C%22klaro%22:true%2C%22has_agreed_end_user%22:true%2C%22google-analytics%22:true}',
|
||||
set: () => {
|
||||
/* empty */
|
||||
}
|
||||
});
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
BrowserKlaroService,
|
||||
{
|
||||
provide: TranslateService,
|
||||
useValue: translateService
|
||||
},
|
||||
{
|
||||
provide: EPersonDataService,
|
||||
useValue: ePersonService,
|
||||
},
|
||||
{
|
||||
provide: AuthService,
|
||||
useValue: authService
|
||||
},
|
||||
{
|
||||
provide: CookieService,
|
||||
useValue: cookieService
|
||||
}
|
||||
]
|
||||
});
|
||||
service = TestBed.get(BrowserKlaroService);
|
||||
appName = 'testName';
|
||||
purpose = 'test purpose';
|
||||
testKey = 'this.is.a.fake.message.key';
|
||||
|
||||
mockConfig = {
|
||||
translations: {
|
||||
en: {
|
||||
purposes: {},
|
||||
test: {
|
||||
testeritis: testKey
|
||||
}
|
||||
}
|
||||
},
|
||||
apps: [{
|
||||
name: appName,
|
||||
purposes: [purpose]
|
||||
}],
|
||||
|
||||
};
|
||||
|
||||
service.klaroConfig = mockConfig;
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
const service: BrowserKlaroService = TestBed.get(BrowserKlaroService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('addAppMessages', () => {
|
||||
service.addAppMessages();
|
||||
expect(mockConfig.translations.en[appName]).toBeDefined();
|
||||
expect(mockConfig.translations.en.purposes[purpose]).toBeDefined();
|
||||
});
|
||||
|
||||
it('translateConfiguration', () => {
|
||||
service.translateConfiguration();
|
||||
expect((service as any).translateService.instant).toHaveBeenCalledWith(testKey);
|
||||
});
|
||||
|
||||
describe('initializeUser when there is a metadata field value', () => {
|
||||
beforeEach(() => {
|
||||
user.setMetadata(COOKIE_MDFIELD, undefined, '{}');
|
||||
spyOn(service, 'restoreSettingsForUsers');
|
||||
});
|
||||
|
||||
it('initializeUser', () => {
|
||||
(service as any).initializeUser(user);
|
||||
expect(service.restoreSettingsForUsers).toHaveBeenCalledWith(user);
|
||||
});
|
||||
});
|
||||
|
||||
describe('initializeUser when there is no metadata field value but there is an anonymous cookie', () => {
|
||||
const cookie = '{test: \'testt\'}';
|
||||
beforeEach(() => {
|
||||
(service as any).cookieService.get.and.returnValue(cookie);
|
||||
spyOn(service, 'updateSettingsForUsers');
|
||||
});
|
||||
|
||||
it('initializeUser', () => {
|
||||
(service as any).initializeUser(user);
|
||||
expect((service as any).cookieService.set).toHaveBeenCalledWith(service.getStorageName(user.uuid), cookie)
|
||||
expect(service.updateSettingsForUsers).toHaveBeenCalledWith(user);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUser$ when there is no one authenticated', () => {
|
||||
beforeEach(() => {
|
||||
(service as any).authService.isAuthenticated.and.returnValue(observableOf(false));
|
||||
});
|
||||
it('should return undefined', () => {
|
||||
getTestScheduler().expectObservable((service as any).getUser$()).toBe('(a|)', { a: undefined });
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUser$ when there someone is authenticated', () => {
|
||||
beforeEach(() => {
|
||||
(service as any).authService.isAuthenticated.and.returnValue(observableOf(true));
|
||||
(service as any).authService.getAuthenticatedUserFromStore.and.returnValue(observableOf(user));
|
||||
});
|
||||
it('should return the user', () => {
|
||||
getTestScheduler().expectObservable((service as any).getUser$()).toBe('(a|)', { a: user });
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSettingsForUser', () => {
|
||||
const cookieConsentString = '{test: \'testt\'}';
|
||||
beforeEach(() => {
|
||||
user.metadata = {};
|
||||
user.metadata[COOKIE_MDFIELD] = [Object.assign(new MetadataValue(), { value: cookieConsentString })];
|
||||
spyOn(JSON, 'parse');
|
||||
});
|
||||
it('should return the cookie consents object', () => {
|
||||
service.getSettingsForUser(user);
|
||||
expect(JSON.parse).toHaveBeenCalledWith(cookieConsentString);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSettingsForUser when there are changes', () => {
|
||||
const cookieConsent = { test: 'testt' };
|
||||
const cookieConsentString = '{test: \'testt\'}';
|
||||
const operation = { op: 'add', path: 'metadata/dc.agreements.cookie', value: cookieConsentString };
|
||||
let updatedUser;
|
||||
|
||||
beforeEach(() => {
|
||||
updatedUser = cloneDeep(user);
|
||||
|
||||
spyOn(updatedUser, 'setMetadata');
|
||||
spyOn(JSON, 'stringify').and.returnValue(cookieConsentString);
|
||||
ePersonService.createPatchFromCache.and.returnValue(observableOf([operation]))
|
||||
});
|
||||
it('should call patch on the data service', () => {
|
||||
service.setSettingsForUser(updatedUser, cookieConsent);
|
||||
expect(updatedUser.setMetadata).toHaveBeenCalledWith(COOKIE_MDFIELD, undefined, cookieConsentString);
|
||||
expect(ePersonService.patch).toHaveBeenCalledWith(updatedUser, [operation])
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSettingsForUser when there are no changes', () => {
|
||||
const cookieConsent = { test: 'testt' };
|
||||
const cookieConsentString = '{test: \'testt\'}';
|
||||
let updatedUser;
|
||||
|
||||
beforeEach(() => {
|
||||
updatedUser = cloneDeep(user);
|
||||
|
||||
spyOn(updatedUser, 'setMetadata');
|
||||
spyOn(JSON, 'stringify').and.returnValue(cookieConsentString);
|
||||
ePersonService.createPatchFromCache.and.returnValue(observableOf([]))
|
||||
});
|
||||
it('should not call patch on the data service', () => {
|
||||
service.setSettingsForUser(updatedUser, cookieConsent);
|
||||
expect(updatedUser.setMetadata).toHaveBeenCalledWith(COOKIE_MDFIELD, undefined, cookieConsentString);
|
||||
expect(ePersonService.patch).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -1,191 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import * as Klaro from 'klaro'
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { TOKENITEM } from '../../core/auth/models/auth-token-info.model';
|
||||
import { AuthService, IMPERSONATING_COOKIE, REDIRECT_COOKIE } from '../../core/auth/auth.service';
|
||||
import { LANG_COOKIE } from '../../core/locale/locale.service';
|
||||
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
|
||||
import { AuthService } from '../../core/auth/auth.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { switchMap, take } from 'rxjs/operators';
|
||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||
import { of as observableOf, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { KlaroService } from './klaro.service';
|
||||
import { hasValue } from '../empty.util';
|
||||
import { hasValue, isNotEmpty } from '../empty.util';
|
||||
import { CookieService } from '../../core/services/cookie.service';
|
||||
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { klaroConfiguration } from './klaro-configuration';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
|
||||
export const HAS_AGREED_END_USER = 'dsHasAgreedEndUser';
|
||||
export const COOKIE_MDFIELD = 'dspace.agreements.cookies';
|
||||
export const ANONYMOUS_STORAGE_NAME_KLARO = 'klaro-anonymous';
|
||||
const cookieNameMessagePrefix = 'cookies.consent.app.title.';
|
||||
const cookieDescriptionMessagePrefix = 'cookies.consent.app.description.';
|
||||
const cookiePurposeMessagePrefix = 'cookies.consent.purpose.';
|
||||
|
||||
@Injectable()
|
||||
export class BrowserKlaroService extends KlaroService {
|
||||
|
||||
message$: BehaviorSubject<string> = new BehaviorSubject<string>('');
|
||||
|
||||
klaroConfig: any = {
|
||||
storageName: this.getStorageName('anonymous'),
|
||||
|
||||
privacyPolicy: '/info/privacy',
|
||||
|
||||
/*
|
||||
Setting 'hideLearnMore' to 'true' will hide the "learn more / customize" link in
|
||||
the consent notice. We strongly advise against using this under most
|
||||
circumstances, as it keeps the user from customizing his/her consent choices.
|
||||
*/
|
||||
hideLearnMore: false,
|
||||
|
||||
/*
|
||||
Setting 'acceptAll' to 'true' will show an "accept all" button in the notice and
|
||||
modal, which will enable all third-party apps if the user clicks on it. If set
|
||||
to 'false', there will be an "accept" button that will only enable the apps that
|
||||
are enabled in the consent modal.
|
||||
*/
|
||||
acceptAll: true,
|
||||
|
||||
/*
|
||||
You can also set a custom expiration time for the Klaro cookie. By default, it
|
||||
will expire after 30 days. Only relevant if 'storageMethod' is set to 'cookie'.
|
||||
*/
|
||||
cookieExpiresAfterDays: 365,
|
||||
|
||||
htmlTexts: true,
|
||||
|
||||
/*
|
||||
You can overwrite existing translations and add translations for your app
|
||||
descriptions and purposes. See `src/translations/` for a full list of
|
||||
translations that can be overwritten:
|
||||
https://github.com/KIProtect/klaro/tree/master/src/translations
|
||||
*/
|
||||
translations: {
|
||||
en: {
|
||||
acceptAll: 'cookies.consent.accept-all',
|
||||
acceptSelected: 'cookies.consent.accept-selected',
|
||||
app: {
|
||||
optOut: {
|
||||
description: 'cookies.consent.app.opt-out.description',
|
||||
title: 'cookies.consent.app.opt-out.title'
|
||||
},
|
||||
purpose: 'cookies.consent.app.purpose',
|
||||
purposes: 'cookies.consent.app.purposes',
|
||||
required: {
|
||||
description: 'cookies.consent.app.required.description',
|
||||
title: 'cookies.consent.app.required.title'
|
||||
}
|
||||
},
|
||||
close: 'cookies.consent.close',
|
||||
decline: 'cookies.consent.decline',
|
||||
consentNotice: {
|
||||
description: 'cookies.consent.content-notice.description',
|
||||
learnMore: 'cookies.consent.content-notice.learnMore'
|
||||
},
|
||||
consentModal: {
|
||||
description: 'cookies.consent.content-modal.description',
|
||||
privacyPolicy: {
|
||||
name: 'cookies.consent.content-modal.privacy-policy.name',
|
||||
text: 'cookies.consent.content-modal.privacy-policy.text'
|
||||
},
|
||||
title: 'cookies.consent.content-modal.title'
|
||||
},
|
||||
purposes: {}
|
||||
}
|
||||
},
|
||||
apps: [
|
||||
{
|
||||
name: 'token_item',
|
||||
purposes: ['authentication'],
|
||||
required: true,
|
||||
cookies: [
|
||||
TOKENITEM
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'impersonation',
|
||||
purposes: ['authentication'],
|
||||
required: true,
|
||||
cookies: [
|
||||
IMPERSONATING_COOKIE
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'redirect',
|
||||
purposes: ['authentication'],
|
||||
required: true,
|
||||
cookies: [
|
||||
REDIRECT_COOKIE
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'language',
|
||||
purposes: ['preferences'],
|
||||
required: true,
|
||||
cookies: [
|
||||
LANG_COOKIE
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'klaro',
|
||||
purposes: ['acknowledgement'],
|
||||
required: true,
|
||||
cookies: [
|
||||
[/^klaro-.+$/],
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'has_agreed_end_user',
|
||||
purposes: ['acknowledgement'],
|
||||
required: true,
|
||||
cookies: [
|
||||
HAS_AGREED_END_USER
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'google-analytics',
|
||||
purposes: ['statistics'],
|
||||
required: false,
|
||||
cookies: [
|
||||
// /*
|
||||
// you an either only provide a cookie name or regular expression (regex) or a list
|
||||
// consisting of a name or regex, a path and a cookie domain. Providing a path and
|
||||
// domain is necessary if you have apps that set cookies for a path that is not
|
||||
// "/", or a domain that is not the current domain. If you do not set these values
|
||||
// properly, the cookie can't be deleted by Klaro, as there is no way to access the
|
||||
// path or domain of a cookie in JS. Notice that it is not possible to delete
|
||||
// cookies that were set on a third-party domain, or cookies that have the HTTPOnly
|
||||
// attribute: https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#new-
|
||||
// cookie_domain
|
||||
// */
|
||||
//
|
||||
// /*
|
||||
// This rule will match cookies that contain the string '_pk_' and that are set on
|
||||
// the path '/' and the domain 'klaro.kiprotect.com'
|
||||
// */
|
||||
[/^_ga.?$/],
|
||||
[/^_gid$/],
|
||||
//
|
||||
// /*
|
||||
// Same as above, only for the 'localhost' domain
|
||||
// */
|
||||
// [/^_pk_.*$/, '/', 'localhost'],
|
||||
//
|
||||
// /*
|
||||
// This rule will match all cookies named 'piwik_ignore' that are set on the path
|
||||
// '/' on the current domain
|
||||
// */
|
||||
// 'piwik_ignore',
|
||||
],
|
||||
/*
|
||||
If 'onlyOnce' is set to 'true', the app will only be executed once regardless
|
||||
how often the user toggles it on and off. This is relevant e.g. for tracking
|
||||
scripts that would generate new page view events every time Klaro disables and
|
||||
re-enables them due to a consent change by the user.
|
||||
*/
|
||||
onlyOnce: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
klaroConfig = klaroConfiguration;
|
||||
|
||||
constructor(
|
||||
private translateService: TranslateService,
|
||||
@@ -196,39 +34,17 @@ export class BrowserKlaroService extends KlaroService {
|
||||
}
|
||||
|
||||
initialize() {
|
||||
|
||||
/**
|
||||
* Make sure the fallback language is english
|
||||
*/
|
||||
this.translateService.setDefaultLang(environment.defaultLanguage);
|
||||
|
||||
const user$: Observable<EPerson> = this.authService.isAuthenticated()
|
||||
.pipe(
|
||||
take(1),
|
||||
switchMap((loggedIn: boolean) => {
|
||||
console.log('loggedIn', loggedIn);
|
||||
if (loggedIn) {
|
||||
return this.authService.getAuthenticatedUserFromStore();
|
||||
}
|
||||
return observableOf(undefined);
|
||||
}),
|
||||
take(1)
|
||||
);
|
||||
const user$: Observable<EPerson> = this.getUser$();
|
||||
|
||||
const translationServiceReady$ = this.translateService.get('loading.default').pipe(take(1));
|
||||
|
||||
observableCombineLatest(user$, translationServiceReady$)
|
||||
.subscribe(([user, translation]: [EPerson, string]) => {
|
||||
user = cloneDeep(user);
|
||||
if (hasValue(user)) {
|
||||
this.klaroConfig.callback = (consent, app) => this.updateSettingsForUsers(user);
|
||||
this.klaroConfig.storageName = this.getStorageName(user.uuid);
|
||||
|
||||
const anonCookie = this.cookieService.get(this.getStorageName('anonymous'));
|
||||
if (hasValue(this.getSettingsForUser(user))) {
|
||||
this.restoreSettingsForUsers(user);
|
||||
} else if (hasValue(anonCookie)) {
|
||||
this.cookieService.set(this.getStorageName(user.uuid), anonCookie);
|
||||
}
|
||||
this.initializeUser(user);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,6 +64,33 @@ export class BrowserKlaroService extends KlaroService {
|
||||
|
||||
}
|
||||
|
||||
private initializeUser(user: EPerson) {
|
||||
this.klaroConfig.callback = (consent, app) => this.updateSettingsForUsers(user);
|
||||
this.klaroConfig.storageName = this.getStorageName(user.uuid);
|
||||
|
||||
const anonCookie = this.cookieService.get(ANONYMOUS_STORAGE_NAME_KLARO);
|
||||
if (hasValue(this.getSettingsForUser(user))) {
|
||||
this.restoreSettingsForUsers(user);
|
||||
} else if (hasValue(anonCookie)) {
|
||||
this.cookieService.set(this.getStorageName(user.uuid), anonCookie);
|
||||
this.updateSettingsForUsers(user);
|
||||
}
|
||||
}
|
||||
|
||||
private getUser$() {
|
||||
return this.authService.isAuthenticated()
|
||||
.pipe(
|
||||
take(1),
|
||||
switchMap((loggedIn: boolean) => {
|
||||
if (loggedIn) {
|
||||
return this.authService.getAuthenticatedUserFromStore();
|
||||
}
|
||||
return observableOf(undefined);
|
||||
}),
|
||||
take(1)
|
||||
);
|
||||
}
|
||||
|
||||
private getTitleTranslation(title: string) {
|
||||
return cookieNameMessagePrefix + title;
|
||||
}
|
||||
@@ -283,6 +126,11 @@ export class BrowserKlaroService extends KlaroService {
|
||||
* Translate the translation section from the Klaro configuration
|
||||
*/
|
||||
translateConfiguration() {
|
||||
/**
|
||||
* Make sure the fallback language is english
|
||||
*/
|
||||
this.translateService.setDefaultLang(environment.defaultLanguage);
|
||||
|
||||
this.translate(this.klaroConfig.translations.en);
|
||||
}
|
||||
|
||||
@@ -297,21 +145,30 @@ export class BrowserKlaroService extends KlaroService {
|
||||
}
|
||||
|
||||
getSettingsForUser(user: EPerson) {
|
||||
return JSON.parse(user.firstMetadataValue(COOKIE_MDFIELD));
|
||||
const mdValue = user.firstMetadataValue(COOKIE_MDFIELD);
|
||||
return hasValue(mdValue) ? JSON.parse(mdValue) : undefined;
|
||||
}
|
||||
|
||||
setSettingsForUser(user: EPerson, config: object) {
|
||||
user.setMetadata(COOKIE_MDFIELD, undefined, JSON.stringify(config));
|
||||
this.ePersonService.update(user);
|
||||
this.ePersonService.createPatchFromCache(user)
|
||||
.pipe(
|
||||
take(1),
|
||||
switchMap((operations: Operation[]) => {
|
||||
if (isNotEmpty(operations)) {
|
||||
return this.ePersonService.patch(user, operations)
|
||||
}
|
||||
return observableOf(undefined)
|
||||
}
|
||||
)
|
||||
).subscribe();
|
||||
}
|
||||
|
||||
restoreSettingsForUsers(user: EPerson) {
|
||||
console.log('restore klaro', user);
|
||||
this.cookieService.set(this.getStorageName(user.uuid), this.getSettingsForUser(user));
|
||||
}
|
||||
|
||||
updateSettingsForUsers(user: EPerson) {
|
||||
console.log('update klaro', user);
|
||||
this.setSettingsForUser(user, this.cookieService.get(this.getStorageName(user.uuid)))
|
||||
}
|
||||
|
||||
|
166
src/app/shared/cookies/klaro-configuration.ts
Normal file
166
src/app/shared/cookies/klaro-configuration.ts
Normal file
@@ -0,0 +1,166 @@
|
||||
import { TOKENITEM } from '../../core/auth/models/auth-token-info.model';
|
||||
import { IMPERSONATING_COOKIE, REDIRECT_COOKIE } from '../../core/auth/auth.service';
|
||||
import { LANG_COOKIE } from '../../core/locale/locale.service';
|
||||
import { ANONYMOUS_STORAGE_NAME_KLARO, HAS_AGREED_END_USER } from './browser-klaro.service';
|
||||
|
||||
export const klaroConfiguration: any = {
|
||||
storageName: ANONYMOUS_STORAGE_NAME_KLARO,
|
||||
|
||||
privacyPolicy: '/info/privacy',
|
||||
|
||||
/*
|
||||
Setting 'hideLearnMore' to 'true' will hide the "learn more / customize" link in
|
||||
the consent notice. We strongly advise against using this under most
|
||||
circumstances, as it keeps the user from customizing his/her consent choices.
|
||||
*/
|
||||
hideLearnMore: false,
|
||||
|
||||
/*
|
||||
Setting 'acceptAll' to 'true' will show an "accept all" button in the notice and
|
||||
modal, which will enable all third-party apps if the user clicks on it. If set
|
||||
to 'false', there will be an "accept" button that will only enable the apps that
|
||||
are enabled in the consent modal.
|
||||
*/
|
||||
acceptAll: true,
|
||||
|
||||
/*
|
||||
You can also set a custom expiration time for the Klaro cookie. By default, it
|
||||
will expire after 30 days. Only relevant if 'storageMethod' is set to 'cookie'.
|
||||
*/
|
||||
cookieExpiresAfterDays: 365,
|
||||
|
||||
htmlTexts: true,
|
||||
|
||||
/*
|
||||
You can overwrite existing translations and add translations for your app
|
||||
descriptions and purposes. See `src/translations/` for a full list of
|
||||
translations that can be overwritten:
|
||||
https://github.com/KIProtect/klaro/tree/master/src/translations
|
||||
*/
|
||||
translations: {
|
||||
en: {
|
||||
acceptAll: 'cookies.consent.accept-all',
|
||||
acceptSelected: 'cookies.consent.accept-selected',
|
||||
app: {
|
||||
optOut: {
|
||||
description: 'cookies.consent.app.opt-out.description',
|
||||
title: 'cookies.consent.app.opt-out.title'
|
||||
},
|
||||
purpose: 'cookies.consent.app.purpose',
|
||||
purposes: 'cookies.consent.app.purposes',
|
||||
required: {
|
||||
description: 'cookies.consent.app.required.description',
|
||||
title: 'cookies.consent.app.required.title'
|
||||
}
|
||||
},
|
||||
close: 'cookies.consent.close',
|
||||
decline: 'cookies.consent.decline',
|
||||
consentNotice: {
|
||||
description: 'cookies.consent.content-notice.description',
|
||||
learnMore: 'cookies.consent.content-notice.learnMore'
|
||||
},
|
||||
consentModal: {
|
||||
description: 'cookies.consent.content-modal.description',
|
||||
privacyPolicy: {
|
||||
name: 'cookies.consent.content-modal.privacy-policy.name',
|
||||
text: 'cookies.consent.content-modal.privacy-policy.text'
|
||||
},
|
||||
title: 'cookies.consent.content-modal.title'
|
||||
},
|
||||
purposes: {}
|
||||
}
|
||||
},
|
||||
apps: [
|
||||
{
|
||||
name: 'token_item',
|
||||
purposes: ['authentication'],
|
||||
required: true,
|
||||
cookies: [
|
||||
TOKENITEM
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'impersonation',
|
||||
purposes: ['authentication'],
|
||||
required: true,
|
||||
cookies: [
|
||||
IMPERSONATING_COOKIE
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'redirect',
|
||||
purposes: ['authentication'],
|
||||
required: true,
|
||||
cookies: [
|
||||
REDIRECT_COOKIE
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'language',
|
||||
purposes: ['preferences'],
|
||||
required: true,
|
||||
cookies: [
|
||||
LANG_COOKIE
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'klaro',
|
||||
purposes: ['acknowledgement'],
|
||||
required: true,
|
||||
cookies: [
|
||||
[/^klaro-.+$/],
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'has_agreed_end_user',
|
||||
purposes: ['acknowledgement'],
|
||||
required: true,
|
||||
cookies: [
|
||||
HAS_AGREED_END_USER
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'google-analytics',
|
||||
purposes: ['statistics'],
|
||||
required: false,
|
||||
cookies: [
|
||||
// /*
|
||||
// you an either only provide a cookie name or regular expression (regex) or a list
|
||||
// consisting of a name or regex, a path and a cookie domain. Providing a path and
|
||||
// domain is necessary if you have apps that set cookies for a path that is not
|
||||
// "/", or a domain that is not the current domain. If you do not set these values
|
||||
// properly, the cookie can't be deleted by Klaro, as there is no way to access the
|
||||
// path or domain of a cookie in JS. Notice that it is not possible to delete
|
||||
// cookies that were set on a third-party domain, or cookies that have the HTTPOnly
|
||||
// attribute: https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#new-
|
||||
// cookie_domain
|
||||
// */
|
||||
//
|
||||
// /*
|
||||
// This rule will match cookies that contain the string '_pk_' and that are set on
|
||||
// the path '/' and the domain 'klaro.kiprotect.com'
|
||||
// */
|
||||
[/^_ga.?$/],
|
||||
[/^_gid$/],
|
||||
//
|
||||
// /*
|
||||
// Same as above, only for the 'localhost' domain
|
||||
// */
|
||||
// [/^_pk_.*$/, '/', 'localhost'],
|
||||
//
|
||||
// /*
|
||||
// This rule will match all cookies named 'piwik_ignore' that are set on the path
|
||||
// '/' on the current domain
|
||||
// */
|
||||
// 'piwik_ignore',
|
||||
],
|
||||
/*
|
||||
If 'onlyOnce' is set to 'true', the app will only be executed once regardless
|
||||
how often the user toggles it on and off. This is relevant e.g. for tracking
|
||||
scripts that would generate new page view events every time Klaro disables and
|
||||
re-enables them due to a consent change by the user.
|
||||
*/
|
||||
onlyOnce: true,
|
||||
},
|
||||
],
|
||||
};
|
@@ -1,3 +0,0 @@
|
||||
export class KlaroEffects {
|
||||
|
||||
}
|
@@ -3,6 +3,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
export function getMockTranslateService(): TranslateService {
|
||||
return jasmine.createSpyObj('translateService', {
|
||||
get: jasmine.createSpy('get'),
|
||||
instant: jasmine.createSpy('instant')
|
||||
instant: jasmine.createSpy('instant'),
|
||||
setDefaultLang: jasmine.createSpy('setDefaultLang')
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user