Skip to content

Commit 9c42116

Browse files
committed
Merge remote-tracking branch 'dspace/dspace-7_x' into merge-dspace7.6.3
2 parents d9faadd + 2eca993 commit 9c42116

10 files changed

Lines changed: 178 additions & 74 deletions

File tree

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dspace-angular",
3-
"version": "7.6.3",
3+
"version": "7.6.4-next",
44
"scripts": {
55
"ng": "ng",
66
"config:watch": "nodemon",
@@ -60,7 +60,7 @@
6060
"@angular/platform-browser-dynamic": "^15.2.10",
6161
"@angular/platform-server": "^15.2.10",
6262
"@angular/router": "^15.2.10",
63-
"@babel/runtime": "7.26.0",
63+
"@babel/runtime": "7.26.7",
6464
"@kolkov/ngx-gallery": "^2.0.1",
6565
"@ng-bootstrap/ng-bootstrap": "^11.0.0",
6666
"@ng-dynamic-forms/core": "^15.0.0",
@@ -91,7 +91,7 @@
9191
"filesize": "^6.1.0",
9292
"http-proxy-middleware": "^2.0.7",
9393
"http-terminator": "^3.2.0",
94-
"isbot": "^5.1.21",
94+
"isbot": "^5.1.25",
9595
"js-cookie": "2.2.1",
9696
"js-yaml": "^4.1.0",
9797
"json5": "^2.2.3",
@@ -146,7 +146,7 @@
146146
"@types/grecaptcha": "^3.0.9",
147147
"@types/jasmine": "~3.6.0",
148148
"@types/js-cookie": "2.2.6",
149-
"@types/lodash": "^4.17.14",
149+
"@types/lodash": "^4.17.15",
150150
"@types/node": "^14.18.63",
151151
"@types/sanitize-html": "^2.13.0",
152152
"@typescript-eslint/eslint-plugin": "^5.62.0",
@@ -157,13 +157,13 @@
157157
"cross-env": "^7.0.3",
158158
"csstype": "^3.1.3",
159159
"cypress": "^13.17.0",
160-
"cypress-axe": "^1.5.0",
160+
"cypress-axe": "^1.6.0",
161161
"deep-freeze": "0.0.1",
162162
"eslint": "^8.39.0",
163163
"eslint-plugin-deprecation": "^1.5.0",
164164
"eslint-plugin-import": "^2.31.0",
165165
"eslint-plugin-jsdoc": "^45.0.0",
166-
"eslint-plugin-jsonc": "^2.18.2",
166+
"eslint-plugin-jsonc": "^2.19.1",
167167
"eslint-plugin-lodash": "^7.4.0",
168168
"eslint-plugin-unused-imports": "^2.0.0",
169169
"express-static-gzip": "^2.2.0",
@@ -187,7 +187,7 @@
187187
"react-copy-to-clipboard": "^5.1.0",
188188
"react-dom": "^16.14.0",
189189
"rimraf": "^3.0.2",
190-
"sass": "~1.83.4",
190+
"sass": "~1.84.0",
191191
"sass-loader": "^12.6.0",
192192
"sass-resources-loader": "^2.2.5",
193193
"ts-node": "^8.10.2",

src/app/core/auth/auth.service.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ describe('AuthService test', () => {
260260
(state as any).core = Object.create({});
261261
(state as any).core.auth = authenticatedState;
262262
});
263-
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
263+
authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
264264
}));
265265

266266
it('should return true when user is logged in', () => {
@@ -345,7 +345,7 @@ describe('AuthService test', () => {
345345
(state as any).core = Object.create({});
346346
(state as any).core.auth = authenticatedState;
347347
});
348-
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
348+
authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
349349
storage = (authService as any).storage;
350350
routeServiceMock = TestBed.inject(RouteService);
351351
routerStub = TestBed.inject(Router);
@@ -565,7 +565,7 @@ describe('AuthService test', () => {
565565
(state as any).core = Object.create({});
566566
(state as any).core.auth = unAuthenticatedState;
567567
});
568-
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
568+
authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
569569
}));
570570

571571
it('should return null for the shortlived token', () => {
@@ -605,7 +605,7 @@ describe('AuthService test', () => {
605605
(state as any).core = Object.create({});
606606
(state as any).core.auth = idleState;
607607
});
608-
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
608+
authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
609609
}));
610610

