[CST-15593] migrate from klaro to orejime

This commit is contained in:
Andrea Barbasso
2024-07-15 17:36:48 +02:00
parent f195484674
commit 84069055f5
37 changed files with 399 additions and 571 deletions

View File

@@ -54,9 +54,9 @@ before(() => {
// Runs once before the first test in each "block"
beforeEach(() => {
// Pre-agree to all Klaro cookies by setting the klaro-anonymous cookie
// Pre-agree to all Orejime cookies by setting the orejime-anonymous cookie
// This just ensures it doesn't get in the way of matching other objects in the page.
cy.setCookie('klaro-anonymous', '{%22authentication%22:true%2C%22preferences%22:true%2C%22acknowledgement%22:true%2C%22google-analytics%22:true%2C%22google-recaptcha%22:true}');
cy.setCookie('orejime-anonymous', '{%22authentication%22:true%2C%22preferences%22:true%2C%22acknowledgement%22:true%2C%22google-analytics%22:true%2C%22google-recaptcha%22:true}');
// Remove any CSRF cookies saved from prior tests
cy.clearCookie(DSPACE_XSRF_COOKIE);

View File

@@ -112,7 +112,6 @@
"json5": "^2.2.3",
"jsonschema": "1.4.1",
"jwt-decode": "^3.1.2",
"klaro": "^0.7.18",
"lodash": "^4.17.21",
"lru-cache": "^7.14.1",
"markdown-it": "^13.0.1",
@@ -127,6 +126,7 @@
"ngx-pagination": "6.0.3",
"ngx-ui-switch": "^14.1.0",
"nouislider": "^15.7.1",
"orejime": "^2.3.0",
"pem": "1.14.7",
"prop-types": "^15.8.1",
"react-copy-to-clipboard": "^5.1.0",

View File

@@ -30,7 +30,7 @@ describe('GoogleRecaptchaService', () => {
findByPropertyName: createSuccessfulRemoteDataObject$({ values: ['googleRecaptchaToken'] }),
});
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}',
get: '{%22token_item%22:true%2C%22impersonation%22:true%2C%22redirect%22:true%2C%22language%22:true%2C%22orejime%22:true%2C%22has_agreed_end_user%22:true%2C%22google-analytics%22:true}',
set: () => {
/* empty */
},

View File

@@ -105,7 +105,7 @@ export class GoogleRecaptchaService {
tap(([recaptchaVersionRD, recaptchaModeRD, recaptchaKeyRD]) => {
if (
this.cookieService.get('klaro-anonymous') && this.cookieService.get('klaro-anonymous')[CAPTCHA_NAME] &&
this.cookieService.get('orejime-anonymous') && this.cookieService.get('orejime-anonymous')[CAPTCHA_NAME] &&
recaptchaKeyRD.hasSucceeded && recaptchaVersionRD.hasSucceeded &&
isNotEmpty(recaptchaVersionRD.payload?.values) && isNotEmpty(recaptchaKeyRD.payload?.values)
) {

View File

@@ -23,7 +23,7 @@ import {
import { NotifyInfoService } from '../core/coar-notify/notify-info/notify-info.service';
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../core/data/feature-authorization/feature-id';
import { KlaroService } from '../shared/cookies/klaro.service';
import { OrejimeService } from '../shared/cookies/orejime.service';
import { hasValue } from '../shared/empty.util';
@Component({
@@ -46,7 +46,7 @@ export class FooterComponent implements OnInit {
coarLdnEnabled$: Observable<boolean>;
constructor(
@Optional() public cookies: KlaroService,
@Optional() public cookies: OrejimeService,
protected authorizationService: AuthorizationDataService,
protected notifyInfoService: NotifyInfoService,
@Inject(APP_CONFIG) protected appConfig: AppConfig,

View File

@@ -38,7 +38,7 @@
<ds-alert [type]="AlertTypeEnum.Warning" *ngIf="registrationVerification && !isRecaptchaCookieAccepted()">
<p class="m-0" [innerHTML]="MESSAGE_PREFIX + '.google-recaptcha.must-accept-cookies' | translate"></p>
<p class="m-0"><a href="javascript:void(0);" (click)="this.klaroService.showSettings()">{{ MESSAGE_PREFIX + '.google-recaptcha.open-cookie-settings' | translate }}</a></p>
<p class="m-0"><a href="javascript:void(0);" (click)="this.orejimeService.showSettings()">{{ MESSAGE_PREFIX + '.google-recaptcha.open-cookie-settings' | translate }}</a></p>
</ds-alert>
<div class="my-3" *ngIf="isRecaptchaCookieAccepted() && (googleRecaptchaService.captchaVersion() | async) === 'v2'">

View File

@@ -54,7 +54,7 @@ import {
import { Registration } from '../core/shared/registration.model';
import { AlertComponent } from '../shared/alert/alert.component';
import { AlertType } from '../shared/alert/alert-type';
import { KlaroService } from '../shared/cookies/klaro.service';
import { OrejimeService } from '../shared/cookies/orejime.service';
import { isNotEmpty } from '../shared/empty.util';
import { GoogleRecaptchaComponent } from '../shared/google-recaptcha/google-recaptcha.component';
import { NotificationsService } from '../shared/notifications/notifications.service';
@@ -126,7 +126,7 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit {
private configService: ConfigurationDataService,
public googleRecaptchaService: GoogleRecaptchaService,
public cookieService: CookieService,
@Optional() public klaroService: KlaroService,
@Optional() public orejimeService: OrejimeService,
private changeDetectorRef: ChangeDetectorRef,
private notificationsService: NotificationsService,
) {
@@ -247,8 +247,8 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit {
* Return true if the user has accepted the required cookies for reCaptcha
*/
isRecaptchaCookieAccepted(): boolean {
const klaroAnonymousCookie = this.cookieService.get('klaro-anonymous');
return isNotEmpty(klaroAnonymousCookie) ? klaroAnonymousCookie[CAPTCHA_NAME] : false;
const orejimeAnonymousCookie = this.cookieService.get('orejime-anonymous');
return isNotEmpty(orejimeAnonymousCookie) ? orejimeAnonymousCookie[CAPTCHA_NAME] : false;
}
/**

View File

@@ -20,12 +20,12 @@ import {
createSuccessfulRemoteDataObject$,
} from '../remote-data.utils';
import {
BrowserKlaroService,
BrowserOrejimeService,
COOKIE_MDFIELD,
} from './browser-klaro.service';
import { ANONYMOUS_STORAGE_NAME_KLARO } from './klaro-configuration';
} from './browser-orejime.service';
import { ANONYMOUS_STORAGE_NAME_OREJIME } from './orejime-configuration';
describe('BrowserKlaroService', () => {
describe('BrowserOrejimeService', () => {
const trackingIdProp = 'google.analytics.key';
const trackingIdTestValue = 'mock-tracking-id';
const googleAnalytics = 'google-analytics';
@@ -37,7 +37,7 @@ describe('BrowserKlaroService', () => {
let cookieService;
let user;
let service: BrowserKlaroService;
let service: BrowserOrejimeService;
let configurationDataService: ConfigurationDataService;
const createConfigSuccessSpy = (...values: string[]) => jasmine.createSpyObj('configurationDataService', {
findByPropertyName: createSuccessfulRemoteDataObject$({
@@ -70,7 +70,7 @@ describe('BrowserKlaroService', () => {
configurationDataService = createConfigSuccessSpy(recaptchaValue);
findByPropertyName = configurationDataService.findByPropertyName;
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}',
get: '{%22token_item%22:true%2C%22impersonation%22:true%2C%22redirect%22:true%2C%22language%22:true%2C%22orejime%22:true%2C%22has_agreed_end_user%22:true%2C%22google-analytics%22:true}',
set: () => {
/* empty */
},
@@ -78,7 +78,7 @@ describe('BrowserKlaroService', () => {
TestBed.configureTestingModule({
providers: [
BrowserKlaroService,
BrowserOrejimeService,
{
provide: TranslateService,
useValue: translateService,
@@ -101,7 +101,7 @@ describe('BrowserKlaroService', () => {
},
],
});
service = TestBed.inject(BrowserKlaroService);
service = TestBed.inject(BrowserOrejimeService);
appName = 'testName';
purpose = 'test purpose';
testKey = 'this.is.a.fake.message.key';
@@ -115,7 +115,7 @@ describe('BrowserKlaroService', () => {
},
},
},
services: [{
apps: [{
name: appName,
purposes: [purpose],
}, {
@@ -125,7 +125,7 @@ describe('BrowserKlaroService', () => {
};
service.klaroConfig = mockConfig;
service.orejimeConfig = mockConfig;
});
it('should be created', () => {
@@ -248,7 +248,7 @@ describe('BrowserKlaroService', () => {
scheduler.schedule(() => service.getSavedPreferences().subscribe());
scheduler.flush();
expect(cookieService.get).toHaveBeenCalledWith(ANONYMOUS_STORAGE_NAME_KLARO);
expect(cookieService.get).toHaveBeenCalledWith(ANONYMOUS_STORAGE_NAME_OREJIME);
});
});
@@ -261,7 +261,7 @@ describe('BrowserKlaroService', () => {
scheduler.schedule(() => service.getSavedPreferences().subscribe());
scheduler.flush();
expect(cookieService.get).toHaveBeenCalledWith('klaro-' + user.uuid);
expect(cookieService.get).toHaveBeenCalledWith('orejime-' + user.uuid);
});
});
});
@@ -320,12 +320,12 @@ describe('BrowserKlaroService', () => {
configurationDataService.findByPropertyName = findByPropertyName;
});
it('should not filter googleAnalytics when servicesToHide are empty', () => {
const filteredConfig = (service as any).filterConfigServices([]);
it('should not filter googleAnalytics when appsToHide is empty', () => {
const filteredConfig = (service as any).filterConfigApps([]);
expect(filteredConfig).toContain(jasmine.objectContaining({ name: googleAnalytics }));
});
it('should filter services using names passed as servicesToHide', () => {
const filteredConfig = (service as any).filterConfigServices([googleAnalytics]);
it('should filter apps using names passed as appsToHide', () => {
const filteredConfig = (service as any).filterConfigApps([googleAnalytics]);
expect(filteredConfig).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
});
it('should have been initialized with googleAnalytics', () => {
@@ -337,7 +337,7 @@ describe('BrowserKlaroService', () => {
}),
);
service.initialize();
expect(service.klaroConfig.services).toContain(jasmine.objectContaining({ name: googleAnalytics }));
expect(service.orejimeConfig.apps).toContain(jasmine.objectContaining({ name: googleAnalytics }));
});
it('should filter googleAnalytics when empty configuration is retrieved', () => {
configurationDataService.findByPropertyName =
@@ -363,7 +363,7 @@ describe('BrowserKlaroService', () => {
);
service.initialize();
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
expect(service.orejimeConfig.apps).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
});
it('should filter googleAnalytics when an error occurs', () => {
configurationDataService.findByPropertyName =
@@ -381,7 +381,7 @@ describe('BrowserKlaroService', () => {
}),
);
service.initialize();
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
expect(service.orejimeConfig.apps).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
});
it('should filter googleAnalytics when an invalid payload is retrieved', () => {
configurationDataService.findByPropertyName =
@@ -399,7 +399,7 @@ describe('BrowserKlaroService', () => {
}),
);
service.initialize();
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
expect(service.orejimeConfig.apps).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
});
});
});

View File

@@ -25,17 +25,21 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { EPerson } from '../../core/eperson/models/eperson.model';
import { CAPTCHA_NAME } from '../../core/google-recaptcha/google-recaptcha.service';
import { CookieService } from '../../core/services/cookie.service';
import {
NativeWindowRef,
NativeWindowService,
} from '../../core/services/window.service';
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import {
hasValue,
isEmpty,
isNotEmpty,
} from '../empty.util';
import { KlaroService } from './klaro.service';
import { OrejimeService } from './orejime.service';
import {
ANONYMOUS_STORAGE_NAME_KLARO,
klaroConfiguration,
} from './klaro-configuration';
ANONYMOUS_STORAGE_NAME_OREJIME,
getOrejimeConfiguration,
} from './orejime-configuration';
/**
* Metadata field to store a user's cookie consent preferences in
@@ -63,21 +67,21 @@ const cookiePurposeMessagePrefix = 'cookies.consent.purpose.';
const updateDebounce = 300;
/**
* By using this injection token instead of importing directly we can keep Klaro out of the main bundle
* By using this injection token instead of importing directly we can keep Orejime out of the main bundle
*/
const LAZY_KLARO = new InjectionToken<Promise<any>>(
'Lazily loaded Klaro',
const LAZY_OREJIME = new InjectionToken<Promise<any>>(
'Lazily loaded Orejime',
{
providedIn: 'root',
factory: async () => (await import('klaro/dist/klaro-no-translations')),
factory: async () => (await import('orejime/dist/orejime')),
},
);
/**
* Browser implementation for the KlaroService, representing a service for handling Klaro consent preferences and UI
* Browser implementation for the OrejimeService, representing a service for handling Orejime consent preferences and UI
*/
@Injectable()
export class BrowserKlaroService extends KlaroService {
export class BrowserOrejimeService extends OrejimeService {
private readonly GOOGLE_ANALYTICS_KEY = 'google.analytics.key';
@@ -85,18 +89,22 @@ export class BrowserKlaroService extends KlaroService {
private readonly GOOGLE_ANALYTICS_SERVICE_NAME = 'google-analytics';
/**
* Initial Klaro configuration
* Initial Orejime configuration
*/
klaroConfig = cloneDeep(klaroConfiguration);
orejimeConfig = cloneDeep(getOrejimeConfiguration(this._window));
private orejimeInstance: any;
constructor(
@Inject(NativeWindowService) private _window: NativeWindowRef,
private translateService: TranslateService,
private authService: AuthService,
private ePersonService: EPersonDataService,
private configService: ConfigurationDataService,
private cookieService: CookieService,
@Inject(LAZY_KLARO) private lazyKlaro: Promise<any>,
@Inject(LAZY_OREJIME) private lazyOrejime: Promise<any>,
) {
super();
}
@@ -106,13 +114,9 @@ export class BrowserKlaroService extends KlaroService {
* - Retrieves the current authenticated user
* - Checks if the translation service is ready
* - Initialize configuration for users
* - Add and translate klaro configuration messages
* - Add and translate orejime configuration messages
*/
initialize() {
if (!environment.info.enablePrivacyStatement) {
delete this.klaroConfig.privacyPolicy;
this.klaroConfig.translations.zz.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy';
}
const hideGoogleAnalytics$ = this.configService.findByPropertyName(this.GOOGLE_ANALYTICS_KEY).pipe(
getFirstCompletedRemoteData(),
@@ -126,16 +130,16 @@ export class BrowserKlaroService extends KlaroService {
),
);
const servicesToHide$: Observable<string[]> = observableCombineLatest([hideGoogleAnalytics$, hideRegistrationVerification$]).pipe(
const appsToHide$: Observable<string[]> = observableCombineLatest([hideGoogleAnalytics$, hideRegistrationVerification$]).pipe(
map(([hideGoogleAnalytics, hideRegistrationVerification]) => {
const servicesToHideArray: string[] = [];
const appsToHideArray: string[] = [];
if (hideGoogleAnalytics) {
servicesToHideArray.push(this.GOOGLE_ANALYTICS_SERVICE_NAME);
appsToHideArray.push(this.GOOGLE_ANALYTICS_SERVICE_NAME);
}
if (hideRegistrationVerification) {
servicesToHideArray.push(CAPTCHA_NAME);
appsToHideArray.push(CAPTCHA_NAME);
}
return servicesToHideArray;
return appsToHideArray;
}),
);
@@ -145,8 +149,8 @@ export class BrowserKlaroService extends KlaroService {
const translationServiceReady$ = this.translateService.get('loading.default').pipe(take(1));
observableCombineLatest([user$, servicesToHide$, translationServiceReady$])
.subscribe(([user, servicesToHide, _]: [EPerson, string[], string]) => {
observableCombineLatest([user$, appsToHide$, translationServiceReady$])
.subscribe(([user, appsToHide, _]: [EPerson, string[], string]) => {
user = cloneDeep(user);
if (hasValue(user)) {
@@ -154,10 +158,15 @@ export class BrowserKlaroService extends KlaroService {
}
/**
* Add all message keys for services and purposes
* Add all message keys for apps and purposes
*/
this.addAppMessages();
/**
* Create categories based on the purposes of the apps
*/
this.createCategories();
/**
* Subscribe on a message to make sure the translation service is ready
* Translate all keys in the translation section of the configuration
@@ -165,20 +174,22 @@ export class BrowserKlaroService extends KlaroService {
*/
this.translateConfiguration();
this.klaroConfig.services = this.filterConfigServices(servicesToHide);
this.lazyKlaro.then(({ setup }) => setup(this.klaroConfig));
this.orejimeConfig.apps = this.filterConfigApps(appsToHide);
this.lazyOrejime.then(({ init }) => {
this.orejimeInstance = init(this.orejimeConfig);
});
});
}
/**
* Return saved preferences stored in the klaro cookie
* Return saved preferences stored in the orejime cookie
*/
getSavedPreferences(): Observable<any> {
return this.getUser$().pipe(
map((user: EPerson) => {
let storageName;
if (isEmpty(user)) {
storageName = ANONYMOUS_STORAGE_NAME_KLARO;
storageName = ANONYMOUS_STORAGE_NAME_OREJIME;
} else {
storageName = this.getStorageName(user.uuid);
}
@@ -192,10 +203,10 @@ export class BrowserKlaroService extends KlaroService {
* @param user The authenticated user
*/
private initializeUser(user: EPerson) {
this.klaroConfig.callback = debounce((consent, app) => this.updateSettingsForUsers(user), updateDebounce);
this.klaroConfig.storageName = this.getStorageName(user.uuid);
this.orejimeConfig.callback = debounce((consent, app) => this.updateSettingsForUsers(user), updateDebounce);
this.orejimeConfig.storageName = this.getStorageName(user.uuid);
const anonCookie = this.cookieService.get(ANONYMOUS_STORAGE_NAME_KLARO);
const anonCookie = this.cookieService.get(ANONYMOUS_STORAGE_NAME_OREJIME);
if (hasValue(this.getSettingsForUser(user))) {
this.restoreSettingsForUsers(user);
} else if (hasValue(anonCookie)) {
@@ -250,26 +261,26 @@ export class BrowserKlaroService extends KlaroService {
* Show the cookie consent form
*/
showSettings() {
this.lazyKlaro.then(({ show }) => show(this.klaroConfig));
this.orejimeInstance.show();
}
/**
* Add message keys for all services and purposes
* Add message keys for all apps and purposes
*/
addAppMessages() {
this.klaroConfig.services.forEach((app) => {
this.klaroConfig.translations.zz[app.name] = {
this.orejimeConfig.apps.forEach((app) => {
this.orejimeConfig.translations.zz[app.name] = {
title: this.getTitleTranslation(app.name),
description: this.getDescriptionTranslation(app.name),
};
app.purposes.forEach((purpose) => {
this.klaroConfig.translations.zz.purposes[purpose] = this.getPurposeTranslation(purpose);
this.orejimeConfig.translations.zz.purposes[purpose] = this.getPurposeTranslation(purpose);
});
});
}
/**
* Translate the translation section from the Klaro configuration
* Translate the translation section from the Orejime configuration
*/
translateConfiguration() {
/**
@@ -277,7 +288,26 @@ export class BrowserKlaroService extends KlaroService {
*/
this.translateService.setDefaultLang(environment.defaultLanguage);
this.translate(this.klaroConfig.translations.zz);
this.translate(this.orejimeConfig.translations.zz);
}
/**
* Create categories based on the purposes of the apps
*/
createCategories() {
this.orejimeConfig.categories = this.orejimeConfig.apps.reduce((accumulator, current) => {
let category = accumulator.find((cat) => cat.name === current.purposes[0]);
if (!category) {
category = {
name: current.purposes[0],
title: this.translateService.instant(this.getPurposeTranslation(current.purposes[0])),
apps: [],
};
accumulator.push(category);
}
category.apps.push(current.name);
return accumulator;
}, []);
}
/**
@@ -295,7 +325,7 @@ export class BrowserKlaroService extends KlaroService {
}
/**
* Retrieves the stored Klaro consent settings for a user
* Retrieves the stored Orejime consent settings for a user
* @param user The user to resolve the consent for
*/
getSettingsForUser(user: EPerson) {
@@ -304,7 +334,7 @@ export class BrowserKlaroService extends KlaroService {
}
/**
* Stores the Klaro consent settings for a user in a metadata field
* Stores the Orejime consent settings for a user in a metadata field
* @param user The user to save the settings for
* @param config The consent settings for the user to save
*/
@@ -344,18 +374,18 @@ export class BrowserKlaroService extends KlaroService {
}
/**
* Create the storage name for klaro cookies based on the user's identifier
* Create the storage name for orejime cookies based on the user's identifier
* @param identifier The user's uuid
*/
getStorageName(identifier: string) {
return 'klaro-' + identifier;
return 'orejime-' + identifier;
}
/**
* remove the google analytics from the services
* remove the Google Analytics from the apps
*/
private filterConfigServices(servicesToHide: string[]): Pick<typeof klaroConfiguration, 'services'>[] {
return this.klaroConfig.services.filter(service => !servicesToHide.some(name => name === service.name));
private filterConfigApps(appsToHide: string[]) {
return this.orejimeConfig.apps.filter(service => !appsToHide.some(name => name === service.name));
}
}

View File

@@ -1,199 +0,0 @@
import {
IMPERSONATING_COOKIE,
REDIRECT_COOKIE,
} from '../../core/auth/auth.service';
import { TOKENITEM } from '../../core/auth/models/auth-token-info.model';
import {
CAPTCHA_COOKIE,
CAPTCHA_NAME,
} from '../../core/google-recaptcha/google-recaptcha.service';
import { LANG_COOKIE } from '../../core/locale/locale.service';
/**
* Cookie for has_agreed_end_user
*/
export const HAS_AGREED_END_USER = 'dsHasAgreedEndUser';
/**
* Storage name used to store klaro cookie
*/
export const ANONYMOUS_STORAGE_NAME_KLARO = 'klaro-anonymous';
export const GOOGLE_ANALYTICS_KLARO_KEY = 'google-analytics';
/**
* Klaro configuration
* For more information see https://kiprotect.com/docs/klaro/annotated-config
*/
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 their 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 services if the user clicks on it. If set
to 'false', there will be an "accept" button that will only enable the services 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: {
/*
The `zz` key contains default translations that will be used as fallback values.
This can e.g. be useful for defining a fallback privacy policy URL.
FOR DSPACE: We use 'zz' to map to our own i18n translations for klaro, see
translateConfiguration() in browser-klaro.service.ts. All the below i18n keys are specified
in your /src/assets/i18n/*.json5 translation pack.
*/
zz: {
acceptAll: 'cookies.consent.accept-all',
acceptSelected: 'cookies.consent.accept-selected',
close: 'cookies.consent.close',
consentModal: {
title: 'cookies.consent.content-modal.title',
description: 'cookies.consent.content-modal.description',
},
consentNotice: {
changeDescription: 'cookies.consent.update',
title: 'cookies.consent.content-notice.title',
description: 'cookies.consent.content-notice.description',
learnMore: 'cookies.consent.content-notice.learnMore',
},
decline: 'cookies.consent.decline',
ok: 'cookies.consent.ok',
poweredBy: 'Powered by Klaro!',
privacyPolicy: {
name: 'cookies.consent.content-modal.privacy-policy.name',
text: 'cookies.consent.content-modal.privacy-policy.text',
},
purposeItem: {
service: 'cookies.consent.content-modal.service',
services: 'cookies.consent.content-modal.services',
},
purposes: {
},
save: 'cookies.consent.save',
service: {
disableAll: {
description: 'cookies.consent.app.disable-all.description',
title: 'cookies.consent.app.disable-all.title',
},
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: {
title: 'cookies.consent.app.required.title',
description: 'cookies.consent.app.required.description',
},
},
},
},
services: [
{
name: 'authentication',
purposes: ['functional'],
required: true,
cookies: [
TOKENITEM,
IMPERSONATING_COOKIE,
REDIRECT_COOKIE,
],
},
{
name: 'preferences',
purposes: ['functional'],
required: true,
cookies: [
LANG_COOKIE,
],
},
{
name: 'acknowledgement',
purposes: ['functional'],
required: true,
cookies: [
[/^klaro-.+$/],
HAS_AGREED_END_USER,
],
},
{
name: GOOGLE_ANALYTICS_KLARO_KEY,
purposes: ['statistical'],
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 services 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,
},
{
name: CAPTCHA_NAME,
purposes: ['registration-password-recovery'],
required: false,
cookies: [
CAPTCHA_COOKIE,
],
onAccept: `window.refreshCaptchaScript?.call()`,
onDecline: `window.refreshCaptchaScript?.call()`,
onlyOnce: true,
},
],
};

View File

@@ -0,0 +1,182 @@
import {
IMPERSONATING_COOKIE,
REDIRECT_COOKIE,
} from '../../core/auth/auth.service';
import { TOKENITEM } from '../../core/auth/models/auth-token-info.model';
import {
CAPTCHA_COOKIE,
CAPTCHA_NAME,
} from '../../core/google-recaptcha/google-recaptcha.service';
import { LANG_COOKIE } from '../../core/locale/locale.service';
import { NativeWindowRef } from '../../core/services/window.service';
/**
* Cookie for has_agreed_end_user
*/
export const HAS_AGREED_END_USER = 'dsHasAgreedEndUser';
export const ANONYMOUS_STORAGE_NAME_OREJIME = 'orejime-anonymous';
export const GOOGLE_ANALYTICS_OREJIME_KEY = 'google-analytics';
/**
* Orejime configuration
* For more information see https://github.com/empreinte-digitale/orejime
*/
export function getOrejimeConfiguration(_window: NativeWindowRef): any {
return {
storageName: ANONYMOUS_STORAGE_NAME_OREJIME,
privacyPolicy: './info/privacy',
// Optional. You can set a custom expiration time for the Orejime cookie, in days.
// defaults to 365.
cookieExpiresAfterDays: 365,
/*
We need to explicitly enable the 'zz' language, where all translations are set, because Orejime's default is 'en'.
*/
lang: 'zz',
/*
The appElement selector is used by Orejime to determine where to insert the consent
*/
appElement: 'ds-app',
/*
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/empreinte-digitale/orejime/blob/master/src/translations/en.yml
*/
translations: {
/*
The `zz` key contains default translations that will be used as fallback values.
This can e.g. be useful for defining a fallback privacy policy URL.
FOR DSPACE: We use 'zz' to map to our own i18n translations for orejime, see
translateConfiguration() in browser-orejime.service.ts. All the below i18n keys are specified
in your /src/assets/i18n/*.json5 translation pack.
*/
zz: {
acceptAll: 'cookies.consent.accept-all',
acceptSelected: 'cookies.consent.accept-selected',
close: 'cookies.consent.close',
consentModal: {
title: 'cookies.consent.content-modal.title',
description: 'cookies.consent.content-modal.description',
privacyPolicy: {
name: 'cookies.consent.content-modal.privacy-policy.name',
text: 'cookies.consent.content-modal.privacy-policy.text',
},
},
consentNotice: {
changeDescription: 'cookies.consent.update',
description: 'cookies.consent.content-notice.description',
learnMore: 'cookies.consent.content-notice.learnMore',
},
decline: 'cookies.consent.decline',
declineAll: 'cookies.consent.decline-all',
accept: 'cookies.consent.ok',
save: 'cookies.consent.save',
purposes: {},
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: {
title: 'cookies.consent.app.required.title',
description: 'cookies.consent.app.required.description',
},
},
},
},
apps: [
{
name: 'authentication',
purposes: ['functional'],
required: true,
cookies: [
TOKENITEM,
IMPERSONATING_COOKIE,
REDIRECT_COOKIE,
],
},
{
name: 'preferences',
purposes: ['functional'],
required: true,
cookies: [
LANG_COOKIE,
],
},
{
name: 'acknowledgement',
purposes: ['functional'],
required: true,
cookies: [
[/^orejime-.+$/],
HAS_AGREED_END_USER,
],
},
{
name: GOOGLE_ANALYTICS_OREJIME_KEY,
purposes: ['statistical'],
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 services 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 Orejime, 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 'orejime.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 Orejime disables and
re-enables them due to a consent change by the user.
*/
onlyOnce: true,
},
{
name: CAPTCHA_NAME,
purposes: ['registration-password-recovery'],
required: false,
cookies: [
CAPTCHA_COOKIE,
],
callback: (consent: boolean) => {
_window?.nativeWindow.refreshCaptchaScript?.call();
},
onlyOnce: true,
},
],
};
}

View File

@@ -2,10 +2,10 @@ import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
/**
* Abstract class representing a service for handling Klaro consent preferences and UI
* Abstract class representing a service for handling Orejime consent preferences and UI
*/
@Injectable()
export abstract class KlaroService {
export abstract class OrejimeService {
/**
* Initializes the service
*/
@@ -17,7 +17,7 @@ export abstract class KlaroService {
abstract showSettings();
/**
* Return saved preferences stored in the klaro cookie
* Return saved preferences stored in the Orejime cookie
*/
abstract getSavedPreferences(): Observable<any>;
}

View File

@@ -6,8 +6,8 @@ import { of } from 'rxjs';
import { ConfigurationDataService } from '../core/data/configuration-data.service';
import { ConfigurationProperty } from '../core/shared/configuration-property.model';
import { KlaroService } from '../shared/cookies/klaro.service';
import { GOOGLE_ANALYTICS_KLARO_KEY } from '../shared/cookies/klaro-configuration';
import { OrejimeService } from '../shared/cookies/orejime.service';
import { GOOGLE_ANALYTICS_OREJIME_KEY } from '../shared/cookies/orejime-configuration';
import {
createFailedRemoteDataObject$,
createSuccessfulRemoteDataObject$,
@@ -24,7 +24,7 @@ describe('GoogleAnalyticsService', () => {
let googleAnalyticsSpy: Angulartics2GoogleAnalytics;
let googleTagManagerSpy: Angulartics2GoogleGlobalSiteTag;
let configSpy: ConfigurationDataService;
let klaroServiceSpy: jasmine.SpyObj<KlaroService>;
let orejimeServiceSpy: jasmine.SpyObj<OrejimeService>;
let scriptElementMock: any;
let srcSpy: any;
let innerHTMLSpy: any;
@@ -47,7 +47,7 @@ describe('GoogleAnalyticsService', () => {
'startTracking',
]);
klaroServiceSpy = jasmine.createSpyObj('KlaroService', {
orejimeServiceSpy = jasmine.createSpyObj('OrejimeService', {
'getSavedPreferences': jasmine.createSpy('getSavedPreferences'),
});
@@ -73,11 +73,11 @@ describe('GoogleAnalyticsService', () => {
body: bodyElementSpy,
});
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
GOOGLE_ANALYTICS_KLARO_KEY: true,
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({
GOOGLE_ANALYTICS_OREJIME_KEY: true,
}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy );
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy );
});
it('should be created', () => {
@@ -97,11 +97,11 @@ describe('GoogleAnalyticsService', () => {
findByPropertyName: createFailedRemoteDataObject$(),
});
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
GOOGLE_ANALYTICS_KLARO_KEY: true,
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({
GOOGLE_ANALYTICS_OREJIME_KEY: true,
}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy);
});
it('should NOT add a script to the body', () => {
@@ -120,10 +120,10 @@ describe('GoogleAnalyticsService', () => {
describe('when the tracking id is empty', () => {
beforeEach(() => {
configSpy = createConfigSuccessSpy();
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_KLARO_KEY]: true,
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_OREJIME_KEY]: true,
}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy);
});
it('should NOT add a script to the body', () => {
@@ -141,8 +141,8 @@ describe('GoogleAnalyticsService', () => {
describe('when google-analytics cookie preferences are not existing', () => {
beforeEach(() => {
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
klaroServiceSpy.getSavedPreferences.and.returnValue(of({}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy);
});
it('should NOT add a script to the body', () => {
@@ -161,10 +161,10 @@ describe('GoogleAnalyticsService', () => {
describe('when google-analytics cookie preferences are set to false', () => {
beforeEach(() => {
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_KLARO_KEY]: false,
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_OREJIME_KEY]: false,
}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy);
});
it('should NOT add a script to the body', () => {
@@ -183,10 +183,10 @@ describe('GoogleAnalyticsService', () => {
beforeEach(() => {
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_KLARO_KEY]: true,
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_OREJIME_KEY]: true,
}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy);
});
it('should create a script tag whose innerHTML contains the tracking id', () => {
@@ -220,10 +220,10 @@ describe('GoogleAnalyticsService', () => {
beforeEach(() => {
configSpy = createConfigSuccessSpy(trackingIdV3TestValue);
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_KLARO_KEY]: true,
orejimeServiceSpy.getSavedPreferences.and.returnValue(of({
[GOOGLE_ANALYTICS_OREJIME_KEY]: true,
}));
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, orejimeServiceSpy, configSpy, documentSpy);
});
it('should create a script tag whose innerHTML contains the tracking id', () => {

View File

@@ -11,8 +11,8 @@ import { combineLatest } from 'rxjs';
import { ConfigurationDataService } from '../core/data/configuration-data.service';
import { getFirstCompletedRemoteData } from '../core/shared/operators';
import { KlaroService } from '../shared/cookies/klaro.service';
import { GOOGLE_ANALYTICS_KLARO_KEY } from '../shared/cookies/klaro-configuration';
import { OrejimeService } from '../shared/cookies/orejime.service';
import { GOOGLE_ANALYTICS_OREJIME_KEY } from '../shared/cookies/orejime-configuration';
import { isEmpty } from '../shared/empty.util';
/**
@@ -25,7 +25,7 @@ export class GoogleAnalyticsService {
constructor(
private googleAnalytics: Angulartics2GoogleAnalytics,
private googleGlobalSiteTag: Angulartics2GoogleGlobalSiteTag,
private klaroService: KlaroService,
private orejimeService: OrejimeService,
private configService: ConfigurationDataService,
@Inject(DOCUMENT) private document: any,
) {
@@ -41,12 +41,12 @@ export class GoogleAnalyticsService {
const googleKey$ = this.configService.findByPropertyName('google.analytics.key').pipe(
getFirstCompletedRemoteData(),
);
const preferences$ = this.klaroService.getSavedPreferences();
const preferences$ = this.orejimeService.getSavedPreferences();
combineLatest([preferences$, googleKey$])
.subscribe(([preferences, remoteData]) => {
// make sure user has accepted Google Analytics consents
if (isEmpty(preferences) || isEmpty(preferences[GOOGLE_ANALYTICS_KLARO_KEY]) || !preferences[GOOGLE_ANALYTICS_KLARO_KEY]) {
if (isEmpty(preferences) || isEmpty(preferences[GOOGLE_ANALYTICS_OREJIME_KEY]) || !preferences[GOOGLE_ANALYTICS_OREJIME_KEY]) {
return;
}

View File

@@ -783,23 +783,17 @@
"cookies.consent.app.purpose": "اللحوم",
"cookies.consent.app.required.description": "هذا التطبيق مطلوب تكرارا",
"cookies.consent.app.required.title": "(مطلوب مرة أخرى)",
"cookies.consent.app.disable-all.description": "استخدم هذا الزر لتفعيل جميع الخدمات أو جونسونها.",
"cookies.consent.app.disable-all.title": "تفعيل أو تفعيل كل الخدمات",
"cookies.consent.update": "لقد قمت بتغيير بعض التغييرات منذ الآن، يرجى تحديث موافقتك.",
"cookies.consent.close": "إغلاق",
"cookies.consent.decline": "الرفض",
"cookies.consent.ok": "لا بأس",
"cookies.consent.save": "حفظ",
"cookies.consent.content-notice.title": "الموافقة على ملفات تعريف الارتباط",
"cookies.consent.content-notice.description": "لإصلاح بجمع ومعالجة معلوماتك الشخصية للأغراض التالية: <strong>الاستثناء، والتفضيلات، والاستخلاص، والإحصاء</strong>. <br/> لمعرفة المزيد، يرجى قراءة {privacyPolicy}.",
"cookies.consent.content-notice.description.no-privacy": "لإصلاح بجمع ومعالجة معلوماتك الشخصية للأغراض التالية: <strong>الاستثناء، والتفضيلات، والاستخلاص، والإحصاء</strong>.",
"cookies.consent.content-notice.learnMore": "تخصيص",
"cookies.consent.content-modal.description": "من هنا يمكنك رؤية وتخصيص المعلومات التي تجمعها عنك.",
"cookies.consent.content-modal.privacy-policy.name": "سياسة الخصوصية",
"cookies.consent.content-modal.privacy-policy.text": "لمعرفة المزيد، يرجى قراءة {privacyPolicy}.",
"cookies.consent.content-modal.title": "المعلومات التي بجمعها",
"cookies.consent.content-modal.services": "خدمات",
"cookies.consent.content-modal.service": "خدمة",
"cookies.consent.app.title.authentication": "استيثاق",
"cookies.consent.app.description.authentication": "مطلوب لتسجيل دخولك",
"cookies.consent.app.title.preferences": "التفضيلات",

View File

@@ -2232,12 +2232,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(sempre requerit)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Utilitzeu aquest camp per activar o desactivar tots els serveis.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Activar o desactivar tots els serveis",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Hi ha hagut canvis des de la darrera visita, si us plau, actualitzeu el vostre consentiment.",
@@ -2253,15 +2247,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Guardar",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Cookie Consent",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Recopilem i processem la vostra informació personal amb les finalitats següents: <strong>Autenticació, Preferències, Reconeixement i Estadístiques</strong>. <br/> Per obtenir més informació, llegiu la nostra {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Recopilem i processem la vostra informació personal per als següents propòsits: <strong>Autenticació, Preferències, Reconeixement i Estadístiques<strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Personalitzar",
@@ -2277,12 +2265,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Informació que recopilem",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "serveis",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "servei",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Autenticació",

View File

@@ -2517,12 +2517,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(vždy vyžadováno)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Pomocí tohoto přepínače povolíte nebo zakážete všechny služby.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Povolit nebo zakázat všechny služby.",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Od vaší poslední návštěvy došlo ke změnám, aktualizujte prosím svůj souhlas.",
@@ -2538,15 +2532,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Uložit",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Souhlas se soubory Cookie",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Vaše osobní údaje shromažďujeme a zpracováváme pro následující účely: <strong>Ověření, Preference, Potvrzení a Statistiky</strong>. <br/> Chcete-li se dozvědět více, přečtěte si prosím naše {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Vaše osobní údaje shromažďujeme a zpracováváme pro následující účely: <strong>Ověření, Preference, Potvrzení a Statistiky</strong>. <strong>Využíváme osobní údaje pro tyto účely:",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Přizpůsobit",
@@ -2562,12 +2550,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Informace, které shromažďujeme",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "služby",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "služba",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Ověřování",

View File

@@ -1004,7 +1004,6 @@
"cookies.consent.content-modal.privacy-policy.text": "Για να μάθετε περισσότερα, διαβάστε την {Πολιτική απορρήτου} μας.",
"cookies.consent.content-modal.title": "Πληροφορίες που συλλέγουμε",
"cookies.consent.content-notice.description": "Συλλέγουμε και επεξεργαζόμαστε τα προσωπικά σας στοιχεία για τους ακόλουθους σκοπούς: <strong>Έλεγχος ταυτότητας, Προτιμήσεις, Αναγνώριση και Στατιστικά</strong>. <br/> Για να μάθετε περισσότερα, διαβάστε την {privacyPolicy} μας.",
"cookies.consent.content-notice.description.no-privacy": "Συλλέγουμε και επεξεργαζόμαστε τα προσωπικά σας στοιχεία για τους ακόλουθους σκοπούς: <strong>Έλεγχος ταυτότητας, Προτιμήσεις, Αναγνώριση και Στατιστικά</strong>.",
"cookies.consent.content-notice.learnMore": "Προσαρμογή",
"cookies.consent.decline": "Απόρριψη",
"cookies.consent.purpose.functional": "Λειτουργικός",

View File

@@ -1582,25 +1582,19 @@
"cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.close": "Close",
"cookies.consent.decline": "Decline",
"cookies.consent.decline-all": "Decline all",
"cookies.consent.ok": "That's ok",
"cookies.consent.save": "Save",
"cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> 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: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: {purposes}",
"cookies.consent.content-notice.learnMore": "Customize",
@@ -1612,10 +1606,6 @@
"cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.service": "service",
"cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.description.authentication": "Required for signing you in",

View File

@@ -2277,12 +2277,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(siempre requerido)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Use este campo para habilitar o deshabilitar todos los servicios.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Habilita o deshabilita todos los servicios",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Hubo cambios desde su última visita, actualice su consentimiento.",
@@ -2298,15 +2292,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Guardar",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Cookie Consent",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Recopilamos y procesamos su información personal para los siguientes propósitos: <strong>Autenticación, Preferencias, Reconocimiento y Estadísticas</strong>. <br/> Para obtener más información, lea nuestra {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Recopilamos y procesamos su información personal para los siguientes propósitos: <strong>Autenticación, Preferencias, Reconocimiento y Estadísticas</strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Personalizar",
@@ -2322,12 +2310,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Información que recopilamos",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "servicios",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "servicio",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Autenticación",

View File

@@ -2341,12 +2341,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(aina pakollinen)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Tästä kytkimestä voit ottaa kaikki palvelut käyttöön tai poistaa ne käytöstä",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Ota käyttöön tai poista käytöstä kaikki palvelut",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Viime käyntisi jälkeen on tehty muutoksia. Ole hyvä ja päivitä suostumuksesi.",
@@ -2362,15 +2356,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Tallenna",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Evästeiden hyväksyntä",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Keräämme ja käsittelemme tietojasi seuraaviin tarkoituksiin: <strong>todentaminen, asetukset, kuittaus ja tilastot</strong>. <br/> Lisätietoa saat lukemalla tämän: {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Keräämme ja käsittelemme tietojasi seuraaviin tarkoituksiin: <strong>todentaminen, asetukset, kuittaus ja tilastot</strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Räätälöi",
@@ -2386,12 +2374,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Keräämämme tieto",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "palvelut",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "palvelu",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Todentaminen",

View File

@@ -1616,8 +1616,6 @@
"cookies.consent.content-notice.description": "हम निम्नलिखित उद्देश्यों के लिए आपकी व्यक्तिगत जानकारी एकत्र और संसाधित करते हैं: <strong>प्रमाणीकरण, प्राथमिकताएं, पावती और सांख्यिकी</strong>। <br/> अधिक जानने के लिए, कृपया हमारी {privacyPolicy} पढ़ें।",
"cookies.consent.content-notice.description.no-privacy": "हम निम्नलिखित उद्देश्यों के लिए आपकी व्यक्तिगत जानकारी एकत्र और संसाधित करते हैं: <strong>प्रमाणीकरण, प्राथमिकताएं, पावती और सांख्यिकी</strong>।",
"cookies.consent.content-notice.learnMore": "अनुकूलित करें",
"cookies.consent.decline": "अस्वीकार",

View File

@@ -2498,14 +2498,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(mindig szükséges)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
// TODO New key - Add a translation
"cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
// TODO New key - Add a translation
"cookies.consent.app.disable-all.title": "Enable or disable all services",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Változások történtek az utolsó látogatása óta, frissítse a beleegyezését.",
@@ -2522,16 +2514,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Mentés",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Cookie elfogadása",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Mi gyűjtjük és feldolgozzuk a személyes adatait a következő célból: <strong>Hitelesítés, Beállítások, Elismerés és Statisztikák</strong>. <br/> Részletekért olvassa el: {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
// TODO New key - Add a translation
"cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Személyreszab",
@@ -2547,14 +2532,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Gyűjtött adatok",
// "cookies.consent.content-modal.services": "services",
// TODO New key - Add a translation
"cookies.consent.content-modal.services": "services",
// "cookies.consent.content-modal.service": "service",
// TODO New key - Add a translation
"cookies.consent.content-modal.service": "service",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Hitelesítés",

View File

@@ -1958,12 +1958,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(sempre obbligatorio)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Utilizzare questo interruttore per abilitare o disabilitare tutti i servizi.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Abilitare o disabilitare tutti i servizi",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Ci sono stati dei cambiamenti dal tuo ultimo accesso, aggiorna il tuo consenso.",
@@ -1979,14 +1973,8 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Salvare",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Consenso ai cookie",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Raccogliamo ed elaboriamo le tue informazioni personali per i seguenti scopi: <strong>Autenticazione, Preferenze, Accettazione e Statistiche</strong>. <br/> Per saperne di più, leggi la nostra {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Raccogliamo ed elaboriamo le tue informazioni personali per i seguenti scopi: <strong>Autenticazione, Preferenze, Accettazione e Statistiche</strong>.",
"cookies.consent.content-notice.description": "Raccogliamo ed elaboriamo le tue informazioni personali per i seguenti scopi: {purposes}",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Personalizza",
@@ -2003,12 +1991,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Informazioni che raccogliamo",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "servizi",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "servizio",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Autenticazione",

View File

@@ -2247,9 +2247,6 @@
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Біз сіздің жеке ақпаратыңызды келесі мақсаттарда жинаймыз және өңдейміз: <strong>Аутентификация, Параметрлері, Растау және Статистикалар</strong>. <br/> Көбірек білу үшін, біздің {privacyPolicy} оқуыңызды өтінеміз.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Біз сіздің жеке мәліметтеріңізді келесі мақсаттар үшін жинаймыз және өңдейміз: <strong>Аутентификация, Қалаулар, Растау және статистикасы</strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Баптау",

View File

@@ -2689,13 +2689,7 @@
"admin.registries.bitstream-formats.table.id": "ID",
"admin.registries.schema.fields.table.id": "ID",
"cookies.consent.app.description.google-recaptcha": "Podczas rejestracji i odzyskiwania hasła używamy narzędzia google reCAPTCHA",
"cookies.consent.app.disable-all.description": "Przełącz, aby zaakceptować lub odrzucić wszystkie",
"cookies.consent.app.disable-all.title": "Akceptowacja lub odrzucenie wszystkich",
"cookies.consent.app.title.google-recaptcha": "Google reCaptcha",
"cookies.consent.content-modal.service": "usługa",
"cookies.consent.content-modal.services": "usługi",
"cookies.consent.content-notice.description.no-privacy": "Zbieramy i przetwarzamy Twoje dane w celu: <strong>autentykacji, ustawień preferencji i zgód oraz do celów statystycznych</strong>.",
"cookies.consent.content-notice.title": "Zgoda na ciasteczka",
"cookies.consent.ok": "Zgadzam się",
"cookies.consent.purpose.registration-password-recovery": "Rejestracja i odzyskiwanie hasła",
"cookies.consent.save": "Zapisz",

View File

@@ -2369,12 +2369,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(sempre requerido)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Use esse comutador para ativar ou desativar todos os serviços.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Ativar ou desativar todos os serviços",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Houve alterações desde sua última visita, atualize seu consentimento.",
@@ -2390,15 +2384,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Salvar",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Consentimento de Cookies",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Coletamos e processamos suas informações pessoais para os seguintes propósitos: <strong>Autenticação, Preferências, Reconhecimento e Estatísticas</strong>. <br/> Para aprender mais, por favor leia nossa {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Coletamos e processamos suas informações pessoais para os seguintes propósitos: <strong>Autenticação, Preferências, Reconhecimento e Estatísticas</strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Customizar",
@@ -2414,12 +2402,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Informações que coletamos",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "Serviços",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "serviço",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Autenticação",

View File

@@ -2412,12 +2412,6 @@
// "cookies.consent.app.required.title": "(always required)",
"cookies.consent.app.required.title": "(sempre necessária)",
// "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.",
"cookies.consent.app.disable-all.description": "Utilize este interruptor para ativar ou desativar todos os serviços.",
// "cookies.consent.app.disable-all.title": "Enable or disable all services",
"cookies.consent.app.disable-all.title": "Ativar ou desativar todos os serviços",
// "cookies.consent.update": "There were changes since your last visit, please update your consent.",
"cookies.consent.update": "Existem alterações desde a sua última visita, atualize o seu consentimento.",
@@ -2433,15 +2427,9 @@
// "cookies.consent.save": "Save",
"cookies.consent.save": "Guardar",
// "cookies.consent.content-notice.title": "Cookie Consent",
"cookies.consent.content-notice.title": "Consentir cookies",
// "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>. <br/> To learn more, please read our {privacyPolicy}.",
"cookies.consent.content-notice.description": "Recolhemos e processamos informação pessoal para os seguintes propósitos: <strong>Autenticação, Guardar Preferências, Termos de Uso e Estatísticas</strong>. <br/> Para saber mais, por favor leia a nossa {privacyPolicy}.",
// "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: <strong>Authentication, Preferences, Acknowledgement and Statistics</strong>.",
"cookies.consent.content-notice.description.no-privacy": "Recolhemos e processamos as suas informações pessoais para os seguintes fins: <strong>Autenticação, Preferências, Reconhecimento e Estatísticas</strong>.",
// "cookies.consent.content-notice.learnMore": "Customize",
"cookies.consent.content-notice.learnMore": "Pesonalizar",
@@ -2457,12 +2445,6 @@
// "cookies.consent.content-modal.title": "Information that we collect",
"cookies.consent.content-modal.title": "Informação que recolhemos",
// "cookies.consent.content-modal.services": "services",
"cookies.consent.content-modal.services": "serviços",
// "cookies.consent.content-modal.service": "service",
"cookies.consent.content-modal.service": "serviço",
// "cookies.consent.app.title.authentication": "Authentication",
"cookies.consent.app.title.authentication": "Autenticação",

View File

@@ -658,23 +658,17 @@
"cookies.consent.app.purpose": "Сврха",
"cookies.consent.app.required.description": "Ова апликација је увек потребна",
"cookies.consent.app.required.title": "(увек потребно)",
"cookies.consent.app.disable-all.description": "Користите овај прекидач да омогућите или онемогућите све услуге.",
"cookies.consent.app.disable-all.title": "Омогућите или онемогућите све услуге",
"cookies.consent.update": "Било је промена од ваше последње посете, ажурирајте своју сагласност.",
"cookies.consent.close": "Затворити",
"cookies.consent.decline": "Одбити",
"cookies.consent.ok": "То је у реду",
"cookies.consent.save": "сачувати",
"cookies.consent.content-notice.title": "Сагласност за колачиће",
"cookies.consent.content-notice.description": "Прикупљамо и обрађујемо ваше личне податке у следеће сврхе: <strong>Провера аутентичности, подешавања, потврда и статистика</strong>. <br/> Да бисте сазнали више, прочитајте нашу {privacyPolicy}.",
"cookies.consent.content-notice.description.no-privacy": "Прикупљамо и обрађујемо ваше личне податке у следеће сврхе: <strong>Провера аутентичности, подешавања, потврда и статистика</strong>.",
"cookies.consent.content-notice.learnMore": "Прилагодити",
"cookies.consent.content-modal.description": "Овде можете видети и прилагодити информације које прикупљамо о вама.",
"cookies.consent.content-modal.privacy-policy.name": "Правила о приватности",
"cookies.consent.content-modal.privacy-policy.text": "Да сазнате више, прочитајте нашу {privacyPolicy}.",
"cookies.consent.content-modal.title": "Информације које прикупљамо",
"cookies.consent.content-modal.services": "Услуге",
"cookies.consent.content-modal.service": "Услуга",
"cookies.consent.app.title.authentication": "Провера",
"cookies.consent.app.description.authentication": "Потребно за пријављивање",
"cookies.consent.app.title.preferences": "Подешавања",

View File

@@ -658,23 +658,17 @@
"cookies.consent.app.purpose": "Svrha",
"cookies.consent.app.required.description": "Ova aplikacija je uvek potrebna",
"cookies.consent.app.required.title": "(uvek potrebno)",
"cookies.consent.app.disable-all.description": "Koristite ovaj prekidač da omogućite ili onemogućite sve usluge.",
"cookies.consent.app.disable-all.title": "Omogućite ili onemogućite sve usluge",
"cookies.consent.update": "Bilo je promena od vaše poslednje posete, ažurirajte svoju saglasnost.",
"cookies.consent.close": "Zatvoriti",
"cookies.consent.decline": "Odbiti",
"cookies.consent.ok": "To je u redu",
"cookies.consent.save": "sačuvati",
"cookies.consent.content-notice.title": "Saglasnost za kolačiće",
"cookies.consent.content-notice.description": "Prikupljamo i obrađujemo vaše lične podatke u sledeće svrhe: <strong>Provera autentičnosti, podešavanja, potvrda i statistika</strong>. <br/> Da biste saznali više, pročitajte našu {privacyPolicy}.",
"cookies.consent.content-notice.description.no-privacy": "Prikupljamo i obrađujemo vaše lične podatke u sledeće svrhe: <strong>Provera autentičnosti, podešavanja, potvrda i statistika</strong>.",
"cookies.consent.content-notice.learnMore": "Prilagoditi",
"cookies.consent.content-modal.description": "Ovde možete videti i prilagoditi informacije koje prikupljamo o vama.",
"cookies.consent.content-modal.privacy-policy.name": "Pravila o privatnosti",
"cookies.consent.content-modal.privacy-policy.text": "Da saznate više, pročitajte našu {privacyPolicy}.",
"cookies.consent.content-modal.title": "Informacije koje prikupljamo",
"cookies.consent.content-modal.services": "Usluge",
"cookies.consent.content-modal.service": "Usluga",
"cookies.consent.app.title.authentication": "Provera",
"cookies.consent.app.description.authentication": "Potrebno za prijavljivanje",
"cookies.consent.app.title.preferences": "Podešavanja",

View File

@@ -638,8 +638,6 @@
"cookies.consent.app.description.google-analytics": "Cho phép chúng tôi theo dõi dữ liệu thống kê",
"cookies.consent.app.description.google-recaptcha": "Chúng tôi sử dụng dịch vụ google reCAPTCHA trong quá trình đăng ký và khôi phục mật khẩu",
"cookies.consent.app.description.preferences": "Bắt buộc để lưu tùy chọn của bạn",
"cookies.consent.app.disable-all.description": "Sử dụng nút chuyển này để bật hoặc tắt tất cả dịch vụ.",
"cookies.consent.app.disable-all.title": "Bật hoặc tắt tất cả dịch vụ",
"cookies.consent.app.opt-out.description": "Ứng dụng này đã được tải theo mặc định (nhưng bạn có thể chọn không tham gia)",
"cookies.consent.app.purpose": "mục đích",
"cookies.consent.app.required.description": "Ứng dụng này luôn được yêu cầu",
@@ -652,13 +650,9 @@
"cookies.consent.content-modal.description": "Tại đây bạn có thể xem và tùy chỉnh thông tin mà chúng tôi thu thập được về bạn.",
"cookies.consent.content-modal.privacy-policy.name": "chính sách bảo mật",
"cookies.consent.content-modal.privacy-policy.text": "Để biết thêm vui lòng đọc {privacyPolicy} của chúng tôi.",
"cookies.consent.content-modal.service": "dịch vụ",
"cookies.consent.content-modal.services": "các dịch vụ",
"cookies.consent.content-modal.title": "Thông tin mà chúng tôi thu thập",
"cookies.consent.content-notice.description": "Chúng tôi thu thập và xử lý thông tin các nhân của bạn cho các mục đích sau: <strong>Xác thực các ưa thích xác nhận và thống kê</strong>. <br/>Để biết thêm vui lòng đọc {privacyPolicy} của chúng tôi.",
"cookies.consent.content-notice.description.no-privacy": "Chúng tôi thu thập và xử lý thông tin cá nhân của bạn cho các mục đích sau: <strong>Xác thực Cài đặt cá nhân Xác nhận và Thống kê</strong>.",
"cookies.consent.content-notice.learnMore": "Tùy chỉnh",
"cookies.consent.content-notice.title": "Đồng ý sử dụng cookie",
"cookies.consent.decline": "Từ chối",
"cookies.consent.ok": "OK",
"cookies.consent.purpose.functional": "Chức năng",

View File

@@ -53,8 +53,8 @@ import { ClientMathService } from '../../app/core/shared/client-math.service';
import { MathService } from '../../app/core/shared/math.service';
import { BrowserXSRFService } from '../../app/core/xsrf/browser-xsrf.service';
import { XSRFService } from '../../app/core/xsrf/xsrf.service';
import { BrowserKlaroService } from '../../app/shared/cookies/browser-klaro.service';
import { KlaroService } from '../../app/shared/cookies/klaro.service';
import { BrowserOrejimeService } from '../../app/shared/cookies/browser-orejime.service';
import { OrejimeService } from '../../app/shared/cookies/orejime.service';
import { MissingTranslationHelper } from '../../app/shared/translate/missing-translation.helper';
import { GoogleAnalyticsService } from '../../app/statistics/google-analytics.service';
import { SubmissionService } from '../../app/submission/submission.service';
@@ -118,8 +118,8 @@ export const browserAppConfig: ApplicationConfig = mergeApplicationConfig({
useClass: ClientCookieService,
},
{
provide: KlaroService,
useClass: BrowserKlaroService,
provide: OrejimeService,
useClass: BrowserOrejimeService,
},
{
provide: SubmissionService,

View File

@@ -37,7 +37,7 @@ import { LocaleService } from '../../app/core/locale/locale.service';
import { HeadTagService } from '../../app/core/metadata/head-tag.service';
import { CorrelationIdService } from '../../app/correlation-id/correlation-id.service';
import { InitService } from '../../app/init.service';
import { KlaroService } from '../../app/shared/cookies/klaro.service';
import { OrejimeService } from '../../app/shared/cookies/orejime.service';
import { isNotEmpty } from '../../app/shared/empty.util';
import { MenuService } from '../../app/shared/menu/menu.service';
import { ThemeService } from '../../app/shared/theme-support/theme.service';
@@ -75,7 +75,7 @@ export class BrowserInitService extends InitService {
protected googleAnalyticsService: GoogleAnalyticsService,
protected headTagService: HeadTagService,
protected breadcrumbsService: BreadcrumbsService,
protected klaroService: KlaroService,
protected orejimeService: OrejimeService,
protected authService: AuthService,
protected themeService: ThemeService,
protected menuService: MenuService,
@@ -123,7 +123,7 @@ export class BrowserInitService extends InitService {
this.themeService.listenForThemeChanges(true);
this.trackAuthTokenExpiration();
this.initKlaro();
this.initOrejime();
await lastValueFrom(this.authenticationReady$());
@@ -155,12 +155,12 @@ export class BrowserInitService extends InitService {
}
/**
* Initialize Klaro (once authentication is resolved)
* Initialize Orejime (once authentication is resolved)
* @protected
*/
protected initKlaro() {
protected initOrejime() {
this.authenticationReady$().subscribe(() => {
this.klaroService.initialize();
this.orejimeService.initialize();
});
}

View File

@@ -147,6 +147,6 @@
--ds-process-overview-table-info-column-width: 250px;
--ds-process-overview-table-actions-column-width: 80px;
--green1: #1FB300; // This variable represents the success color for the Klaro cookie banner
--button-text-color-cookie: #333; // This variable represents the text color for buttons in the Klaro cookie banner
--green1: #1FB300; // This variable represents the success color for the Orejime cookie banner
--button-text-color-cookie: #fff; // This variable represents the text color for buttons in the Orejime cookie banner
}

View File

@@ -37,24 +37,28 @@ body {
z-index: 0;
}
.klaro
.cookie-notice {
.cn-buttons {
.cm-btn.cm-btn-success {
.orejime-AppContainer .orejime-Notice-actionItem {
&.orejime-Notice-actionItem--save > button {
color: var(--button-text-color-cookie);
background-color: var(--green1);
}
.cm-btn.cm-btn-success.cm-btn-accept-all {
color: var(--button-text-color-cookie);
background-color: var(--green1);
}
}
}
.klaro .cookie-modal a, .klaro .context-notice a, .klaro .cookie-notice a
{
.orejime-ModalPortal {
.orejime-Button.orejime-AppToggles-enableAll,
.orejime-Modal-saveButton {
color: var(--button-text-color-cookie);
background-color: var(--green1);
}
.orejime-Modal-closeButton svg {
cursor: pointer;
}
a {
color: var(--green1);
}
}
.media-viewer
.change-gallery

View File

@@ -3,3 +3,4 @@
@import '~node_modules/bootstrap/scss/bootstrap.scss';
@import '~node_modules/nouislider/dist/nouislider.min';
@import '~node_modules/ngx-ui-switch/ui-switch.component.scss';
@import '~node_modules/orejime/dist/orejime.scss';

View File

@@ -5920,6 +5920,11 @@ executable@^4.1.1:
dependencies:
pify "^2.2.0"
exenv@^1.2.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==
exponential-backoff@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
@@ -7787,11 +7792,6 @@ kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klaro@^0.7.18:
version "0.7.18"
resolved "https://registry.yarnpkg.com/klaro/-/klaro-0.7.18.tgz#fef3a05fcd656451b941e11459f37d6c336e84c0"
integrity sha512-Q5nehkGeZuFerisW4oeeB1ax6dHDszWckR70EcxKvhFiJQ61CM0WBSo20yLbdvz8N9MFsOFu4RNCO9JsbkCxgQ==
kleur@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
@@ -8909,6 +8909,14 @@ ora@5.4.1, ora@^5.4.1:
strip-ansi "^6.0.0"
wcwidth "^1.0.1"
orejime@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/orejime/-/orejime-2.3.0.tgz#1fc6f570c9bcb11538cc5d270997a526d8135af0"
integrity sha512-eDUgd5yEF5pCIUHPNXVDKmgH+4k4GEwxU7eexBFeVESba3ZYDHSDq4ULXiF2LnZwxg+H6Qi28o8rGfGxNeOriA==
dependencies:
"@babel/runtime" "^7.1.2"
react-modal "^3.13.1"
os-tmpdir@^1.0.2, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -9902,6 +9910,21 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
react-lifecycles-compat@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-modal@^3.13.1:
version "3.16.1"
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b"
integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==
dependencies:
exenv "^1.2.0"
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.0"
warning "^4.0.3"
react-mosaic-component@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/react-mosaic-component/-/react-mosaic-component-4.1.1.tgz#48a34e5e5c16654075212666c2aebeb488bab9f2"
@@ -11056,16 +11079,7 @@ streamroller@^3.1.5:
debug "^4.3.4"
fs-extra "^8.1.0"
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -11124,7 +11138,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -11145,13 +11159,6 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -11857,6 +11864,13 @@ void-elements@^2.0.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==
warning@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
dependencies:
loose-envify "^1.0.0"
watchpack@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
@@ -12197,7 +12211,7 @@ wildcard@^2.0.0:
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67"
integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -12215,15 +12229,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"