diff --git a/.eslintrc.json b/.eslintrc.json index 25547554b0..44f53ecb58 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -204,6 +204,7 @@ "import/order": "off", "import/no-deprecated": "warn", + "import/no-namespace": "error", "lodash/import-scope": [ "error", diff --git a/package.json b/package.json index f99e6440f4..3b01ba5c04 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "json5": "^2.1.3", "jsonschema": "1.4.0", "jwt-decode": "^3.1.2", - "klaro": "^0.7.10", + "klaro": "^0.7.18", "lodash": "^4.17.21", "markdown-it": "^13.0.1", "markdown-it-mathjax3": "^4.3.1", diff --git a/scripts/base-href.ts b/scripts/base-href.ts index aee547b46d..7212e1c516 100644 --- a/scripts/base-href.ts +++ b/scripts/base-href.ts @@ -1,4 +1,4 @@ -import * as fs from 'fs'; +import { existsSync, writeFileSync } from 'fs'; import { join } from 'path'; import { AppConfig } from '../src/config/app-config.interface'; @@ -16,7 +16,7 @@ const appConfig: AppConfig = buildAppConfig(); const angularJsonPath = join(process.cwd(), 'angular.json'); -if (!fs.existsSync(angularJsonPath)) { +if (!existsSync(angularJsonPath)) { console.error(`Error:\n${angularJsonPath} does not exist\n`); process.exit(1); } @@ -30,7 +30,7 @@ try { angularJson.projects['dspace-angular'].architect.build.options.baseHref = baseHref; - fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2) + '\n'); + writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2) + '\n'); } catch (e) { console.error(e); } diff --git a/scripts/env-to-yaml.ts b/scripts/env-to-yaml.ts index c2dd1cf0ca..6e8153f4c1 100644 --- a/scripts/env-to-yaml.ts +++ b/scripts/env-to-yaml.ts @@ -1,5 +1,5 @@ -import * as fs from 'fs'; -import * as yaml from 'js-yaml'; +import { existsSync, writeFileSync } from 'fs'; +import { dump } from 'js-yaml'; import { join } from 'path'; /** @@ -18,7 +18,7 @@ if (args[0] === undefined) { const envFullPath = join(process.cwd(), args[0]); -if (!fs.existsSync(envFullPath)) { +if (!existsSync(envFullPath)) { console.error(`Error:\n${envFullPath} does not exist\n`); process.exit(1); } @@ -26,10 +26,10 @@ if (!fs.existsSync(envFullPath)) { try { const env = require(envFullPath).environment; - const config = yaml.dump(env); + const config = dump(env); if (args[1]) { const ymlFullPath = join(process.cwd(), args[1]); - fs.writeFileSync(ymlFullPath, config); + writeFileSync(ymlFullPath, config); } else { console.log(config); } diff --git a/scripts/serve.ts b/scripts/serve.ts index 99bfc822d4..ee8570a45c 100644 --- a/scripts/serve.ts +++ b/scripts/serve.ts @@ -1,4 +1,4 @@ -import * as child from 'child_process'; +import { spawn } from 'child_process'; import { AppConfig } from '../src/config/app-config.interface'; import { buildAppConfig } from '../src/config/config.server'; @@ -9,7 +9,7 @@ const appConfig: AppConfig = buildAppConfig(); * Calls `ng serve` with the following arguments configured for the UI in the app config: host, port, nameSpace, ssl * Any CLI arguments given to this script are patched through to `ng serve` as well. */ -child.spawn( +spawn( `ng serve --host ${appConfig.ui.host} --port ${appConfig.ui.port} --serve-path ${appConfig.ui.nameSpace} --ssl ${appConfig.ui.ssl} ${process.argv.slice(2).join(' ')} --configuration development`, { stdio: 'inherit', shell: true } ); diff --git a/scripts/test-rest.ts b/scripts/test-rest.ts index 51822cf939..9066777c42 100644 --- a/scripts/test-rest.ts +++ b/scripts/test-rest.ts @@ -1,5 +1,5 @@ -import * as http from 'http'; -import * as https from 'https'; +import { request } from 'http'; +import { request as https_request } from 'https'; import { AppConfig } from '../src/config/app-config.interface'; import { buildAppConfig } from '../src/config/config.server'; @@ -20,7 +20,7 @@ console.log(`...Testing connection to REST API at ${restUrl}...\n`); // If SSL enabled, test via HTTPS, else via HTTP if (appConfig.rest.ssl) { - const req = https.request(restUrl, (res) => { + const req = https_request(restUrl, (res) => { console.log(`RESPONSE: ${res.statusCode} ${res.statusMessage} \n`); // We will keep reading data until the 'end' event fires. // This ensures we don't just read the first chunk. @@ -39,7 +39,7 @@ if (appConfig.rest.ssl) { req.end(); } else { - const req = http.request(restUrl, (res) => { + const req = request(restUrl, (res) => { console.log(`RESPONSE: ${res.statusCode} ${res.statusMessage} \n`); // We will keep reading data until the 'end' event fires. // This ensures we don't just read the first chunk. diff --git a/server.ts b/server.ts index 81137ad56a..608c214076 100644 --- a/server.ts +++ b/server.ts @@ -19,14 +19,17 @@ import 'zone.js/node'; import 'reflect-metadata'; import 'rxjs'; -import axios from 'axios'; -import * as pem from 'pem'; -import * as https from 'https'; +/* eslint-disable import/no-namespace */ import * as morgan from 'morgan'; import * as express from 'express'; -import * as bodyParser from 'body-parser'; import * as compression from 'compression'; import * as expressStaticGzip from 'express-static-gzip'; +/* eslint-enable import/no-namespace */ + +import axios from 'axios'; +import { createCertificate } from 'pem'; +import { createServer } from 'https'; +import { json } from 'body-parser'; import { existsSync, readFileSync } from 'fs'; import { join } from 'path'; @@ -110,7 +113,7 @@ export function app() { * Add parser for request bodies * See [morgan](https://github.com/expressjs/body-parser) */ - server.use(bodyParser.json()); + server.use(json()); // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) server.engine('html', (_, options, callback) => @@ -266,7 +269,7 @@ function serverStarted() { * @param keys SSL credentials */ function createHttpsServer(keys) { - https.createServer({ + createServer({ key: keys.serviceKey, cert: keys.certificate }, app).listen(environment.ui.port, environment.ui.host, () => { @@ -320,7 +323,7 @@ function start() { process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // lgtm[js/disabling-certificate-validation] - pem.createCertificate({ + createCertificate({ days: 1, selfSigned: true }, (error, keys) => { diff --git a/src/app/app.reducer.ts b/src/app/app.reducer.ts index 14f3ddd312..f84db92445 100644 --- a/src/app/app.reducer.ts +++ b/src/app/app.reducer.ts @@ -1,4 +1,4 @@ -import * as fromRouter from '@ngrx/router-store'; +import { routerReducer, RouterReducerState } from '@ngrx/router-store'; import { ActionReducerMap, createSelector, MemoizedSelector } from '@ngrx/store'; import { ePeopleRegistryReducer, @@ -53,7 +53,7 @@ import { MenusState } from './shared/menu/menus-state.model'; import { correlationIdReducer } from './correlation-id/correlation-id.reducer'; export interface AppState { - router: fromRouter.RouterReducerState; + router: RouterReducerState; hostWindow: HostWindowState; forms: FormState; metadataRegistry: MetadataRegistryState; @@ -75,7 +75,7 @@ export interface AppState { } export const appReducers: ActionReducerMap = { - router: fromRouter.routerReducer, + router: routerReducer, hostWindow: hostWindowReducer, forms: formReducer, metadataRegistry: metadataRegistryReducer, diff --git a/src/app/core/cache/object-cache.reducer.spec.ts b/src/app/core/cache/object-cache.reducer.spec.ts index e346a00b61..919edc8e57 100644 --- a/src/app/core/cache/object-cache.reducer.spec.ts +++ b/src/app/core/cache/object-cache.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { Operation } from 'fast-json-patch'; import { Item } from '../shared/item.model'; diff --git a/src/app/core/cache/server-sync-buffer.reducer.spec.ts b/src/app/core/cache/server-sync-buffer.reducer.spec.ts index ce159500c6..51ba010c1e 100644 --- a/src/app/core/cache/server-sync-buffer.reducer.spec.ts +++ b/src/app/core/cache/server-sync-buffer.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { RemoveFromObjectCacheAction } from './object-cache.actions'; import { serverSyncBufferReducer } from './server-sync-buffer.reducer'; diff --git a/src/app/core/data/object-updates/object-updates.reducer.spec.ts b/src/app/core/data/object-updates/object-updates.reducer.spec.ts index a51a1431bb..08944a073f 100644 --- a/src/app/core/data/object-updates/object-updates.reducer.spec.ts +++ b/src/app/core/data/object-updates/object-updates.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { AddFieldUpdateAction, diff --git a/src/app/core/data/request.reducer.spec.ts b/src/app/core/data/request.reducer.spec.ts index f6f557ad8f..05f074a96a 100644 --- a/src/app/core/data/request.reducer.spec.ts +++ b/src/app/core/data/request.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { RequestConfigureAction, diff --git a/src/app/core/index/index.reducer.spec.ts b/src/app/core/index/index.reducer.spec.ts index 867e4dbad8..774b9b2742 100644 --- a/src/app/core/index/index.reducer.spec.ts +++ b/src/app/core/index/index.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { indexReducer, MetaIndexState } from './index.reducer'; diff --git a/src/app/core/index/index.selectors.ts b/src/app/core/index/index.selectors.ts index 697616c321..e6ca04f79b 100644 --- a/src/app/core/index/index.selectors.ts +++ b/src/app/core/index/index.selectors.ts @@ -3,7 +3,6 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { coreSelector } from '../core.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; import { IndexState, MetaIndexState } from './index.reducer'; -import * as parse from 'url-parse'; import { IndexName } from './index-name.model'; import { CoreState } from '../core-state.model'; @@ -21,17 +20,21 @@ import { CoreState } from '../core-state.model'; */ export const getUrlWithoutEmbedParams = (url: string): string => { if (isNotEmpty(url)) { - const parsed = parse(url); - if (isNotEmpty(parsed.query)) { - const parts = parsed.query.split(/[?|&]/) - .filter((part: string) => isNotEmpty(part)) - .filter((part: string) => !(part.startsWith('embed=') || part.startsWith('embed.size='))); - let args = ''; - if (isNotEmpty(parts)) { - args = `?${parts.join('&')}`; + try { + const parsed = new URL(url); + if (isNotEmpty(parsed.search)) { + const parts = parsed.search.split(/[?|&]/) + .filter((part: string) => isNotEmpty(part)) + .filter((part: string) => !(part.startsWith('embed=') || part.startsWith('embed.size='))); + let args = ''; + if (isNotEmpty(parts)) { + args = `?${parts.join('&')}`; + } + url = new URLCombiner(parsed.origin, parsed.pathname, args).toString(); + return url; } - url = new URLCombiner(parsed.origin, parsed.pathname, args).toString(); - return url; + } catch (e) { + // Ignore parsing errors. By default, we return the original string below. } } @@ -44,15 +47,19 @@ export const getUrlWithoutEmbedParams = (url: string): string => { */ export const getEmbedSizeParams = (url: string): { name: string, size: number }[] => { if (isNotEmpty(url)) { - const parsed = parse(url); - if (isNotEmpty(parsed.query)) { - return parsed.query.split(/[?|&]/) - .filter((part: string) => isNotEmpty(part)) - .map((part: string) => part.match(/^embed.size=([^=]+)=(\d+)$/)) - .filter((matches: RegExpMatchArray) => hasValue(matches) && hasValue(matches[1]) && hasValue(matches[2])) - .map((matches: RegExpMatchArray) => { - return { name: matches[1], size: Number(matches[2]) }; - }); + try { + const parsed = new URL(url); + if (isNotEmpty(parsed.search)) { + return parsed.search.split(/[?|&]/) + .filter((part: string) => isNotEmpty(part)) + .map((part: string) => part.match(/^embed.size=([^=]+)=(\d+)$/)) + .filter((matches: RegExpMatchArray) => hasValue(matches) && hasValue(matches[1]) && hasValue(matches[2])) + .map((matches: RegExpMatchArray) => { + return { name: matches[1], size: Number(matches[2]) }; + }); + } + } catch (e) { + // Ignore parsing errors. By default, we return an empty result below. } } diff --git a/src/app/core/json-patch/json-patch-operations.reducer.spec.ts b/src/app/core/json-patch/json-patch-operations.reducer.spec.ts index 1f98cf0920..34a68a8801 100644 --- a/src/app/core/json-patch/json-patch-operations.reducer.spec.ts +++ b/src/app/core/json-patch/json-patch-operations.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { diff --git a/src/app/core/router/router.effects.ts b/src/app/core/router/router.effects.ts index c2e3155eff..5df38aa1fc 100644 --- a/src/app/core/router/router.effects.ts +++ b/src/app/core/router/router.effects.ts @@ -1,8 +1,7 @@ import { filter, map, pairwise } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; -import * as fromRouter from '@ngrx/router-store'; -import { RouterNavigationAction } from '@ngrx/router-store'; +import { RouterNavigationAction, ROUTER_NAVIGATION } from '@ngrx/router-store'; import { Router } from '@angular/router'; import { RouteUpdateAction } from './router.actions'; @@ -14,7 +13,7 @@ export class RouterEffects { */ routeChange$ = createEffect(() => this.actions$ .pipe( - ofType(fromRouter.ROUTER_NAVIGATION), + ofType(ROUTER_NAVIGATION), pairwise(), map((actions: RouterNavigationAction[]) => actions.map((navigateAction) => { diff --git a/src/app/navbar/navbar.effects.spec.ts b/src/app/navbar/navbar.effects.spec.ts index bcb105d5b2..787ecafeec 100644 --- a/src/app/navbar/navbar.effects.spec.ts +++ b/src/app/navbar/navbar.effects.spec.ts @@ -4,7 +4,7 @@ import { HostWindowResizeAction } from '../shared/host-window.actions'; import { Observable } from 'rxjs'; import { provideMockActions } from '@ngrx/effects/testing'; import { cold, hot } from 'jasmine-marbles'; -import * as fromRouter from '@ngrx/router-store'; +import { ROUTER_NAVIGATION } from '@ngrx/router-store'; import { CollapseMenuAction } from '../shared/menu/menu.actions'; import { MenuService } from '../shared/menu/menu.service'; import { MenuServiceStub } from '../shared/testing/menu-service.stub'; @@ -43,7 +43,7 @@ describe('NavbarEffects', () => { describe('routeChange$', () => { it('should return a COLLAPSE action in response to an UPDATE_LOCATION action', () => { - actions = hot('--a-', { a: { type: fromRouter.ROUTER_NAVIGATION } }); + actions = hot('--a-', { a: { type: ROUTER_NAVIGATION } }); const expected = cold('--b-', { b: new CollapseMenuAction(MenuID.PUBLIC) }); diff --git a/src/app/navbar/navbar.effects.ts b/src/app/navbar/navbar.effects.ts index 43992a1c61..dc3a29e1bf 100644 --- a/src/app/navbar/navbar.effects.ts +++ b/src/app/navbar/navbar.effects.ts @@ -1,7 +1,7 @@ import { first, map, switchMap } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; -import * as fromRouter from '@ngrx/router-store'; +import { ROUTER_NAVIGATION } from '@ngrx/router-store'; import { HostWindowActionTypes } from '../shared/host-window.actions'; import { @@ -33,7 +33,7 @@ export class NavbarEffects { */ routeChange$ = createEffect(() => this.actions$ .pipe( - ofType(fromRouter.ROUTER_NAVIGATION), + ofType(ROUTER_NAVIGATION), map(() => new CollapseMenuAction(this.menuID)) )); /** diff --git a/src/app/shared/cookies/browser-klaro.service.spec.ts b/src/app/shared/cookies/browser-klaro.service.spec.ts index 37dfda693a..7fd72b54b3 100644 --- a/src/app/shared/cookies/browser-klaro.service.spec.ts +++ b/src/app/shared/cookies/browser-klaro.service.spec.ts @@ -101,7 +101,7 @@ describe('BrowserKlaroService', () => { mockConfig = { translations: { - en: { + zz: { purposes: {}, test: { testeritis: testKey @@ -159,8 +159,8 @@ describe('BrowserKlaroService', () => { it('addAppMessages', () => { service.addAppMessages(); - expect(mockConfig.translations.en[appName]).toBeDefined(); - expect(mockConfig.translations.en.purposes[purpose]).toBeDefined(); + expect(mockConfig.translations.zz[appName]).toBeDefined(); + expect(mockConfig.translations.zz.purposes[purpose]).toBeDefined(); }); it('translateConfiguration', () => { diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index 3b3229f555..56e371242b 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import * as Klaro from 'klaro'; +import { setup, show } from 'klaro/dist/klaro-no-translations'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { AuthService } from '../../core/auth/auth.service'; import { TranslateService } from '@ngx-translate/core'; @@ -79,7 +79,7 @@ export class BrowserKlaroService extends KlaroService { initialize() { if (!environment.info.enablePrivacyStatement) { delete this.klaroConfig.privacyPolicy; - this.klaroConfig.translations.en.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; + this.klaroConfig.translations.zz.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; } const hideGoogleAnalytics$ = this.configService.findByPropertyName(this.GOOGLE_ANALYTICS_KEY).pipe( @@ -136,7 +136,7 @@ export class BrowserKlaroService extends KlaroService { this.klaroConfig.services = this.filterConfigServices(servicesToHide); - Klaro.setup(this.klaroConfig); + setup(this.klaroConfig); }); } @@ -220,7 +220,7 @@ export class BrowserKlaroService extends KlaroService { * Show the cookie consent form */ showSettings() { - Klaro.show(this.klaroConfig); + show(this.klaroConfig); } /** @@ -228,12 +228,12 @@ export class BrowserKlaroService extends KlaroService { */ addAppMessages() { this.klaroConfig.services.forEach((app) => { - this.klaroConfig.translations.en[app.name] = { + this.klaroConfig.translations.zz[app.name] = { title: this.getTitleTranslation(app.name), description: this.getDescriptionTranslation(app.name) }; app.purposes.forEach((purpose) => { - this.klaroConfig.translations.en.purposes[purpose] = this.getPurposeTranslation(purpose); + this.klaroConfig.translations.zz.purposes[purpose] = this.getPurposeTranslation(purpose); }); }); } @@ -247,7 +247,7 @@ export class BrowserKlaroService extends KlaroService { */ this.translateService.setDefaultLang(environment.defaultLanguage); - this.translate(this.klaroConfig.translations.en); + this.translate(this.klaroConfig.translations.zz); } /** diff --git a/src/app/shared/cookies/klaro-configuration.ts b/src/app/shared/cookies/klaro-configuration.ts index 8a9855bd89..a41b641dec 100644 --- a/src/app/shared/cookies/klaro-configuration.ts +++ b/src/app/shared/cookies/klaro-configuration.ts @@ -54,10 +54,46 @@ export const klaroConfiguration: any = { https://github.com/KIProtect/klaro/tree/master/src/translations */ translations: { - en: { + /* + 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', - app: { + 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' @@ -65,26 +101,10 @@ export const klaroConfiguration: any = { purpose: 'cookies.consent.app.purpose', purposes: 'cookies.consent.app.purposes', required: { - description: 'cookies.consent.app.required.description', - title: 'cookies.consent.app.required.title' + title: 'cookies.consent.app.required.title', + description: 'cookies.consent.app.required.description' } - }, - close: 'cookies.consent.close', - decline: 'cookies.consent.decline', - changeDescription: 'cookies.consent.update', - 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: {} + } } }, services: [ diff --git a/src/app/shared/host-window.reducer.spec.ts b/src/app/shared/host-window.reducer.spec.ts index f0e7aa7245..f580c0e1da 100644 --- a/src/app/shared/host-window.reducer.spec.ts +++ b/src/app/shared/host-window.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { hostWindowReducer } from './search/host-window.reducer'; import { HostWindowResizeAction } from './host-window.actions'; diff --git a/src/app/shared/menu/menu.reducer.spec.ts b/src/app/shared/menu/menu.reducer.spec.ts index 7ae05536af..2865e887fc 100644 --- a/src/app/shared/menu/menu.reducer.spec.ts +++ b/src/app/shared/menu/menu.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { ActivateMenuSectionAction, diff --git a/src/app/shared/mocks/dspace-rest/endpoint-mocking-rest.service.ts b/src/app/shared/mocks/dspace-rest/endpoint-mocking-rest.service.ts index 8d621ad4be..0358451557 100644 --- a/src/app/shared/mocks/dspace-rest/endpoint-mocking-rest.service.ts +++ b/src/app/shared/mocks/dspace-rest/endpoint-mocking-rest.service.ts @@ -7,7 +7,6 @@ import { RestRequestMethod } from '../../../core/data/rest-request-method'; import { RawRestResponse } from '../../../core/dspace-rest/raw-rest-response.model'; import { DspaceRestService, HttpOptions } from '../../../core/dspace-rest/dspace-rest.service'; import { MOCK_RESPONSE_MAP, ResponseMapMock } from './mocks/response-map.mock'; -import * as URL from 'url-parse'; import { environment } from '../../../../environments/environment'; /** diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts b/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts index ae8108662d..aa64589d2e 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { SearchFilterCollapseAction, diff --git a/src/app/shared/sidebar/sidebar-effects.service.ts b/src/app/shared/sidebar/sidebar-effects.service.ts index ba53e2fec9..f6f99ca0fc 100644 --- a/src/app/shared/sidebar/sidebar-effects.service.ts +++ b/src/app/shared/sidebar/sidebar-effects.service.ts @@ -1,7 +1,7 @@ import { map, tap, filter } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { createEffect, Actions, ofType } from '@ngrx/effects'; -import * as fromRouter from '@ngrx/router-store'; +import { ROUTER_NAVIGATION } from '@ngrx/router-store'; import { SidebarCollapseAction } from './sidebar.actions'; import { URLBaser } from '../../core/url-baser/url-baser'; @@ -14,7 +14,7 @@ export class SidebarEffects { private previousPath: string; routeChange$ = createEffect(() => this.actions$ .pipe( - ofType(fromRouter.ROUTER_NAVIGATION), + ofType(ROUTER_NAVIGATION), filter((action) => this.previousPath !== this.getBaseUrl(action)), tap((action) => { this.previousPath = this.getBaseUrl(action); diff --git a/src/app/shared/sidebar/sidebar.reducer.spec.ts b/src/app/shared/sidebar/sidebar.reducer.spec.ts index 796c40537c..76962f60c1 100644 --- a/src/app/shared/sidebar/sidebar.reducer.spec.ts +++ b/src/app/shared/sidebar/sidebar.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { sidebarReducer } from './sidebar.reducer'; diff --git a/src/app/shared/truncatable/truncatable.reducer.spec.ts b/src/app/shared/truncatable/truncatable.reducer.spec.ts index 841ec5e367..9866f382f7 100644 --- a/src/app/shared/truncatable/truncatable.reducer.spec.ts +++ b/src/app/shared/truncatable/truncatable.reducer.spec.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-namespace import * as deepFreeze from 'deep-freeze'; import { truncatableReducer } from './truncatable.reducer'; diff --git a/src/app/shared/utils/file-size-pipe.ts b/src/app/shared/utils/file-size-pipe.ts index 2d219cdaf4..934f3ee67a 100644 --- a/src/app/shared/utils/file-size-pipe.ts +++ b/src/app/shared/utils/file-size-pipe.ts @@ -1,4 +1,5 @@ import { Pipe, PipeTransform } from '@angular/core'; +// eslint-disable-next-line import/no-namespace import * as fileSize from 'filesize'; /* diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 597f226cc7..6b8777adf9 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1234,12 +1234,22 @@ "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.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: Authentication, Preferences, Acknowledgement and Statistics.
To learn more, please read our {privacyPolicy}.", "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.", @@ -1254,7 +1264,9 @@ "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", @@ -1284,7 +1296,6 @@ "cookies.consent.app.description.google-recaptcha": "We use google reCAPTCHA service during registration and password recovery", - "cookies.consent.purpose.functional": "Functional", "cookies.consent.purpose.statistical": "Statistical", diff --git a/src/config/config.server.ts b/src/config/config.server.ts index 278cf4f1d5..65daede0a8 100644 --- a/src/config/config.server.ts +++ b/src/config/config.server.ts @@ -1,6 +1,6 @@ -import * as colors from 'colors'; -import * as fs from 'fs'; -import * as yaml from 'js-yaml'; +import { red, blue, green, bold } from 'colors'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { load } from 'js-yaml'; import { join } from 'path'; import { AppConfig } from './app-config.interface'; @@ -62,7 +62,7 @@ const getDefaultConfigPath = () => { // default to config/config.yml let defaultConfigPath = join(CONFIG_PATH, 'config.yml'); - if (!fs.existsSync(defaultConfigPath)) { + if (!existsSync(defaultConfigPath)) { defaultConfigPath = join(CONFIG_PATH, 'config.yaml'); } @@ -95,11 +95,11 @@ const getEnvConfigFilePath = (env: Environment) => { // check if any environment variations of app config exist for (const envVariation of envVariations) { envLocalConfigPath = join(CONFIG_PATH, `config.${envVariation}.yml`); - if (fs.existsSync(envLocalConfigPath)) { + if (existsSync(envLocalConfigPath)) { break; } envLocalConfigPath = join(CONFIG_PATH, `config.${envVariation}.yaml`); - if (fs.existsSync(envLocalConfigPath)) { + if (existsSync(envLocalConfigPath)) { break; } } @@ -110,8 +110,8 @@ const getEnvConfigFilePath = (env: Environment) => { const overrideWithConfig = (config: Config, pathToConfig: string) => { try { console.log(`Overriding app config with ${pathToConfig}`); - const externalConfig = fs.readFileSync(pathToConfig, 'utf8'); - mergeConfig(config, yaml.load(externalConfig)); + const externalConfig = readFileSync(pathToConfig, 'utf8'); + mergeConfig(config, load(externalConfig)); } catch (err) { console.error(err); } @@ -178,18 +178,18 @@ export const buildAppConfig = (destConfigPath?: string): AppConfig => { switch (env) { case 'production': - console.log(`Building ${colors.red.bold(`production`)} app config`); + console.log(`Building ${red.bold(`production`)} app config`); break; case 'test': - console.log(`Building ${colors.blue.bold(`test`)} app config`); + console.log(`Building ${blue.bold(`test`)} app config`); break; default: - console.log(`Building ${colors.green.bold(`development`)} app config`); + console.log(`Building ${green.bold(`development`)} app config`); } // override with default config const defaultConfigPath = getDefaultConfigPath(); - if (fs.existsSync(defaultConfigPath)) { + if (existsSync(defaultConfigPath)) { overrideWithConfig(appConfig, defaultConfigPath); } else { console.warn(`Unable to find default config file at ${defaultConfigPath}`); @@ -197,7 +197,7 @@ export const buildAppConfig = (destConfigPath?: string): AppConfig => { // override with env config const localConfigPath = getEnvConfigFilePath(env); - if (fs.existsSync(localConfigPath)) { + if (existsSync(localConfigPath)) { overrideWithConfig(appConfig, localConfigPath); } else { console.warn(`Unable to find env config file at ${localConfigPath}`); @@ -206,7 +206,7 @@ export const buildAppConfig = (destConfigPath?: string): AppConfig => { // override with external config if specified by environment variable `DSPACE_APP_CONFIG_PATH` const externalConfigPath = ENV('APP_CONFIG_PATH', true); if (isNotEmpty(externalConfigPath)) { - if (fs.existsSync(externalConfigPath)) { + if (existsSync(externalConfigPath)) { overrideWithConfig(appConfig, externalConfigPath); } else { console.warn(`Unable to find external config file at ${externalConfigPath}`); @@ -236,9 +236,9 @@ export const buildAppConfig = (destConfigPath?: string): AppConfig => { buildBaseUrl(appConfig.rest); if (isNotEmpty(destConfigPath)) { - fs.writeFileSync(destConfigPath, JSON.stringify(appConfig, null, 2)); + writeFileSync(destConfigPath, JSON.stringify(appConfig, null, 2)); - console.log(`Angular ${colors.bold('config.json')} file generated correctly at ${colors.bold(destConfigPath)} \n`); + console.log(`Angular ${bold('config.json')} file generated correctly at ${bold(destConfigPath)} \n`); } return appConfig; diff --git a/src/config/config.util.ts b/src/config/config.util.ts index c45282269c..3d152d4563 100644 --- a/src/config/config.util.ts +++ b/src/config/config.util.ts @@ -1,4 +1,4 @@ -import * as merge from 'deepmerge'; +import { all } from 'deepmerge'; import { environment } from '../environments/environment'; @@ -28,7 +28,7 @@ const mergeConfig = (destinationConfig: any, sourceConfig: AppConfig): void => { const mergeOptions = { arrayMerge: (destinationArray, sourceArray, options) => sourceArray }; - Object.assign(destinationConfig, merge.all([ + Object.assign(destinationConfig, all([ destinationConfig, sourceConfig ], mergeOptions)); diff --git a/src/ngx-translate-loaders/translate-server.loader.ts b/src/ngx-translate-loaders/translate-server.loader.ts index bc34c1199d..c09c71f049 100644 --- a/src/ngx-translate-loaders/translate-server.loader.ts +++ b/src/ngx-translate-loaders/translate-server.loader.ts @@ -1,6 +1,6 @@ import { TranslateLoader } from '@ngx-translate/core'; import { Observable, of as observableOf } from 'rxjs'; -import * as fs from 'fs'; +import { readFileSync } from 'fs'; import { TransferState } from '@angular/platform-browser'; import { NGX_TRANSLATE_STATE, NgxTranslateState } from './ngx-translate-state'; @@ -24,7 +24,7 @@ export class TranslateServerLoader implements TranslateLoader { */ public getTranslation(lang: string): Observable { // Retrieve the file for the given language, and parse it - const messages = JSON.parse(fs.readFileSync(`${this.prefix}${lang}${this.suffix}`, 'utf8')); + const messages = JSON.parse(readFileSync(`${this.prefix}${lang}${this.suffix}`, 'utf8')); // Store the parsed messages in the transfer state so they'll be available immediately when the // app loads on the client this.storeInTransferState(lang, messages); diff --git a/yarn.lock b/yarn.lock index aa855e0792..1798394d7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8172,7 +8172,7 @@ kind-of@^6.0.0, 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.10: +klaro@^0.7.18: version "0.7.18" resolved "https://registry.yarnpkg.com/klaro/-/klaro-0.7.18.tgz#fef3a05fcd656451b941e11459f37d6c336e84c0" integrity sha512-Q5nehkGeZuFerisW4oeeB1ax6dHDszWckR70EcxKvhFiJQ61CM0WBSo20yLbdvz8N9MFsOFu4RNCO9JsbkCxgQ==