611611
it('isUserIdle should return true when user is not idle', () => {

src/app/core/auth/auth.service.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { Inject, Injectable, Optional } from '@angular/core';
1+
import { Inject, Injectable } from '@angular/core';
22
import { Router } from '@angular/router';
33
import { HttpHeaders } from '@angular/common/http';
4-
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
54

65
import { Observable, of as observableOf } from 'rxjs';
76
import { filter, map, startWith, switchMap, take } from 'rxjs/operators';
@@ -79,18 +78,17 @@ export class AuthService {
7978
*/
8079
private tokenRefreshTimer;
8180

82-
constructor(@Inject(REQUEST) protected req: any,
83-
@Inject(NativeWindowService) protected _window: NativeWindowRef,
84-
@Optional() @Inject(RESPONSE) private response: any,
85-
protected authRequestService: AuthRequestService,
86-
protected epersonService: EPersonDataService,
87-
protected router: Router,
88-
protected routeService: RouteService,
89-
protected storage: CookieService,
90-
protected store: Store<AppState>,
91-
protected hardRedirectService: HardRedirectService,
92-
private notificationService: NotificationsService,
93-
private translateService: TranslateService
81+
constructor(
82+
@Inject(NativeWindowService) protected _window: NativeWindowRef,
83+
protected authRequestService: AuthRequestService,
84+
protected epersonService: EPersonDataService,
85+
protected router: Router,
86+
protected routeService: RouteService,
87+
protected storage: CookieService,
88+
protected store: Store<AppState>,
89+
protected hardRedirectService: HardRedirectService,
90+
protected notificationService: NotificationsService,
91+
protected translateService: TranslateService
9492
) {
9593
this.store.pipe(
9694
// when this service is constructed the store is not fully initialized yet
@@ -473,10 +471,6 @@ export class AuthService {
473471
if (this._window.nativeWindow.location) {
474472
// Hard redirect to login page, so that all state is definitely lost
475473
this._window.nativeWindow.location.href = redirectUrl;
476-
} else if (this.response) {
477-
if (!this.response._headerSent) {
478-
this.response.redirect(302, redirectUrl);
479-
}
480474
} else {
481475
this.router.navigateByUrl(redirectUrl);
482476
}

src/app/core/auth/server-auth.service.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,60 @@
1-
import { Injectable } from '@angular/core';
1+
import { Injectable, Inject, Optional } from '@angular/core';
22
import { HttpHeaders } from '@angular/common/http';
3-
3+
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
44
import { Observable } from 'rxjs';
55
import { map } from 'rxjs/operators';
6-
76
import { hasValue, isNotEmpty } from '../../shared/empty.util';
87
import { HttpOptions } from '../dspace-rest/dspace-rest.service';
9-
import { AuthService } from './auth.service';
8+
import { AuthService, LOGIN_ROUTE } from './auth.service';
109
import { AuthStatus } from './models/auth-status.model';
1110
import { AuthTokenInfo } from './models/auth-token-info.model';
1211
import { RemoteData } from '../data/remote-data';
12+
import { NativeWindowService, NativeWindowRef } from '../services/window.service';
13+
import { AuthRequestService } from './auth-request.service';
14+
import { EPersonDataService } from '../eperson/eperson-data.service';
15+
import { Router } from '@angular/router';
16+
import { RouteService } from '../services/route.service';
17+
import { CookieService } from '../services/cookie.service';
18+
import { Store } from '@ngrx/store';
19+
import { AppState } from '../../app.reducer';
20+
import { HardRedirectService } from '../services/hard-redirect.service';
21+
import { NotificationsService } from '../../shared/notifications/notifications.service';
22+
import { TranslateService } from '@ngx-translate/core';
1323

1424
/**
1525
* The auth service.
1626
*/
1727
@Injectable()
1828
export class ServerAuthService extends AuthService {
1929

30+
constructor(
31+
@Inject(REQUEST) protected req: any,
32+
@Optional() @Inject(RESPONSE) private response: any,
33+
@Inject(NativeWindowService) protected _window: NativeWindowRef,
34+
protected authRequestService: AuthRequestService,
35+
protected epersonService: EPersonDataService,
36+
protected router: Router,
37+
protected routeService: RouteService,
38+
protected storage: CookieService,
39+
protected store: Store<AppState>,
40+
protected hardRedirectService: HardRedirectService,
41+
protected notificationService: NotificationsService,
42+
protected translateService: TranslateService
43+
) {
44+
super(
45+
_window,
46+
authRequestService,
47+
epersonService,
48+
router,
49+
routeService,
50+
storage,
51+
store,
52+
hardRedirectService,
53+
notificationService,
54+
translateService
55+
);
56+
}
57+
2058
/**
2159
* Returns the authenticated user
2260
* @returns {User}
@@ -60,4 +98,18 @@ export class ServerAuthService extends AuthService {
6098
map((rd: RemoteData<AuthStatus>) => Object.assign(new AuthStatus(), rd.payload))
6199
);
62100
}
101+
102+
override redirectToLoginWhenTokenExpired() {
103+
const redirectUrl = LOGIN_ROUTE + '?expired=true';
104+
if (this._window.nativeWindow.location) {
105+
// Hard redirect to login page, so that all state is definitely lost
106+
this._window.nativeWindow.location.href = redirectUrl;
107+
} else if (this.response) {
108+
if (!this.response._headerSent) {
109+
this.response.redirect(302, redirectUrl);
110+
}
111+
} else {
112+
this.router.navigateByUrl(redirectUrl);
113+
}
114+
}
63115
}

src/app/core/metadata/metadata.service.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ export class MetadataService {
161161
this.setCitationKeywordsTag();
162162

163163
this.setCitationAbstractUrlTag();
164+
this.setCitationDoiTag();
164165
this.setCitationPdfUrlTag();
165166
this.setCitationPublisherTag();
166167

@@ -173,7 +174,6 @@ export class MetadataService {
173174
// this.setCitationIssueTag();
174175
// this.setCitationFirstPageTag();
175176
// this.setCitationLastPageTag();
176-
// this.setCitationDOITag();
177177
// this.setCitationPMIDTag();
178178

179179
// this.setCitationFullTextTag();
@@ -294,6 +294,18 @@ export class MetadataService {
294294
}
295295
}
296296

297+
/**
298+
* Add <meta name="citation_doi" ... > to the <head>
299+
*/
300+
private setCitationDoiTag(): void {
301+
if (this.currentObject.value instanceof Item) {
302+
let doi = this.getMetaTagValue('dc.identifier.doi');
303+
if (hasValue(doi)) {
304+
this.addMetaTag('citation_doi', doi);
305+
}
306+
}
307+
}
308+
297309
/**
298310
* Add <meta name="citation_pdf_url" ... > to the <head>
299311
*/

src/app/core/services/cookie.service.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import { Inject, Injectable } from '@angular/core';
2-
3-
import { REQUEST } from '@nguniversal/express-engine/tokens';
4-
1+
import { Injectable } from '@angular/core';
52
import { Subject , Observable } from 'rxjs';
63
import { CookieAttributes } from 'js-cookie';
74

@@ -22,9 +19,6 @@ export abstract class CookieService implements ICookieService {
2219
protected readonly cookieSource = new Subject<{ readonly [key: string]: any }>();
2320
public readonly cookies$ = this.cookieSource.asObservable();
2421

25-
constructor(@Inject(REQUEST) protected req: any) {
26-
}
27-
2822
public abstract set(name: string, value: any, options?: CookieAttributes): void;
2923

3024
public abstract remove(name: string, options?: CookieAttributes): void;

src/app/core/services/server-cookie.service.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
import { Injectable } from '@angular/core';
1+
import { Injectable, Inject } from '@angular/core';
22
import { CookieAttributes } from 'js-cookie';
33
import { CookieService, ICookieService } from './cookie.service';
4+
import { REQUEST } from '@nguniversal/express-engine/tokens';
45

56
@Injectable()
67
export class ServerCookieService extends CookieService implements ICookieService {
78

9+
constructor(@Inject(REQUEST) protected req: any) {
10+
super();
11+
}
12+
813
public set(name: string, value: any, options?: CookieAttributes): void {
914
return;
1015
}

src/app/shared/search/search-filters/search-filters.component.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,16 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {
8888
}
8989

9090
ngOnInit(): void {
91-
this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(
92-
tap(() => this.filtersWithComputedVisibility = 0),
93-
map((filters) => {
94-
Object.keys(filters).forEach((f) => filters[f] = null);
95-
return filters;
96-
})
97-
);
98-
this.searchLink = this.getSearchLink();
91+
this.router.events.subscribe(() => {
92+
this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(
93+
tap(() => this.filtersWithComputedVisibility = 0),
94+
map((filters) => {
95+
Object.keys(filters).forEach((f) => filters[f] = null);
96+
return filters;
97+
})
98+
);
99+
this.searchLink = this.getSearchLink();
100+
});
99101
}
100102

101103
/**

src/assets/i18n/fr.json5

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4144,6 +4144,27 @@
41444144
// "process.detail.back": "Back",
41454145
"process.detail.back": "Retour",
41464146

4147+
//"process.detail.delete.body": "Are you sure you want to delete the current process?",
4148+
"process.detail.delete.body": "Êtes-vous sûr de vouloir supprimer ce processus?",
4149+
4150+
//"process.detail.delete.button": "Delete process",
4151+
"process.detail.delete.button": "Supprimer le processus",
4152+
4153+
//"process.detail.delete.cancel": "Cancel",
4154+
"process.detail.delete.cancel": "Annuler",
4155+
4156+
//"process.detail.delete.confirm": "Delete process",
4157+
"process.detail.delete.confirm": "Supprimer le processus",
4158+
4159+
//"process.detail.delete.error": "Something went wrong when deleting the process",
4160+
"process.detail.delete.error": "Une erreur s'est produite lors de la suppression du processus",
4161+
4162+
//"process.detail.delete.header": "Delete process",
4163+
"process.detail.delete.header": "Supprimer un processus",
4164+
4165+
//"process.detail.delete.success": "The process was successfully deleted.",
4166+
"process.detail.delete.success": "Le processus a bien été supprimé.",
4167+
41474168
// "process.detail.output": "Process Output",
41484169
"process.detail.output": "Sortie du processus",
41494170

@@ -4162,6 +4183,9 @@
41624183
// "process.detail.output-files.empty": "This process doesn't contain any output files",
41634184
"process.detail.output-files.empty": "Ce processus ne contient pas de fichiers de sortie",
41644185

4186+
//"process.detail.refreshing": "Auto-refreshing…",
4187+
"process.detail.refreshing": "Actualisation automatique...",
4188+
41654189
// "process.detail.script": "Script",
41664190
"process.detail.script": "Script",
41674191

@@ -5736,6 +5760,24 @@
57365760
// "submission.sections.general.sections_not_valid": "There are incomplete sections.",
57375761
"submission.sections.general.sections_not_valid": "Sections incomplètes.",
57385762

5763+
//"submission.sections.identifiers.info": "The following identifiers will be created for your item:",
5764+
"submission.sections.identifiers.info": "Les identifiants uniques suivants seront attribués à votre document :",
5765+
5766+
//"submission.sections.identifiers.no_handle": "No handles have been minted for this item.",
5767+
"submission.sections.identifiers.no_handle": "Aucun handle n'a été crée pour ce document.",
5768+
5769+
//"submission.sections.identifiers.no_doi": "No DOIs have been minted for this item.",
5770+
"submission.sections.identifiers.no_doi": "Aucun DOI n'a été créé pour ce document.",
5771+
5772+
//"submission.sections.identifiers.handle_label": "Handle: ",
5773+
"submission.sections.identifiers.handle_label": "Handle : ",
5774+
5775+
//"submission.sections.identifiers.doi_label": "DOI: ",
5776+
"submission.sections.identifiers.doi_label": "DOI : ",
5777+
5778+
//"submission.sections.identifiers.otherIdentifiers_label": "Other identifiers: ",
5779+
"submission.sections.identifiers.otherIdentifiers_label": "Autres identifiants : ",
5780+
57395781
// "submission.sections.submit.progressbar.accessCondition": "Item access conditions",
57405782
"submission.sections.submit.progressbar.accessCondition": "Autorisations d'accès à l'Item",
57415783

@@ -5757,6 +5799,9 @@
57575799
// "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates",
57585800
"submission.sections.submit.progressbar.detect-duplicate": "Doublon(s) potentiel(s)",
57595801

5802+
//"submission.sections.submit.progressbar.identifiers": "Identifiers",
5803+
"submission.sections.submit.progressbar.identifiers": "Identifiants",
5804+
57605805
// "submission.sections.submit.progressbar.license": "Deposit license",
57615806
"submission.sections.submit.progressbar.license": "Licence du dépôt",
57625807

0 commit comments

Comments
 (0)