mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[DURACOM-234] Migrate to functional guards WIP
This commit is contained in:
@@ -36,7 +36,7 @@ export function getBitstreamRequestACopyRoute(item, bitstream): { routerLink: st
|
||||
}
|
||||
export const COAR_NOTIFY_SUPPORT = 'coar-notify-support';
|
||||
|
||||
export const HOME_PAGE_PATH = 'admin';
|
||||
export const HOME_PAGE_PATH = 'home';
|
||||
|
||||
export function getHomePageRoute() {
|
||||
return `/${HOME_PAGE_PATH}`;
|
||||
|
@@ -11,7 +11,7 @@ import { BrowseByDataType } from './browse-by-switcher/browse-by-data-type';
|
||||
|
||||
describe('BrowseByGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
let guard: BrowseByGuard;
|
||||
let guard: any;
|
||||
let translateService: any;
|
||||
let browseDefinitionService: any;
|
||||
let router: any;
|
||||
@@ -35,7 +35,7 @@ describe('BrowseByGuard', () => {
|
||||
|
||||
router = new RouterStub() as any;
|
||||
|
||||
guard = new BrowseByGuard(translateService, browseDefinitionService, router);
|
||||
guard = BrowseByGuard;
|
||||
});
|
||||
|
||||
it('should return true, and sets up the data correctly, with a scope and value', () => {
|
||||
@@ -53,7 +53,7 @@ describe('BrowseByGuard', () => {
|
||||
value,
|
||||
},
|
||||
};
|
||||
guard.canActivate(scopedRoute as any, undefined)
|
||||
guard(scopedRoute as any, undefined, browseDefinitionService, router, translateService)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) => {
|
||||
@@ -86,7 +86,7 @@ describe('BrowseByGuard', () => {
|
||||
},
|
||||
};
|
||||
|
||||
guard.canActivate(scopedNoValueRoute as any, undefined)
|
||||
guard(scopedNoValueRoute, undefined, browseDefinitionService, router, translateService)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) => {
|
||||
@@ -123,7 +123,7 @@ describe('BrowseByGuard', () => {
|
||||
},
|
||||
};
|
||||
|
||||
guard.canActivate(scopedNoValueRoute as any, undefined).pipe(
|
||||
guard(scopedNoValueRoute as any, undefined, browseDefinitionService, router, translateService).pipe(
|
||||
first(),
|
||||
).subscribe((canActivate) => {
|
||||
const result = {
|
||||
@@ -154,7 +154,8 @@ describe('BrowseByGuard', () => {
|
||||
value,
|
||||
},
|
||||
};
|
||||
guard.canActivate(route as any, undefined)
|
||||
|
||||
guard(route as any, undefined, browseDefinitionService, router, translateService)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) => {
|
||||
@@ -189,7 +190,8 @@ describe('BrowseByGuard', () => {
|
||||
value,
|
||||
},
|
||||
};
|
||||
guard.canActivate(scopedRoute as any, undefined)
|
||||
|
||||
guard(scopedRoute as any, undefined, browseDefinitionService, router, translateService)
|
||||
.pipe(first())
|
||||
.subscribe((canActivate) => {
|
||||
expect(router.navigate).toHaveBeenCalled();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
Data,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
@@ -25,25 +26,18 @@ import {
|
||||
hasValue,
|
||||
} from '../shared/empty.util';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
/**
|
||||
* A guard taking care of the correct route.data being set for the Browse-By components
|
||||
*/
|
||||
export class BrowseByGuard {
|
||||
|
||||
constructor(
|
||||
protected translate: TranslateService,
|
||||
protected browseDefinitionService: BrowseDefinitionDataService,
|
||||
protected router: Router,
|
||||
) {
|
||||
}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
export const BrowseByGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
browseDefinitionService: BrowseDefinitionDataService = inject(BrowseDefinitionDataService),
|
||||
router: Router = inject(Router),
|
||||
translate: TranslateService = inject(TranslateService),
|
||||
): Observable<boolean> => {
|
||||
const title = route.data.title;
|
||||
const id = route.params.id || route.queryParams.id || route.data.id;
|
||||
let browseDefinition$: Observable<BrowseDefinition | undefined>;
|
||||
if (hasNoValue(route.data.browseDefinition) && hasValue(id)) {
|
||||
browseDefinition$ = this.browseDefinitionService.findById(id).pipe(
|
||||
browseDefinition$ = browseDefinitionService.findById(id).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((browseDefinitionRD: RemoteData<BrowseDefinition>) => browseDefinitionRD.payload),
|
||||
);
|
||||
@@ -52,21 +46,21 @@ export class BrowseByGuard {
|
||||
}
|
||||
const scope = route.queryParams.scope ?? route.parent?.params.id;
|
||||
const value = route.queryParams.value;
|
||||
const metadataTranslated = this.translate.instant(`browse.metadata.${id}`);
|
||||
const metadataTranslated = translate.instant(`browse.metadata.${id}`);
|
||||
return browseDefinition$.pipe(
|
||||
switchMap((browseDefinition: BrowseDefinition | undefined) => {
|
||||
if (hasValue(browseDefinition)) {
|
||||
route.data = this.createData(title, id, browseDefinition, metadataTranslated, value, route, scope);
|
||||
route.data = createData(title, id, browseDefinition, metadataTranslated, value, route, scope);
|
||||
return observableOf(true);
|
||||
} else {
|
||||
void this.router.navigate([PAGE_NOT_FOUND_PATH]);
|
||||
void router.navigate([PAGE_NOT_FOUND_PATH]);
|
||||
return observableOf(false);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private createData(title: string, id: string, browseDefinition: BrowseDefinition, field: string, value: string, route: ActivatedRouteSnapshot, scope: string): Data {
|
||||
function createData(title: string, id: string, browseDefinition: BrowseDefinition, field: string, value: string, route: ActivatedRouteSnapshot, scope: string): Data {
|
||||
return Object.assign({}, route.data, {
|
||||
title: title,
|
||||
id: id,
|
||||
@@ -75,5 +69,4 @@ export class BrowseByGuard {
|
||||
value: hasValue(value) ? `"${value}"` : '',
|
||||
scope: scope,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import { CreateCollectionPageGuard } from './create-collection-page.guard';
|
||||
|
||||
describe('CreateCollectionPageGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
let guard: CreateCollectionPageGuard;
|
||||
let guard: any;
|
||||
let router;
|
||||
let communityDataServiceStub: any;
|
||||
|
||||
@@ -28,11 +28,11 @@ describe('CreateCollectionPageGuard', () => {
|
||||
};
|
||||
router = new RouterMock();
|
||||
|
||||
guard = new CreateCollectionPageGuard(router, communityDataServiceStub);
|
||||
guard = CreateCollectionPageGuard;
|
||||
});
|
||||
|
||||
it('should return true when the parent ID resolves to a community', () => {
|
||||
guard.canActivate({ queryParams: { parent: 'valid-id' } } as any, undefined)
|
||||
guard({ queryParams: { parent: 'valid-id' } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
@@ -41,7 +41,7 @@ describe('CreateCollectionPageGuard', () => {
|
||||
});
|
||||
|
||||
it('should return false when no parent ID has been provided', () => {
|
||||
guard.canActivate({ queryParams: { } } as any, undefined)
|
||||
guard({ queryParams: { } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
@@ -50,7 +50,7 @@ describe('CreateCollectionPageGuard', () => {
|
||||
});
|
||||
|
||||
it('should return false when the parent ID does not resolve to a community', () => {
|
||||
guard.canActivate({ queryParams: { parent: 'invalid-id' } } as any, undefined)
|
||||
guard({ queryParams: { parent: 'invalid-id' } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
@@ -59,7 +59,7 @@ describe('CreateCollectionPageGuard', () => {
|
||||
});
|
||||
|
||||
it('should return false when the parent ID resolves to an error response', () => {
|
||||
guard.canActivate({ queryParams: { parent: 'error-id' } } as any, undefined)
|
||||
guard({ queryParams: { parent: 'error-id' } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivate,
|
||||
CanActivateFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
@@ -24,34 +24,29 @@ import {
|
||||
} from '../../shared/empty.util';
|
||||
|
||||
/**
|
||||
* Prevent creation of a collection without a parent community provided
|
||||
* @class CreateCollectionPageGuard
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CreateCollectionPageGuard implements CanActivate {
|
||||
public constructor(private router: Router, private communityService: CommunityDataService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* True when either a parent ID query parameter has been provided and the parent ID resolves to a valid parent community
|
||||
* Reroutes to a 404 page when the page cannot be activated
|
||||
* @method canActivate
|
||||
*/
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
export const CreateCollectionPageGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
communityService: CommunityDataService = inject(CommunityDataService),
|
||||
router: Router = inject(Router),
|
||||
): Observable<boolean> => {
|
||||
const parentID = route.queryParams.parent;
|
||||
if (hasNoValue(parentID)) {
|
||||
this.router.navigate(['/404']);
|
||||
router.navigate(['/404']);
|
||||
return observableOf(false);
|
||||
}
|
||||
return this.communityService.findById(parentID)
|
||||
return communityService.findById(parentID)
|
||||
.pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((communityRD: RemoteData<Community>) => hasValue(communityRD) && communityRD.hasSucceeded && hasValue(communityRD.payload)),
|
||||
tap((isValid: boolean) => {
|
||||
if (!isValid) {
|
||||
this.router.navigate(['/404']);
|
||||
router.navigate(['/404']);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import { CreateCommunityPageGuard } from './create-community-page.guard';
|
||||
|
||||
describe('CreateCommunityPageGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
let guard: CreateCommunityPageGuard;
|
||||
let guard: any;
|
||||
let router;
|
||||
let communityDataServiceStub: any;
|
||||
|
||||
@@ -28,11 +28,11 @@ describe('CreateCommunityPageGuard', () => {
|
||||
};
|
||||
router = new RouterMock();
|
||||
|
||||
guard = new CreateCommunityPageGuard(router, communityDataServiceStub);
|
||||
guard = CreateCommunityPageGuard;
|
||||
});
|
||||
|
||||
it('should return true when the parent ID resolves to a community', () => {
|
||||
guard.canActivate({ queryParams: { parent: 'valid-id' } } as any, undefined)
|
||||
guard({ queryParams: { parent: 'valid-id' } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
@@ -41,7 +41,7 @@ describe('CreateCommunityPageGuard', () => {
|
||||
});
|
||||
|
||||
it('should return true when no parent ID has been provided', () => {
|
||||
guard.canActivate({ queryParams: { } } as any, undefined)
|
||||
guard({ queryParams: { } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
@@ -50,7 +50,7 @@ describe('CreateCommunityPageGuard', () => {
|
||||
});
|
||||
|
||||
it('should return false when the parent ID does not resolve to a community', () => {
|
||||
guard.canActivate({ queryParams: { parent: 'invalid-id' } } as any, undefined)
|
||||
guard({ queryParams: { parent: 'invalid-id' } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
@@ -59,7 +59,7 @@ describe('CreateCommunityPageGuard', () => {
|
||||
});
|
||||
|
||||
it('should return false when the parent ID resolves to an error response', () => {
|
||||
guard.canActivate({ queryParams: { parent: 'error-id' } } as any, undefined)
|
||||
guard({ queryParams: { parent: 'error-id' } } as any, undefined, communityDataServiceStub, router)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(canActivate) =>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
@@ -23,35 +24,29 @@ import {
|
||||
} from '../../shared/empty.util';
|
||||
|
||||
/**
|
||||
* Prevent creation of a community with an invalid parent community provided
|
||||
* @class CreateCommunityPageGuard
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CreateCommunityPageGuard {
|
||||
public constructor(private router: Router, private communityService: CommunityDataService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* True when either NO parent ID query parameter has been provided, or the parent ID resolves to a valid parent community
|
||||
* Reroutes to a 404 page when the page cannot be activated
|
||||
* @method canActivate
|
||||
*/
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
export const CreateCommunityPageGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
communityService: CommunityDataService = inject(CommunityDataService),
|
||||
router: Router = inject(Router),
|
||||
): Observable<boolean> => {
|
||||
const parentID = route.queryParams.parent;
|
||||
if (hasNoValue(parentID)) {
|
||||
return observableOf(true);
|
||||
}
|
||||
|
||||
return this.communityService.findById(parentID)
|
||||
return communityService.findById(parentID)
|
||||
.pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((communityRD: RemoteData<Community>) => hasValue(communityRD) && communityRD.hasSucceeded && hasValue(communityRD.payload)),
|
||||
tap((isValid: boolean) => {
|
||||
if (!isValid) {
|
||||
this.router.navigate(['/404']);
|
||||
router.navigate(['/404']);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -20,7 +20,7 @@ import { authReducer } from './auth.reducer';
|
||||
import { AuthBlockingGuard } from './auth-blocking.guard';
|
||||
|
||||
describe('AuthBlockingGuard', () => {
|
||||
let guard: AuthBlockingGuard;
|
||||
let guard: any;
|
||||
let initialState;
|
||||
let store: Store<AppState>;
|
||||
let mockStore: MockStore<AppState>;
|
||||
@@ -52,14 +52,14 @@ describe('AuthBlockingGuard', () => {
|
||||
beforeEach(() => {
|
||||
store = TestBed.inject(Store);
|
||||
mockStore = store as MockStore<AppState>;
|
||||
guard = new AuthBlockingGuard(store);
|
||||
guard = AuthBlockingGuard;
|
||||
});
|
||||
|
||||
describe(`canActivate`, () => {
|
||||
|
||||
describe(`when authState.blocking is undefined`, () => {
|
||||
it(`should not emit anything`, (done) => {
|
||||
expect(guard.canActivate()).toBeObservable(cold('-'));
|
||||
expect(guard(null, null, store)).toBeObservable(cold('-'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -77,7 +77,7 @@ describe('AuthBlockingGuard', () => {
|
||||
});
|
||||
|
||||
it(`should not emit anything`, (done) => {
|
||||
expect(guard.canActivate()).toBeObservable(cold('-'));
|
||||
expect(guard(null, null, store)).toBeObservable(cold('-'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -95,7 +95,7 @@ describe('AuthBlockingGuard', () => {
|
||||
});
|
||||
|
||||
it(`should succeed`, (done) => {
|
||||
expect(guard.canActivate()).toBeObservable(cold('(a|)', { a: true }));
|
||||
expect(guard(null, null, store)).toBeObservable(cold('(a|)', { a: true }));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@@ -1,4 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
import {
|
||||
select,
|
||||
Store,
|
||||
@@ -19,24 +24,16 @@ import { isAuthenticationBlocking } from './selectors';
|
||||
* route until the authentication status has loaded.
|
||||
* To ensure all rest requests get the correct auth header.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AuthBlockingGuard {
|
||||
|
||||
constructor(private store: Store<AppState>) {
|
||||
}
|
||||
|
||||
/**
|
||||
* True when the authentication isn't blocking everything
|
||||
*/
|
||||
canActivate(): Observable<boolean> {
|
||||
return this.store.pipe(select(isAuthenticationBlocking)).pipe(
|
||||
export const AuthBlockingGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
store: Store<AppState> = inject(Store<AppState>),
|
||||
): Observable<boolean> => {
|
||||
return store.pipe(select(isAuthenticationBlocking)).pipe(
|
||||
map((isBlocking: boolean) => isBlocking === false),
|
||||
distinctUntilChanged(),
|
||||
filter((finished: boolean) => finished === true),
|
||||
take(1),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateChildFn,
|
||||
CanActivateFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
UrlTree,
|
||||
@@ -16,7 +18,7 @@ import {
|
||||
switchMap,
|
||||
} from 'rxjs/operators';
|
||||
|
||||
import { CoreState } from '../core-state.model';
|
||||
import { AppState } from '../../app.reducer';
|
||||
import {
|
||||
AuthService,
|
||||
LOGIN_ROUTE,
|
||||
@@ -28,49 +30,35 @@ import {
|
||||
|
||||
/**
|
||||
* Prevent unauthorized activating and loading of routes
|
||||
* @class AuthenticatedGuard
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthenticatedGuard {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
constructor(private authService: AuthService, private router: Router, private store: Store<CoreState>) {}
|
||||
|
||||
/**
|
||||
* True when user is authenticated
|
||||
* UrlTree with redirect to login page when user isn't authenticated
|
||||
* @method canActivate
|
||||
*/
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
|
||||
export const AuthenticatedGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
authService: AuthService = inject(AuthService),
|
||||
router: Router = inject(Router),
|
||||
store: Store<AppState> = inject(Store<AppState>),
|
||||
): Observable<boolean | UrlTree> => {
|
||||
const url = state.url;
|
||||
return this.handleAuth(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* True when user is authenticated
|
||||
* UrlTree with redirect to login page when user isn't authenticated
|
||||
* @method canActivateChild
|
||||
*/
|
||||
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
|
||||
return this.canActivate(route, state);
|
||||
}
|
||||
|
||||
private handleAuth(url: string): Observable<boolean | UrlTree> {
|
||||
// redirect to sign in page if user is not authenticated
|
||||
return this.store.pipe(select(isAuthenticationLoading)).pipe(
|
||||
return store.pipe(select(isAuthenticationLoading)).pipe(
|
||||
find((isLoading: boolean) => isLoading === false),
|
||||
switchMap(() => this.store.pipe(select(isAuthenticated))),
|
||||
switchMap(() => store.pipe(select(isAuthenticated))),
|
||||
map((authenticated) => {
|
||||
if (authenticated) {
|
||||
return authenticated;
|
||||
} else {
|
||||
this.authService.setRedirectUrl(url);
|
||||
this.authService.removeToken();
|
||||
return this.router.createUrlTree([LOGIN_ROUTE]);
|
||||
authService.setRedirectUrl(url);
|
||||
authService.removeToken();
|
||||
return router.createUrlTree([LOGIN_ROUTE]);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const AuthenticatedGuardChild: CanActivateChildFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
) => AuthenticatedGuard(route, state);
|
||||
|
@@ -1,36 +1,27 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { Router } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { NotifyInfoGuard } from './notify-info.guard';
|
||||
import { NotifyInfoService } from './notify-info.service';
|
||||
|
||||
describe('NotifyInfoGuard', () => {
|
||||
let guard: NotifyInfoGuard;
|
||||
let guard: any;
|
||||
let notifyInfoServiceSpy: any;
|
||||
let router: any;
|
||||
|
||||
beforeEach(() => {
|
||||
notifyInfoServiceSpy = jasmine.createSpyObj('NotifyInfoService', ['isCoarConfigEnabled']);
|
||||
router = jasmine.createSpyObj('Router', ['parseUrl']);
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
NotifyInfoGuard,
|
||||
{ provide: NotifyInfoService, useValue: notifyInfoServiceSpy },
|
||||
{ provide: Router, useValue: router },
|
||||
],
|
||||
});
|
||||
guard = TestBed.inject(NotifyInfoGuard);
|
||||
guard = NotifyInfoGuard;
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(guard).toBeTruthy();
|
||||
notifyInfoServiceSpy.isCoarConfigEnabled.and.returnValue(of(true));
|
||||
expect(guard(null, null, notifyInfoServiceSpy, router)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return true if COAR config is enabled', (done) => {
|
||||
notifyInfoServiceSpy.isCoarConfigEnabled.and.returnValue(of(true));
|
||||
|
||||
guard.canActivate(null, null).subscribe((result) => {
|
||||
guard(null, null, notifyInfoServiceSpy, router).subscribe((result) => {
|
||||
expect(result).toBe(true);
|
||||
done();
|
||||
});
|
||||
@@ -40,7 +31,7 @@ describe('NotifyInfoGuard', () => {
|
||||
notifyInfoServiceSpy.isCoarConfigEnabled.and.returnValue(of(false));
|
||||
router.parseUrl.and.returnValue(of('/404'));
|
||||
|
||||
guard.canActivate(null, null).subscribe(() => {
|
||||
guard(null, null, notifyInfoServiceSpy, router).subscribe(() => {
|
||||
expect(router.parseUrl).toHaveBeenCalledWith('/404');
|
||||
done();
|
||||
});
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivate,
|
||||
CanActivateFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
UrlTree,
|
||||
@@ -11,27 +11,13 @@ import { map } from 'rxjs/operators';
|
||||
|
||||
import { NotifyInfoService } from './notify-info.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class NotifyInfoGuard implements CanActivate {
|
||||
constructor(
|
||||
private notifyInfoService: NotifyInfoService,
|
||||
private router: Router,
|
||||
) {}
|
||||
|
||||
canActivate(
|
||||
export const NotifyInfoGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Observable<boolean | UrlTree> {
|
||||
return this.notifyInfoService.isCoarConfigEnabled().pipe(
|
||||
map(coarLdnEnabled => {
|
||||
if (coarLdnEnabled) {
|
||||
return true;
|
||||
} else {
|
||||
return this.router.parseUrl('/404');
|
||||
}
|
||||
}),
|
||||
notifyInfoService: NotifyInfoService = inject(NotifyInfoService),
|
||||
router: Router = inject(Router),
|
||||
): Observable<boolean | UrlTree> => {
|
||||
return notifyInfoService.isCoarConfigEnabled().pipe(
|
||||
map(isEnabled => isEnabled ? true : router.parseUrl('/404')),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
RouterStateSnapshot,
|
||||
UrlTree,
|
||||
} from '@angular/router';
|
||||
@@ -10,16 +11,13 @@ import { AuthorizationDataService } from '../data/feature-authorization/authoriz
|
||||
import { FeatureID } from '../data/feature-authorization/feature-id';
|
||||
|
||||
/**
|
||||
* An guard for redirecting users to the feedback page if user is authorized
|
||||
* A guard for redirecting users to the feedback page if user is authorized
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FeedbackGuard {
|
||||
export const FeedbackGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
authorizationService: AuthorizationDataService = inject(AuthorizationDataService),
|
||||
): Observable<boolean | UrlTree> => {
|
||||
return authorizationService.isAuthorized(FeatureID.CanSendFeedback);
|
||||
};
|
||||
|
||||
constructor(private authorizationService: AuthorizationDataService) {
|
||||
}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
|
||||
return this.authorizationService.isAuthorized(FeatureID.CanSendFeedback);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,14 +5,14 @@ import { DefaultAppConfig } from '../../../config/default-app-config';
|
||||
import { ReloadGuard } from './reload.guard';
|
||||
|
||||
describe('ReloadGuard', () => {
|
||||
let guard: ReloadGuard;
|
||||
let guard: any;
|
||||
let router: Router;
|
||||
let appConfig: AppConfig;
|
||||
|
||||
beforeEach(() => {
|
||||
router = jasmine.createSpyObj('router', ['parseUrl', 'createUrlTree']);
|
||||
appConfig = new DefaultAppConfig();
|
||||
guard = new ReloadGuard(router, appConfig);
|
||||
guard = ReloadGuard;
|
||||
});
|
||||
|
||||
describe('canActivate', () => {
|
||||
@@ -31,7 +31,7 @@ describe('ReloadGuard', () => {
|
||||
});
|
||||
|
||||
it('should create a UrlTree with the redirect URL', () => {
|
||||
guard.canActivate(route, undefined);
|
||||
guard(route, undefined, appConfig, router);
|
||||
expect(router.parseUrl).toHaveBeenCalledWith(redirectUrl.substring(1));
|
||||
});
|
||||
});
|
||||
@@ -44,7 +44,7 @@ describe('ReloadGuard', () => {
|
||||
});
|
||||
|
||||
it('should create a UrlTree to home', () => {
|
||||
guard.canActivate(route, undefined);
|
||||
guard(route, undefined, appConfig, router);
|
||||
expect(router.createUrlTree).toHaveBeenCalledWith(['home']);
|
||||
});
|
||||
});
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import {
|
||||
Inject,
|
||||
Injectable,
|
||||
} from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
UrlTree,
|
||||
@@ -13,33 +11,25 @@ import {
|
||||
APP_CONFIG,
|
||||
AppConfig,
|
||||
} from '../../../config/app-config.interface';
|
||||
import { HOME_PAGE_PATH } from '../../app-routing-paths';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
|
||||
/**
|
||||
* A guard redirecting the user to the URL provided in the route's query params
|
||||
* When no redirect url is found, the user is redirected to the homepage
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ReloadGuard {
|
||||
constructor(
|
||||
private router: Router,
|
||||
@Inject(APP_CONFIG) private appConfig: AppConfig,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UrlTree of the URL to redirect to
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): UrlTree {
|
||||
export const ReloadGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
appConfig: AppConfig = inject(APP_CONFIG),
|
||||
router: Router = inject(Router),
|
||||
): UrlTree => {
|
||||
if (isNotEmpty(route.queryParams.redirect)) {
|
||||
const url = route.queryParams.redirect.startsWith(this.appConfig.ui.nameSpace)
|
||||
? route.queryParams.redirect.substring(this.appConfig.ui.nameSpace.length)
|
||||
const url = route.queryParams.redirect.startsWith(appConfig.ui.nameSpace)
|
||||
? route.queryParams.redirect.substring(appConfig.ui.nameSpace.length)
|
||||
: route.queryParams.redirect;
|
||||
return this.router.parseUrl(url);
|
||||
return router.parseUrl(url);
|
||||
} else {
|
||||
return this.router.createUrlTree(['home']);
|
||||
return router.createUrlTree([HOME_PAGE_PATH]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -16,7 +16,7 @@ import { ServerCheckGuard } from './server-check.guard';
|
||||
import SpyObj = jasmine.SpyObj;
|
||||
|
||||
describe('ServerCheckGuard', () => {
|
||||
let guard: ServerCheckGuard;
|
||||
let guard: any;
|
||||
let router: Router;
|
||||
let eventSubject: ReplaySubject<RouterEvent>;
|
||||
let rootDataServiceStub: SpyObj<RootDataService>;
|
||||
@@ -39,7 +39,7 @@ describe('ServerCheckGuard', () => {
|
||||
navigateByUrl: jasmine.createSpy('navigateByUrl'),
|
||||
parseUrl: jasmine.createSpy('parseUrl').and.returnValue(redirectUrlTree),
|
||||
} as any;
|
||||
guard = new ServerCheckGuard(router, rootDataServiceStub);
|
||||
guard = ServerCheckGuard;
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
@@ -53,7 +53,7 @@ describe('ServerCheckGuard', () => {
|
||||
|
||||
it('should return true', () => {
|
||||
testScheduler.run(({ expectObservable }) => {
|
||||
const result$ = guard.canActivateChild({} as any, {} as any);
|
||||
const result$ = guard({} as any, {} as any, rootDataServiceStub, router);
|
||||
expectObservable(result$).toBe('(a|)', { a: true });
|
||||
});
|
||||
});
|
||||
@@ -66,14 +66,14 @@ describe('ServerCheckGuard', () => {
|
||||
|
||||
it('should return a UrlTree with the route to the 500 error page', () => {
|
||||
testScheduler.run(({ expectObservable }) => {
|
||||
const result$ = guard.canActivateChild({} as any, {} as any);
|
||||
const result$ = guard({} as any, {} as any, rootDataServiceStub, router);
|
||||
expectObservable(result$).toBe('(b|)', { b: redirectUrlTree });
|
||||
});
|
||||
expect(router.parseUrl).toHaveBeenCalledWith('/500');
|
||||
});
|
||||
});
|
||||
|
||||
describe(`listenForRouteChanges`, () => {
|
||||
xdescribe(`listenForRouteChanges`, () => {
|
||||
it(`should invalidate the root cache, when the method is first called`, () => {
|
||||
testScheduler.run(() => {
|
||||
guard.listenForRouteChanges();
|
||||
|
@@ -1,14 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
NavigationStart,
|
||||
CanActivateChildFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
UrlTree,
|
||||
} from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import {
|
||||
filter,
|
||||
map,
|
||||
take,
|
||||
} from 'rxjs/operators';
|
||||
@@ -16,52 +15,18 @@ import {
|
||||
import { getPageInternalServerErrorRoute } from '../../app-routing-paths';
|
||||
import { RootDataService } from '../data/root-data.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
/**
|
||||
* A guard that checks if root api endpoint is reachable.
|
||||
* If not redirect to 500 error page
|
||||
*/
|
||||
export class ServerCheckGuard {
|
||||
constructor(private router: Router, private rootDataService: RootDataService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* True when root api endpoint is reachable.
|
||||
*/
|
||||
canActivateChild(
|
||||
export const ServerCheckGuard: CanActivateChildFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Observable<boolean | UrlTree> {
|
||||
|
||||
return this.rootDataService.checkServerAvailability().pipe(
|
||||
rootDataService: RootDataService = inject(RootDataService),
|
||||
router: Router = inject(Router),
|
||||
): Observable<boolean | UrlTree> => {
|
||||
return rootDataService.checkServerAvailability().pipe(
|
||||
take(1),
|
||||
map((isAvailable: boolean) => {
|
||||
if (!isAvailable) {
|
||||
return this.router.parseUrl(getPageInternalServerErrorRoute());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}),
|
||||
map((isAvailable: boolean) => isAvailable ? true : router.parseUrl(getPageInternalServerErrorRoute())),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to all router events. Every time a new navigation starts, invalidate the cache
|
||||
* for the root endpoint. That way we retrieve it once per routing operation to ensure the
|
||||
* backend is not down. But if the guard is called multiple times during the same routing
|
||||
* operation, the cached version is used.
|
||||
*/
|
||||
listenForRouteChanges(): void {
|
||||
// we'll always be too late for the first NavigationStart event with the router subscribe below,
|
||||
// so this statement is for the very first route operation.
|
||||
this.rootDataService.invalidateRootCache();
|
||||
|
||||
this.router.events.pipe(
|
||||
filter(event => event instanceof NavigationStart),
|
||||
).subscribe(() => {
|
||||
this.rootDataService.invalidateRootCache();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -12,7 +12,7 @@ describe('LookupGuard', () => {
|
||||
findByIdAndIDType: jasmine.createSpy('findByIdAndIDType').and.returnValue(observableOf({ hasFailed: false,
|
||||
hasSucceeded: true })),
|
||||
};
|
||||
guard = new LookupGuard(dsoService);
|
||||
guard = LookupGuard;
|
||||
});
|
||||
|
||||
it('should call findByIdAndIDType with handle params', () => {
|
||||
@@ -22,7 +22,7 @@ describe('LookupGuard', () => {
|
||||
idType: '123456789',
|
||||
},
|
||||
};
|
||||
guard.canActivate(scopedRoute as any, undefined);
|
||||
guard(scopedRoute as any, undefined, dsoService);
|
||||
expect(dsoService.findByIdAndIDType).toHaveBeenCalledWith('hdl:123456789/1234', IdentifierType.HANDLE);
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('LookupGuard', () => {
|
||||
idType: 'handle',
|
||||
},
|
||||
};
|
||||
guard.canActivate(scopedRoute as any, undefined);
|
||||
guard(scopedRoute as any, undefined, dsoService);
|
||||
expect(dsoService.findByIdAndIDType).toHaveBeenCalledWith('hdl:123456789%2F1234', IdentifierType.HANDLE);
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('LookupGuard', () => {
|
||||
idType: 'uuid',
|
||||
},
|
||||
};
|
||||
guard.canActivate(scopedRoute as any, undefined);
|
||||
guard(scopedRoute as any, undefined, dsoService);
|
||||
expect(dsoService.findByIdAndIDType).toHaveBeenCalledWith('34cfed7c-f597-49ef-9cbe-ea351f0023c2', IdentifierType.UUID);
|
||||
});
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
@@ -16,22 +17,18 @@ interface LookupParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LookupGuard {
|
||||
|
||||
constructor(private dsoService: DsoRedirectService) {
|
||||
}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
const params = this.getLookupParams(route);
|
||||
return this.dsoService.findByIdAndIDType(params.id, params.type).pipe(
|
||||
export const LookupGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
dsoService: DsoRedirectService = inject(DsoRedirectService),
|
||||
): Observable<boolean> => {
|
||||
const params = getLookupParams(route);
|
||||
return dsoService.findByIdAndIDType(params.id, params.type).pipe(
|
||||
map((response: RemoteData<DSpaceObject>) => response.hasFailed),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private getLookupParams(route: ActivatedRouteSnapshot): LookupParams {
|
||||
function getLookupParams(route: ActivatedRouteSnapshot): LookupParams {
|
||||
let type;
|
||||
let id;
|
||||
const idType = route.params.idType;
|
||||
@@ -55,5 +52,4 @@ export class LookupGuard {
|
||||
type: type,
|
||||
id: id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
NavigationExtras,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
@@ -18,28 +19,19 @@ import { MYDSPACE_ROUTE } from './my-dspace-page.component';
|
||||
|
||||
/**
|
||||
* Prevent unauthorized activating and loading of mydspace configuration
|
||||
* @class MyDSpaceGuard
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class MyDSpaceGuard {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
constructor(private configurationService: MyDSpaceConfigurationService, private router: Router) {
|
||||
}
|
||||
|
||||
/**
|
||||
* True when configuration is valid
|
||||
* @method canActivate
|
||||
*/
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
return this.configurationService.getAvailableConfigurationTypes().pipe(
|
||||
export const MyDSpaceGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
configurationService: MyDSpaceConfigurationService = inject(MyDSpaceConfigurationService),
|
||||
router: Router = inject(Router),
|
||||
): Observable<boolean> => {
|
||||
return configurationService.getAvailableConfigurationTypes().pipe(
|
||||
first(),
|
||||
map((configurationList) => this.validateConfigurationParam(route.queryParamMap.get('configuration'), configurationList)));
|
||||
}
|
||||
map((configurationList) => validateConfigurationParam(route.queryParamMap.get('configuration'), configurationList)));
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Check if the given configuration is present in the list of those available
|
||||
*
|
||||
* @param configuration
|
||||
@@ -48,7 +40,7 @@ export class MyDSpaceGuard {
|
||||
* the list of available configuration
|
||||
*
|
||||
*/
|
||||
private validateConfigurationParam(configuration: string, configurationList: MyDSpaceConfigurationValueType[]): boolean {
|
||||
function validateConfigurationParam(configuration: string, configurationList: MyDSpaceConfigurationValueType[]): boolean {
|
||||
const configurationDefault: string = configurationList[0];
|
||||
if (isEmpty(configuration) || !configurationList.includes(configuration as MyDSpaceConfigurationValueType)) {
|
||||
// If configuration param is empty or is not included in available configurations redirect to a default configuration value
|
||||
@@ -61,5 +53,4 @@ export class MyDSpaceGuard {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ import {
|
||||
import { RegistrationGuard } from './registration.guard';
|
||||
|
||||
describe('RegistrationGuard', () => {
|
||||
let guard: RegistrationGuard;
|
||||
let guard: any;
|
||||
|
||||
let epersonRegistrationService: EpersonRegistrationService;
|
||||
let router: Router;
|
||||
@@ -65,7 +65,7 @@ describe('RegistrationGuard', () => {
|
||||
setRedirectUrl: {},
|
||||
});
|
||||
|
||||
guard = new RegistrationGuard(epersonRegistrationService, router, authService);
|
||||
guard = RegistrationGuard;
|
||||
});
|
||||
|
||||
describe('canActivate', () => {
|
||||
@@ -75,21 +75,21 @@ describe('RegistrationGuard', () => {
|
||||
});
|
||||
|
||||
it('should return true', (done) => {
|
||||
guard.canActivate(route, state).subscribe((result) => {
|
||||
guard(route, state, authService, epersonRegistrationService, router).subscribe((result) => {
|
||||
expect(result).toEqual(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add the response to the route\'s data', (done) => {
|
||||
guard.canActivate(route, state).subscribe(() => {
|
||||
guard(route, state, authService, epersonRegistrationService, router).subscribe(() => {
|
||||
expect(route.data).toEqual({ ...startingRouteData, registration: registrationRD });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not redirect', (done) => {
|
||||
guard.canActivate(route, state).subscribe(() => {
|
||||
guard(route, state, authService, epersonRegistrationService, router).subscribe(() => {
|
||||
expect(router.navigateByUrl).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
@@ -102,7 +102,7 @@ describe('RegistrationGuard', () => {
|
||||
});
|
||||
|
||||
it('should redirect', () => {
|
||||
guard.canActivate(route, state).subscribe();
|
||||
guard(route, state, authService, epersonRegistrationService, router).subscribe();
|
||||
expect(router.navigateByUrl).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
@@ -12,37 +13,25 @@ import { EpersonRegistrationService } from '../core/data/eperson-registration.se
|
||||
import { redirectOn4xx } from '../core/shared/authorized.operators';
|
||||
import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
/**
|
||||
* A guard responsible for redirecting to 4xx pages upon retrieving a Registration object
|
||||
* The guard also adds the resulting RemoteData<Registration> object to the route's data for further usage in components
|
||||
* The reason this is a guard and not a resolver, is because it has to run before the EndUserAgreementCookieGuard
|
||||
*/
|
||||
export class RegistrationGuard {
|
||||
constructor(private epersonRegistrationService: EpersonRegistrationService,
|
||||
private router: Router,
|
||||
private authService: AuthService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user activate the route? Returns true if the provided token resolves to an existing Registration, false if
|
||||
* not. Redirects to 4xx page on 4xx error. Adds the resulting RemoteData<Registration> object to the route's
|
||||
* data.registration property
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
export const RegistrationGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
authService: AuthService = inject(AuthService),
|
||||
epersonRegistrationService: EpersonRegistrationService = inject(EpersonRegistrationService),
|
||||
router: Router = inject(Router),
|
||||
): Observable<boolean> => {
|
||||
const token = route.params.token;
|
||||
return this.epersonRegistrationService.searchByToken(token).pipe(
|
||||
return epersonRegistrationService.searchByToken(token).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
redirectOn4xx(this.router, this.authService),
|
||||
redirectOn4xx(router, authService),
|
||||
map((rd) => {
|
||||
route.data = { ...route.data, registration: rd };
|
||||
return rd.hasSucceeded;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
@@ -1,25 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
CanActivateFn,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
/**
|
||||
* Assemble the correct i18n key for the configuration search page's title depending on the current route's configuration parameter.
|
||||
* The format of the key will be "{configuration}.search.title" with:
|
||||
* - configuration: The current configuration stored in route.params
|
||||
*/
|
||||
export class ConfigurationSearchPageGuard {
|
||||
canActivate(
|
||||
export const ConfigurationSearchPageGuard: CanActivateFn = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
|
||||
state: RouterStateSnapshot,
|
||||
): boolean => {
|
||||
const configuration = route.params.configuration;
|
||||
|
||||
const newTitle = configuration + '.search.title';
|
||||
const newTitle = `${configuration}.search.title`;
|
||||
|
||||
route.data = { title: newTitle };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -10,6 +10,10 @@ import {
|
||||
Injectable,
|
||||
TransferState,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
NavigationStart,
|
||||
Router,
|
||||
} from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import {
|
||||
@@ -30,7 +34,6 @@ import { coreSelector } from '../../app/core/core.selectors';
|
||||
import { RootDataService } from '../../app/core/data/root-data.service';
|
||||
import { LocaleService } from '../../app/core/locale/locale.service';
|
||||
import { MetadataService } from '../../app/core/metadata/metadata.service';
|
||||
import { ServerCheckGuard } from '../../app/core/server-check/server-check.guard';
|
||||
import { CorrelationIdService } from '../../app/correlation-id/correlation-id.service';
|
||||
import { InitService } from '../../app/init.service';
|
||||
import { KlaroService } from '../../app/shared/cookies/klaro.service';
|
||||
@@ -76,7 +79,7 @@ export class BrowserInitService extends InitService {
|
||||
protected themeService: ThemeService,
|
||||
protected menuService: MenuService,
|
||||
private rootDataService: RootDataService,
|
||||
protected serverCheckGuard: ServerCheckGuard,
|
||||
protected router: Router,
|
||||
) {
|
||||
super(
|
||||
store,
|
||||
@@ -198,7 +201,25 @@ export class BrowserInitService extends InitService {
|
||||
*/
|
||||
protected initRouteListeners(): void {
|
||||
super.initRouteListeners();
|
||||
this.serverCheckGuard.listenForRouteChanges();
|
||||
this.listenForRouteChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to all router events. Every time a new navigation starts, invalidate the cache
|
||||
* for the root endpoint. That way we retrieve it once per routing operation to ensure the
|
||||
* backend is not down. But if the guard is called multiple times during the same routing
|
||||
* operation, the cached version is used.
|
||||
*/
|
||||
protected listenForRouteChanges(): void {
|
||||
// we'll always be too late for the first NavigationStart event with the router subscribe below,
|
||||
// so this statement is for the very first route operation.
|
||||
this.rootDataService.invalidateRootCache();
|
||||
|
||||
this.router.events.pipe(
|
||||
filter(event => event instanceof NavigationStart),
|
||||
).subscribe(() => {
|
||||
this.rootDataService.invalidateRootCache();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user