mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #1546 from atmire/Issue-1136-Password-Registration-link-fixes
Redirect to 404 page for forgot password or registration link with used tokens
This commit is contained in:
@@ -90,10 +90,12 @@ describe('EpersonRegistrationService', () => {
|
|||||||
const expected = service.searchByToken('test-token');
|
const expected = service.searchByToken('test-token');
|
||||||
|
|
||||||
expect(expected).toBeObservable(cold('(a|)', {
|
expect(expected).toBeObservable(cold('(a|)', {
|
||||||
a: Object.assign(new Registration(), {
|
a: jasmine.objectContaining({
|
||||||
email: registrationWithUser.email,
|
payload: Object.assign(new Registration(), {
|
||||||
token: 'test-token',
|
email: registrationWithUser.email,
|
||||||
user: registrationWithUser.user
|
token: 'test-token',
|
||||||
|
user: registrationWithUser.user
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@@ -79,7 +79,7 @@ export class EpersonRegistrationService {
|
|||||||
* Search a registration based on the provided token
|
* Search a registration based on the provided token
|
||||||
* @param token
|
* @param token
|
||||||
*/
|
*/
|
||||||
searchByToken(token: string): Observable<Registration> {
|
searchByToken(token: string): Observable<RemoteData<Registration>> {
|
||||||
const requestId = this.requestService.generateRequestId();
|
const requestId = this.requestService.generateRequestId();
|
||||||
|
|
||||||
const href$ = this.getTokenSearchEndpoint(token).pipe(
|
const href$ = this.getTokenSearchEndpoint(token).pipe(
|
||||||
@@ -97,15 +97,14 @@ export class EpersonRegistrationService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return this.rdbService.buildSingle<Registration>(href$).pipe(
|
return this.rdbService.buildSingle<Registration>(href$).pipe(
|
||||||
skipWhile((rd: RemoteData<Registration>) => rd.isStale),
|
map((rd) => {
|
||||||
getFirstSucceededRemoteData(),
|
if (rd.hasSucceeded && hasValue(rd.payload)) {
|
||||||
map((restResponse: RemoteData<Registration>) => {
|
return Object.assign(rd, { payload: Object.assign(rd.payload, { token }) });
|
||||||
return Object.assign(new Registration(), {
|
} else {
|
||||||
email: restResponse.payload.email, token: token, user: restResponse.payload.user
|
return rd;
|
||||||
});
|
}
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<div class="container">
|
<div class="container" *ngIf="(registration$ |async)">
|
||||||
<h3 class="mb-4">{{'forgot-password.form.head' | translate}}</h3>
|
<h3 class="mb-4">{{'forgot-password.form.head' | translate}}</h3>
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header">{{'forgot-password.form.identification.header' | translate}}</div>
|
<div class="card-header">{{'forgot-password.form.identification.header' | translate}}</div>
|
||||||
|
@@ -16,7 +16,11 @@ import { Registration } from '../../core/shared/registration.model';
|
|||||||
import { ForgotPasswordFormComponent } from './forgot-password-form.component';
|
import { ForgotPasswordFormComponent } from './forgot-password-form.component';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { AuthenticateAction } from '../../core/auth/auth.actions';
|
import { AuthenticateAction } from '../../core/auth/auth.actions';
|
||||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
import {
|
||||||
|
createFailedRemoteDataObject$,
|
||||||
|
createSuccessfulRemoteDataObject,
|
||||||
|
createSuccessfulRemoteDataObject$
|
||||||
|
} from '../../shared/remote-data.utils';
|
||||||
|
|
||||||
describe('ForgotPasswordFormComponent', () => {
|
describe('ForgotPasswordFormComponent', () => {
|
||||||
let comp: ForgotPasswordFormComponent;
|
let comp: ForgotPasswordFormComponent;
|
||||||
@@ -36,7 +40,7 @@ describe('ForgotPasswordFormComponent', () => {
|
|||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
|
|
||||||
route = {data: observableOf({registration: registration})};
|
route = {data: observableOf({registration: createSuccessfulRemoteDataObject(registration)})};
|
||||||
router = new RouterStub();
|
router = new RouterStub();
|
||||||
notificationsService = new NotificationsServiceStub();
|
notificationsService = new NotificationsServiceStub();
|
||||||
|
|
||||||
|
@@ -11,7 +11,10 @@ import { Store } from '@ngrx/store';
|
|||||||
import { CoreState } from '../../core/core.reducers';
|
import { CoreState } from '../../core/core.reducers';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
import {
|
||||||
|
getFirstCompletedRemoteData,
|
||||||
|
getFirstSucceededRemoteDataPayload,
|
||||||
|
} from '../../core/shared/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-forgot-password-form',
|
selector: 'ds-forgot-password-form',
|
||||||
@@ -48,7 +51,8 @@ export class ForgotPasswordFormComponent {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.registration$ = this.route.data.pipe(
|
this.registration$ = this.route.data.pipe(
|
||||||
map((data) => data.registration as Registration),
|
map((data) => data.registration as RemoteData<Registration>),
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
);
|
);
|
||||||
this.registration$.subscribe((registration: Registration) => {
|
this.registration$.subscribe((registration: Registration) => {
|
||||||
this.email = registration.email;
|
this.email = registration.email;
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { ItemPageResolver } from '../item-page/item-page.resolver';
|
import { ItemPageResolver } from '../item-page/item-page.resolver';
|
||||||
import { RegistrationResolver } from '../register-email-form/registration.resolver';
|
|
||||||
import { ThemedForgotPasswordFormComponent } from './forgot-password-form/themed-forgot-password-form.component';
|
import { ThemedForgotPasswordFormComponent } from './forgot-password-form/themed-forgot-password-form.component';
|
||||||
import { ThemedForgotEmailComponent } from './forgot-password-email/themed-forgot-email.component';
|
import { ThemedForgotEmailComponent } from './forgot-password-email/themed-forgot-email.component';
|
||||||
|
import { RegistrationGuard } from '../register-page/registration.guard';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -16,12 +16,11 @@ import { ThemedForgotEmailComponent } from './forgot-password-email/themed-forgo
|
|||||||
{
|
{
|
||||||
path: ':token',
|
path: ':token',
|
||||||
component: ThemedForgotPasswordFormComponent,
|
component: ThemedForgotPasswordFormComponent,
|
||||||
resolve: {registration: RegistrationResolver}
|
canActivate: [ RegistrationGuard ],
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
RegistrationResolver,
|
|
||||||
ItemPageResolver,
|
ItemPageResolver,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { RegistrationResolver } from './registration.resolver';
|
import { RegistrationResolver } from './registration.resolver';
|
||||||
import { EpersonRegistrationService } from '../core/data/eperson-registration.service';
|
import { EpersonRegistrationService } from '../core/data/eperson-registration.service';
|
||||||
import { of as observableOf } from 'rxjs';
|
|
||||||
import { Registration } from '../core/shared/registration.model';
|
import { Registration } from '../core/shared/registration.model';
|
||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||||
|
|
||||||
describe('RegistrationResolver', () => {
|
describe('RegistrationResolver', () => {
|
||||||
let resolver: RegistrationResolver;
|
let resolver: RegistrationResolver;
|
||||||
@@ -13,7 +13,7 @@ describe('RegistrationResolver', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
epersonRegistrationService = jasmine.createSpyObj('epersonRegistrationService', {
|
epersonRegistrationService = jasmine.createSpyObj('epersonRegistrationService', {
|
||||||
searchByToken: observableOf(registration)
|
searchByToken: createSuccessfulRemoteDataObject$(registration)
|
||||||
});
|
});
|
||||||
resolver = new RegistrationResolver(epersonRegistrationService);
|
resolver = new RegistrationResolver(epersonRegistrationService);
|
||||||
});
|
});
|
||||||
@@ -23,9 +23,9 @@ describe('RegistrationResolver', () => {
|
|||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(resolved) => {
|
(resolved) => {
|
||||||
expect(resolved.token).toEqual(token);
|
expect(resolved.payload.token).toEqual(token);
|
||||||
expect(resolved.email).toEqual('test@email.org');
|
expect(resolved.payload.email).toEqual('test@email.org');
|
||||||
expect(resolved.user).toEqual('user-uuid');
|
expect(resolved.payload.user).toEqual('user-uuid');
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -3,18 +3,22 @@ import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/r
|
|||||||
import { EpersonRegistrationService } from '../core/data/eperson-registration.service';
|
import { EpersonRegistrationService } from '../core/data/eperson-registration.service';
|
||||||
import { Registration } from '../core/shared/registration.model';
|
import { Registration } from '../core/shared/registration.model';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
import { RemoteData } from '../core/data/remote-data';
|
||||||
|
import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
/**
|
/**
|
||||||
* Resolver to resolve a Registration object based on the provided token
|
* Resolver to resolve a Registration object based on the provided token
|
||||||
*/
|
*/
|
||||||
export class RegistrationResolver implements Resolve<Registration> {
|
export class RegistrationResolver implements Resolve<RemoteData<Registration>> {
|
||||||
|
|
||||||
constructor(private epersonRegistrationService: EpersonRegistrationService) {
|
constructor(private epersonRegistrationService: EpersonRegistrationService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Registration> {
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Registration>> {
|
||||||
const token = route.params.token;
|
const token = route.params.token;
|
||||||
return this.epersonRegistrationService.searchByToken(token);
|
return this.epersonRegistrationService.searchByToken(token).pipe(
|
||||||
|
getFirstCompletedRemoteData(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<div class="container">
|
<div class="container" *ngIf="(registration$ |async)">
|
||||||
<h3 class="mb-4">{{'register-page.create-profile.header' | translate}}</h3>
|
<h3 class="mb-4">{{'register-page.create-profile.header' | translate}}</h3>
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header">{{'register-page.create-profile.identification.header' | translate}}</div>
|
<div class="card-header">{{'register-page.create-profile.identification.header' | translate}}</div>
|
||||||
|
@@ -21,7 +21,11 @@ import {
|
|||||||
END_USER_AGREEMENT_METADATA_FIELD,
|
END_USER_AGREEMENT_METADATA_FIELD,
|
||||||
EndUserAgreementService
|
EndUserAgreementService
|
||||||
} from '../../core/end-user-agreement/end-user-agreement.service';
|
} from '../../core/end-user-agreement/end-user-agreement.service';
|
||||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
import {
|
||||||
|
createFailedRemoteDataObject$,
|
||||||
|
createSuccessfulRemoteDataObject,
|
||||||
|
createSuccessfulRemoteDataObject$
|
||||||
|
} from '../../shared/remote-data.utils';
|
||||||
|
|
||||||
describe('CreateProfileComponent', () => {
|
describe('CreateProfileComponent', () => {
|
||||||
let comp: CreateProfileComponent;
|
let comp: CreateProfileComponent;
|
||||||
@@ -106,7 +110,7 @@ describe('CreateProfileComponent', () => {
|
|||||||
};
|
};
|
||||||
epersonWithAgreement = Object.assign(new EPerson(), valuesWithAgreement);
|
epersonWithAgreement = Object.assign(new EPerson(), valuesWithAgreement);
|
||||||
|
|
||||||
route = {data: observableOf({registration: registration})};
|
route = {data: observableOf({registration: createSuccessfulRemoteDataObject(registration)})};
|
||||||
router = new RouterStub();
|
router = new RouterStub();
|
||||||
notificationsService = new NotificationsServiceStub();
|
notificationsService = new NotificationsServiceStub();
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ import {
|
|||||||
END_USER_AGREEMENT_METADATA_FIELD,
|
END_USER_AGREEMENT_METADATA_FIELD,
|
||||||
EndUserAgreementService
|
EndUserAgreementService
|
||||||
} from '../../core/end-user-agreement/end-user-agreement.service';
|
} from '../../core/end-user-agreement/end-user-agreement.service';
|
||||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that renders the create profile page to be used by a user registering through a token
|
* Component that renders the create profile page to be used by a user registering through a token
|
||||||
@@ -56,7 +56,8 @@ export class CreateProfileComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.registration$ = this.route.data.pipe(
|
this.registration$ = this.route.data.pipe(
|
||||||
map((data) => data.registration as Registration),
|
map((data) => data.registration as RemoteData<Registration>),
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
);
|
);
|
||||||
this.registration$.subscribe((registration: Registration) => {
|
this.registration$.subscribe((registration: Registration) => {
|
||||||
this.email = registration.email;
|
this.email = registration.email;
|
||||||
|
@@ -2,9 +2,9 @@ import { NgModule } from '@angular/core';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { RegisterEmailComponent } from './register-email/register-email.component';
|
import { RegisterEmailComponent } from './register-email/register-email.component';
|
||||||
import { ItemPageResolver } from '../item-page/item-page.resolver';
|
import { ItemPageResolver } from '../item-page/item-page.resolver';
|
||||||
import { RegistrationResolver } from '../register-email-form/registration.resolver';
|
|
||||||
import { EndUserAgreementCookieGuard } from '../core/end-user-agreement/end-user-agreement-cookie.guard';
|
import { EndUserAgreementCookieGuard } from '../core/end-user-agreement/end-user-agreement-cookie.guard';
|
||||||
import { ThemedCreateProfileComponent } from './create-profile/themed-create-profile.component';
|
import { ThemedCreateProfileComponent } from './create-profile/themed-create-profile.component';
|
||||||
|
import { RegistrationGuard } from './registration.guard';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -17,13 +17,14 @@ import { ThemedCreateProfileComponent } from './create-profile/themed-create-pro
|
|||||||
{
|
{
|
||||||
path: ':token',
|
path: ':token',
|
||||||
component: ThemedCreateProfileComponent,
|
component: ThemedCreateProfileComponent,
|
||||||
resolve: {registration: RegistrationResolver},
|
canActivate: [
|
||||||
canActivate: [EndUserAgreementCookieGuard]
|
RegistrationGuard,
|
||||||
|
EndUserAgreementCookieGuard,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
RegistrationResolver,
|
|
||||||
ItemPageResolver
|
ItemPageResolver
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
106
src/app/register-page/registration.guard.spec.ts
Normal file
106
src/app/register-page/registration.guard.spec.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { RegistrationGuard } from './registration.guard';
|
||||||
|
import { EpersonRegistrationService } from '../core/data/eperson-registration.service';
|
||||||
|
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
|
import { AuthService } from '../core/auth/auth.service';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import {
|
||||||
|
createFailedRemoteDataObject$,
|
||||||
|
createSuccessfulRemoteDataObject,
|
||||||
|
} from '../shared/remote-data.utils';
|
||||||
|
import { Registration } from '../core/shared/registration.model';
|
||||||
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
|
import { RemoteData } from '../core/data/remote-data';
|
||||||
|
|
||||||
|
describe('RegistrationGuard', () => {
|
||||||
|
let guard: RegistrationGuard;
|
||||||
|
|
||||||
|
let epersonRegistrationService: EpersonRegistrationService;
|
||||||
|
let router: Router;
|
||||||
|
let authService: AuthService;
|
||||||
|
|
||||||
|
let registration: Registration;
|
||||||
|
let registrationRD: RemoteData<Registration>;
|
||||||
|
let currentUrl: string;
|
||||||
|
|
||||||
|
let startingRouteData: any;
|
||||||
|
let route: ActivatedRouteSnapshot;
|
||||||
|
let state: RouterStateSnapshot;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
registration = Object.assign(new Registration(), {
|
||||||
|
email: 'test@email.com',
|
||||||
|
token: 'testToken',
|
||||||
|
user: 'testUser',
|
||||||
|
});
|
||||||
|
registrationRD = createSuccessfulRemoteDataObject(registration);
|
||||||
|
currentUrl = 'test-current-url';
|
||||||
|
|
||||||
|
startingRouteData = {
|
||||||
|
existingData: 'some-existing-data',
|
||||||
|
};
|
||||||
|
route = Object.assign(new ActivatedRouteSnapshot(), {
|
||||||
|
data: Object.assign({}, startingRouteData),
|
||||||
|
params: {
|
||||||
|
token: 'testToken',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
state = Object.assign({
|
||||||
|
url: currentUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
epersonRegistrationService = jasmine.createSpyObj('epersonRegistrationService', {
|
||||||
|
searchByToken: observableOf(registrationRD),
|
||||||
|
});
|
||||||
|
router = jasmine.createSpyObj('router', {
|
||||||
|
navigateByUrl: Promise.resolve(),
|
||||||
|
}, {
|
||||||
|
url: currentUrl,
|
||||||
|
});
|
||||||
|
authService = jasmine.createSpyObj('authService', {
|
||||||
|
isAuthenticated: observableOf(false),
|
||||||
|
setRedirectUrl: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
guard = new RegistrationGuard(epersonRegistrationService, router, authService);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('canActivate', () => {
|
||||||
|
describe('when searchByToken returns a successful response', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
(epersonRegistrationService.searchByToken as jasmine.Spy).and.returnValue(observableOf(registrationRD));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true', (done) => {
|
||||||
|
guard.canActivate(route, state).subscribe((result) => {
|
||||||
|
expect(result).toEqual(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add the response to the route\'s data', (done) => {
|
||||||
|
guard.canActivate(route, state).subscribe(() => {
|
||||||
|
expect(route.data).toEqual({ ...startingRouteData, registration: registrationRD });
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not redirect', (done) => {
|
||||||
|
guard.canActivate(route, state).subscribe(() => {
|
||||||
|
expect(router.navigateByUrl).not.toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when searchByToken returns a 404 response', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
(epersonRegistrationService.searchByToken as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Not Found', 404));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect', () => {
|
||||||
|
guard.canActivate(route, state).subscribe();
|
||||||
|
expect(router.navigateByUrl).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
43
src/app/register-page/registration.guard.ts
Normal file
43
src/app/register-page/registration.guard.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
|
import { EpersonRegistrationService } from '../core/data/eperson-registration.service';
|
||||||
|
import { AuthService } from '../core/auth/auth.service';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { getFirstCompletedRemoteData, redirectOn4xx } from '../core/shared/operators';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
|
||||||
|
@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 implements CanActivate {
|
||||||
|
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> {
|
||||||
|
const token = route.params.token;
|
||||||
|
return this.epersonRegistrationService.searchByToken(token).pipe(
|
||||||
|
getFirstCompletedRemoteData(),
|
||||||
|
redirectOn4xx(this.router, this.authService),
|
||||||
|
map((rd) => {
|
||||||
|
route.data = { ...route.data, registration: rd };
|
||||||
|
return rd.hasSucceeded;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user