Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/auth/routing/src/config/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export const DAFF_AUTH_ROUTING_CONFIG_DEFAULT: DaffAuthRoutingConfig = {
authCompleteRedirectPath: '/',
logoutRedirectPath: '/',
tokenExpirationRedirectPath: '/',
resetPasswordRedirectPath: '/',
};
6 changes: 6 additions & 0 deletions libs/auth/routing/src/config/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ export interface DaffAuthRoutingConfig {
* Defaults to `'/'`.
*/
tokenExpirationRedirectPath: string;

/**
* The path to which the user will be redirected when the reset password guard blocks activation.
* Defaults to `'/'`.
*/
resetPasswordRedirectPath: string;
}
10 changes: 8 additions & 2 deletions libs/auth/routing/src/guards/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@ export { MemberOnlyGuard } from './member-only.guard';
export { GuestOnlyGuard } from './guest-only.guard';
export { DaffAuthResetPasswordGuard } from './reset-password.guard';

export { DaffAuthGuestOnlyGuardRedirectUrl } from './guest-only-guard-redirect.token';
export { DaffAuthMemberOnlyGuardRedirectUrl } from './member-only-guard-redirect.token';
export {
DaffAuthGuestOnlyGuardRedirectUrl,
provideDaffAuthGuestOnlyGuardRedirectUrl,
} from './guest-only-guard-redirect.token';
export {
DaffAuthMemberOnlyGuardRedirectUrl,
provideDaffAuthMemberOnlyGuardRedirectUrl,
} from './member-only-guard-redirect.token';
28 changes: 13 additions & 15 deletions libs/auth/routing/src/guards/reset-password.guard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import {
import {
ActivatedRoute,
Router,
UrlTree,
} from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable } from 'rxjs';

import { DAFF_AUTH_ROUTING_CONFIG } from '@daffodil/auth/routing';
import {
DAFF_AUTH_ROUTING_CONFIG,
provideDaffAuthRoutingConfig,
} from '@daffodil/auth/routing';
import { DaffResetPasswordLanding } from '@daffodil/auth/state';
import {
DaffAuthStateTestingModule,
Expand All @@ -34,10 +37,12 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {

let param: string;
let token: string;
let redirectUrl: string;

beforeEach(() => {
param = 'token';
token = '290384runfei9usnrg0ew9rgm';
redirectUrl = 'redirectUrl';

TestBed.configureTestingModule({
imports: [
Expand All @@ -60,6 +65,7 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {
resetPasswordTokenParam: param,
},
},
provideDaffAuthRoutingConfig({ resetPasswordRedirectPath: redirectUrl }),
],
});

Expand All @@ -71,7 +77,7 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {
});

describe('canActivate | checking if the route can be activated', () => {
let result: Observable<boolean>;
let result: boolean | UrlTree;

describe('when there is a token set to the param', () => {
beforeEach(fakeAsync(() => {
Expand All @@ -80,15 +86,11 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {
result = guard.canActivate(TestBed.inject(ActivatedRoute).snapshot);
}));

it('should allow activation', done => {
result.subscribe(res => {
expect(res).toBeTrue();
done();
});
it('should allow activation', () => {
expect(result).toBeTrue();
});

it('should dispatch DaffResetPasswordLanding with the token', () => {
result.subscribe();
expect(mockFacade.dispatch).toHaveBeenCalledWith(new DaffResetPasswordLanding(token));
});
});
Expand All @@ -100,15 +102,11 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {
result = guard.canActivate(TestBed.inject(ActivatedRoute).snapshot);
}));

it('should not allow activation', done => {
result.subscribe(res => {
expect(res).toBeFalse();
done();
});
it('should return the parsed redirect URL', () => {
expect(result.toString()).toEqual(`/${redirectUrl}`);
});

it('should not dispatch DaffResetPasswordLanding with the token', () => {
result.subscribe();
expect(mockFacade.dispatch).not.toHaveBeenCalledWith(new DaffResetPasswordLanding(token));
});
});
Expand Down
38 changes: 21 additions & 17 deletions libs/auth/routing/src/guards/reset-password.guard.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
import { isPlatformServer } from '@angular/common';
import {
Inject,
inject,
Injectable,
PLATFORM_ID,
} from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
import {
Observable,
of,
} from 'rxjs';
ActivatedRouteSnapshot,
CanActivate,
Router,
UrlTree,
} from '@angular/router';

import {
DaffAuthFacade,
DaffResetPasswordLanding,
} from '@daffodil/auth/state';

import {
DaffAuthRoutingConfig,
DAFF_AUTH_ROUTING_CONFIG,
} from '../config/public_api';
import { DAFF_AUTH_ROUTING_CONFIG } from '../config/public_api';

@Injectable({
providedIn: 'any',
})
export class DaffAuthResetPasswordGuard {
constructor(
private facade: DaffAuthFacade,
@Inject(DAFF_AUTH_ROUTING_CONFIG) private config: DaffAuthRoutingConfig,
) {}
export class DaffAuthResetPasswordGuard implements CanActivate {
readonly facade = inject(DaffAuthFacade);
readonly config = inject(DAFF_AUTH_ROUTING_CONFIG);
readonly platformId = inject(PLATFORM_ID);
readonly router = inject(Router);

canActivate(route: ActivatedRouteSnapshot): boolean | UrlTree {
if (isPlatformServer(this.platformId)) {
return true;
}

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
const token = route.queryParamMap.get(this.config.resetPasswordTokenParam);

if (!token) {
return of(false);
return this.router.parseUrl(this.config.resetPasswordRedirectPath);
}

this.facade.dispatch(new DaffResetPasswordLanding(token));

return of(true);
return true;
}
}
Loading