Skip to content

Commit 3c0fe26

Browse files
author
Andrea Barbasso
committed
Merge branch 'dspace-cris-2023_02_x' into tasl/dspace-cris-2023_02_x/DSC-1713
# Conflicts: # src/app/menu.resolver.ts
2 parents e3940c9 + 5ae6cce commit 3c0fe26

136 files changed

Lines changed: 3207 additions & 361 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config/config.example.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,12 @@ browseBy:
275275
fiveYearLimit: 30
276276
# The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items)
277277
defaultLowerLimit: 1900
278+
# Whether to add item badges to BOTH browse and search result lists.
279+
showLabels: true
278280
# If true, thumbnail images for items will be added to BOTH search and browse result lists.
279281
showThumbnails: true
282+
# Whether to add item thumbnail images to BOTH browse and search result lists.
283+
showMetrics: false
280284
# The number of entries in a paginated browse results list.
281285
# Rounded to the nearest size in the list of selectable sizes on the
282286
# settings menu.

server.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ extendEnvironmentWithAppConfig(environment, appConfig);
8383
// Create a DOM window object based on the template
8484
const _window = domino.createWindow(indexHtml);
8585

86+
// The REST server base URL
87+
const REST_BASE_URL = environment.rest.ssrBaseUrl || environment.rest.baseUrl;
88+
8689
// Assign the DOM window and document objects to the global object
8790
(_window as any).screen = {deviceXDPI: 0, logicalXDPI: 0};
8891
(global as any).window = _window;
@@ -185,7 +188,7 @@ export function app() {
185188
* Proxy the sitemaps
186189
*/
187190
router.use('/sitemap**', createProxyMiddleware({
188-
target: `${environment.rest.baseUrl}/sitemaps`,
191+
target: `${REST_BASE_URL}/sitemaps`,
189192
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
190193
changeOrigin: true
191194
}));
@@ -194,7 +197,7 @@ export function app() {
194197
* Proxy the linksets
195198
*/
196199
router.use('/signposting**', createProxyMiddleware({
197-
target: `${environment.rest.baseUrl}`,
200+
target: `${REST_BASE_URL}`,
198201
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
199202
changeOrigin: true
200203
}));
@@ -645,7 +648,7 @@ function clientHealthCheck(req, res) {
645648
* The callback function to serve health check requests
646649
*/
647650
function healthCheck(req, res) {
648-
const baseUrl = `${environment.rest.baseUrl}${environment.actuators.endpointPath}`;
651+
const baseUrl = `${REST_BASE_URL}${environment.actuators.endpointPath}`;
649652
axios.get(baseUrl)
650653
.then((response) => {
651654
res.status(response.status).send(response.data);

src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[attr.aria-labelledby]="'sidebarName-' + section.id"
66
[title]="('menu.section.icon.' + section.id) | translate"
77
[routerLink]="itemModel.link"
8+
[queryParams]="itemModel.queryParams"
89
(keyup.space)="navigate($event)"
910
(keyup.enter)="navigate($event)"
1011
href="javascript:void(0);"
@@ -21,3 +22,4 @@
2122
</div>
2223
</a>
2324
</div>
25+

src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ export class AdminSidebarSectionComponent extends MenuSectionComponent implement
4949
navigate(event: any): void {
5050
event.preventDefault();
5151
if (!this.isDisabled) {
52-
this.router.navigate(this.itemModel.link);
52+
const extras = {
53+
queryParams: this.itemModel.queryParams
54+
};
55+
this.router.navigate(this.itemModel.link, extras);
5356
}
5457
}
5558
}

src/app/app-routing.module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
import { ServerCheckGuard } from './core/server-check/server-check.guard';
4444
import { MenuResolver } from './menu.resolver';
4545
import { ThemedPageErrorComponent } from './page-error/themed-page-error.component';
46+
import { ForgotPasswordCheckGuard } from './core/rest-property/forgot-password-check-guard.guard';
4647
import { SUGGESTION_MODULE_PATH } from './suggestions-page/suggestions-page-routing-paths';
4748
import { RedirectService } from './redirect/redirect.service';
4849

@@ -99,7 +100,10 @@ import { RedirectService } from './redirect/redirect.service';
99100
path: FORGOT_PASSWORD_PATH,
100101
loadChildren: () => import('./forgot-password/forgot-password.module')
101102
.then((m) => m.ForgotPasswordModule),
102-
canActivate: [EndUserAgreementCurrentUserGuard]
103+
canActivate: [
104+
ForgotPasswordCheckGuard,
105+
EndUserAgreementCurrentUserGuard
106+
]
103107
},
104108
{
105109
path: COMMUNITY_MODULE_PATH,

src/app/app.module.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { RootModule } from './root.module';
3333
import { NuMarkdownModule } from '@ng-util/markdown';
3434
import { FooterModule } from './footer/footer.module';
3535
import { SocialModule } from './social/social.module';
36+
import { DspaceRestInterceptor } from './core/dspace-rest/dspace-rest.interceptor';
3637

3738
export function getConfig() {
3839
return environment;
@@ -109,6 +110,11 @@ const PROVIDERS = [
109110
useClass: LogInterceptor,
110111
multi: true
111112
},
113+
{
114+
provide: HTTP_INTERCEPTORS,
115+
useClass: DspaceRestInterceptor,
116+
multi: true
117+
},
112118
// register the dynamic matcher used by form. MUST be provided by the app module
113119
...DYNAMIC_MATCHER_PROVIDERS,
114120
];

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ import { AuthStatus } from './models/auth-status.model';
4242
import { EPersonMock } from '../../shared/testing/eperson.mock';
4343
import { AppState, storeModuleConfig } from '../../app.reducer';
4444
import { StoreActionTypes } from '../../store.actions';
45-
import { isAuthenticated, isAuthenticatedLoaded } from './selectors';
45+
import { getAuthenticatedUser, isAuthenticated, isAuthenticatedLoaded } from './selectors';
4646
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
4747
import { RouterStub } from '../../shared/testing/router.stub';
48+
import { EPerson } from '../eperson/models/eperson.model';
4849

4950

5051
describe('AuthEffects', () => {
@@ -467,6 +468,8 @@ describe('AuthEffects', () => {
467468

468469
describe('when refresh state, token and redirect action', () => {
469470
it('should return a REFRESH_STATE_TOKEN_AND_REDIRECT_SUCCESS action in response to a REFRESH_STATE_TOKEN_AND_REDIRECT action', (done) => {
471+
472+
store.overrideSelector(getAuthenticatedUser, { id: EPersonMock.id } as EPerson);
470473
spyOn((authEffects as any).authService, 'retrieveAuthenticatedUserById').and.returnValue(observableOf(EPersonMock));
471474

472475
actions = hot('--a-', {
@@ -484,7 +487,9 @@ describe('AuthEffects', () => {
484487
});
485488

486489
describe('when refresh state token failed', () => {
487-
it('should return a REFRESH_STATE_TOKEN_AND_REDIRECT_SUCCESS action in response to a REFRESH_STATE_TOKEN_AND_REDIRECT action', (done) => {
490+
it('should return a REFRESH_STATE_TOKEN_AND_REDIRECT_ERROR action in response to a REFRESH_STATE_TOKEN_AND_REDIRECT action', (done) => {
491+
492+
store.overrideSelector(getAuthenticatedUser, { id: 'mock-id'} as EPerson);
488493
spyOn((authEffects as any).authService, 'retrieveAuthenticatedUserById').and.returnValue(observableThrow(''));
489494

490495
actions = hot('--a-', {

src/app/core/auth/auth.effects.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
queueScheduler,
99
timer
1010
} from 'rxjs';
11-
import { catchError, delay, filter, map, observeOn, switchMap, take, tap } from 'rxjs/operators';
11+
import { catchError, delay, filter, map, observeOn, switchMap, take, tap, withLatestFrom } from 'rxjs/operators';
1212
// import @ngrx
1313
import { Actions, createEffect, ofType } from '@ngrx/effects';
1414
import { Action, select, Store } from '@ngrx/store';
@@ -19,7 +19,7 @@ import { EPerson } from '../eperson/models/eperson.model';
1919
import { AuthStatus } from './models/auth-status.model';
2020
import { AuthTokenInfo } from './models/auth-token-info.model';
2121
import { AppState } from '../../app.reducer';
22-
import { isAuthenticated, isAuthenticatedLoaded } from './selectors';
22+
import { getAuthenticatedUser, isAuthenticated, isAuthenticatedLoaded } from './selectors';
2323
import { StoreActionTypes } from '../../store.actions';
2424
import { AuthMethod } from './models/auth.method';
2525
// import actions
@@ -53,7 +53,7 @@ import {
5353
RetrieveTokenAction,
5454
SetUserAsIdleAction
5555
} from './auth.actions';
56-
import { hasValue } from '../../shared/empty.util';
56+
import { hasValue, isNotNull } from '../../shared/empty.util';
5757
import { Router } from '@angular/router';
5858
import { environment } from '../../../environments/environment';
5959
import { RequestActionTypes } from '../data/request.actions';
@@ -187,8 +187,9 @@ export class AuthEffects {
187187
public refreshToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN),
188188
switchMap((action: RefreshTokenAction) => {
189189
return this.authService.refreshAuthenticationToken(action.payload).pipe(
190+
take(1),
190191
map((token: AuthTokenInfo) => new RefreshTokenSuccessAction(token)),
191-
catchError((error) => observableOf(new RefreshTokenErrorAction()))
192+
catchError(_ => observableOf(new RefreshTokenErrorAction()))
192193
);
193194
})
194195
));
@@ -259,7 +260,7 @@ export class AuthEffects {
259260
return this.authService.retrieveAuthMethodsFromAuthStatus(action.payload)
260261
.pipe(
261262
map((authMethodModels: AuthMethod[]) => new RetrieveAuthMethodsSuccessAction(authMethodModels)),
262-
catchError((error) => observableOf(new RetrieveAuthMethodsErrorAction()))
263+
catchError(_ => observableOf(new RetrieveAuthMethodsErrorAction()))
263264
);
264265
})
265266
));
@@ -268,21 +269,25 @@ export class AuthEffects {
268269
.pipe(ofType(AuthActionTypes.REFRESH_TOKEN_AND_REDIRECT),
269270
switchMap((action: RefreshTokenAndRedirectAction) => {
270271
return this.authService.refreshAuthenticationToken(action.payload.token)
271-
.pipe(map((token: AuthTokenInfo) => new RefreshTokenAndRedirectSuccessAction(token, action.payload.redirectUrl)),
272-
catchError((error) => observableOf(new RefreshTokenAndRedirectErrorAction()))
272+
.pipe(
273+
take(1),
274+
map((token: AuthTokenInfo) => new RefreshTokenAndRedirectSuccessAction(token, action.payload.redirectUrl)),
275+
catchError(_ => observableOf(new RefreshTokenAndRedirectErrorAction()))
273276
);
274277
}))
275278
);
276279

280+
277281
public refreshStateTokenRedirect$: Observable<Action> = createEffect(() => this.actions$
278282
.pipe(ofType(AuthActionTypes.REFRESH_EPERSON_AND_TOKEN_REDIRECT),
279-
switchMap((action: RefreshEpersonAndTokenRedirectAction) =>
280-
this.authService.getAuthenticatedUserFromStore()
281-
.pipe(
282-
switchMap(user => this.authService.retrieveAuthenticatedUserById(user.id)),
283-
map(user => new RefreshEpersonAndTokenRedirectSuccessAction(user, action.payload.token, action.payload.redirectUrl)),
284-
catchError((error) => observableOf(new RefreshEpersonAndTokenRedirectErrorAction()))
285-
)
283+
map(({ payload }: RefreshEpersonAndTokenRedirectAction) => payload),
284+
withLatestFrom(this.store.pipe(select(getAuthenticatedUser), filter(isNotNull))),
285+
switchMap(([{ token, redirectUrl }, { id }]) =>
286+
this.authService.retrieveAuthenticatedUserById(id).pipe(
287+
take(1),
288+
map(user => new RefreshEpersonAndTokenRedirectSuccessAction(user, token, redirectUrl)),
289+
catchError(_ => observableOf(new RefreshEpersonAndTokenRedirectErrorAction()))
290+
)
286291
)
287292
)
288293
);

src/app/core/data/feature-authorization/feature-id.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export enum FeatureID {
3636
CanEditItem = 'canEditItem',
3737
CanRegisterDOI = 'canRegisterDOI',
3838
CanSubscribe = 'canSubscribeDso',
39+
EPersonForgotPassword = 'epersonForgotPassword',
3940
ShowClaimItem = 'showClaimItem',
4041
CanCorrectItem = 'canCorrectItem',
4142
}

src/app/core/data/processes/process-data.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ export class ProcessDataService extends IdentifiableDataService<Process> impleme
123123
* @param processId The ID of the process
124124
*/
125125
getProcess(processId: string): Observable<RemoteData<Process>> {
126-
const href$ = this.getProcessEndpoint(processId);
127-
return this.findByHref(href$,false);
126+
return this.findById(processId, false);
128127
}
129128

130129
/**

0 commit comments

Comments
 (0)