Skip to content

Commit d30b888

Browse files
authored
feat(auth): add SSR handling and redirect behavior to DaffAuthResetPasswordGuard (#4413)
1 parent 1889ea2 commit d30b888

5 files changed

Lines changed: 49 additions & 34 deletions

File tree

libs/auth/routing/src/config/default.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export const DAFF_AUTH_ROUTING_CONFIG_DEFAULT: DaffAuthRoutingConfig = {
66
authCompleteRedirectPath: '/',
77
logoutRedirectPath: '/',
88
tokenExpirationRedirectPath: '/',
9+
resetPasswordRedirectPath: '/',
910
};

libs/auth/routing/src/config/interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,10 @@ export interface DaffAuthRoutingConfig {
3030
* Defaults to `'/'`.
3131
*/
3232
tokenExpirationRedirectPath: string;
33+
34+
/**
35+
* The path to which the user will be redirected when the reset password guard blocks activation.
36+
* Defaults to `'/'`.
37+
*/
38+
resetPasswordRedirectPath: string;
3339
}

libs/auth/routing/src/guards/public_api.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,11 @@ export { MemberOnlyGuard } from './member-only.guard';
22
export { GuestOnlyGuard } from './guest-only.guard';
33
export { DaffAuthResetPasswordGuard } from './reset-password.guard';
44

5-
export { DaffAuthGuestOnlyGuardRedirectUrl } from './guest-only-guard-redirect.token';
6-
export { DaffAuthMemberOnlyGuardRedirectUrl } from './member-only-guard-redirect.token';
5+
export {
6+
DaffAuthGuestOnlyGuardRedirectUrl,
7+
provideDaffAuthGuestOnlyGuardRedirectUrl,
8+
} from './guest-only-guard-redirect.token';
9+
export {
10+
DaffAuthMemberOnlyGuardRedirectUrl,
11+
provideDaffAuthMemberOnlyGuardRedirectUrl,
12+
} from './member-only-guard-redirect.token';

libs/auth/routing/src/guards/reset-password.guard.spec.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ import {
77
import {
88
ActivatedRoute,
99
Router,
10+
UrlTree,
1011
} from '@angular/router';
1112
import { RouterTestingModule } from '@angular/router/testing';
12-
import { Observable } from 'rxjs';
1313

14-
import { DAFF_AUTH_ROUTING_CONFIG } from '@daffodil/auth/routing';
14+
import {
15+
DAFF_AUTH_ROUTING_CONFIG,
16+
provideDaffAuthRoutingConfig,
17+
} from '@daffodil/auth/routing';
1518
import { DaffResetPasswordLanding } from '@daffodil/auth/state';
1619
import {
1720
DaffAuthStateTestingModule,
@@ -34,10 +37,12 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {
3437

3538
let param: string;
3639
let token: string;
40+
let redirectUrl: string;
3741

3842
beforeEach(() => {
3943
param = 'token';
4044
token = '290384runfei9usnrg0ew9rgm';
45+
redirectUrl = 'redirectUrl';
4146

4247
TestBed.configureTestingModule({
4348
imports: [
@@ -60,6 +65,7 @@ describe('@daffodil/auth/routing | DaffAuthResetPasswordGuard', () => {
6065
resetPasswordTokenParam: param,
6166
},
6267
},
68+
provideDaffAuthRoutingConfig({ resetPasswordRedirectPath: redirectUrl }),
6369
],
6470
});
6571

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

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

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

83-
it('should allow activation', done => {
84-
result.subscribe(res => {
85-
expect(res).toBeTrue();
86-
done();
87-
});
89+
it('should allow activation', () => {
90+
expect(result).toBeTrue();
8891
});
8992

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

103-
it('should not allow activation', done => {
104-
result.subscribe(res => {
105-
expect(res).toBeFalse();
106-
done();
107-
});
105+
it('should return the parsed redirect URL', () => {
106+
expect(result.toString()).toEqual(`/${redirectUrl}`);
108107
});
109108

110109
it('should not dispatch DaffResetPasswordLanding with the token', () => {
111-
result.subscribe();
112110
expect(mockFacade.dispatch).not.toHaveBeenCalledWith(new DaffResetPasswordLanding(token));
113111
});
114112
});
Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,45 @@
1+
import { isPlatformServer } from '@angular/common';
12
import {
2-
Inject,
3+
inject,
34
Injectable,
5+
PLATFORM_ID,
46
} from '@angular/core';
5-
import { ActivatedRouteSnapshot } from '@angular/router';
67
import {
7-
Observable,
8-
of,
9-
} from 'rxjs';
8+
ActivatedRouteSnapshot,
9+
CanActivate,
10+
Router,
11+
UrlTree,
12+
} from '@angular/router';
1013

1114
import {
1215
DaffAuthFacade,
1316
DaffResetPasswordLanding,
1417
} from '@daffodil/auth/state';
1518

16-
import {
17-
DaffAuthRoutingConfig,
18-
DAFF_AUTH_ROUTING_CONFIG,
19-
} from '../config/public_api';
19+
import { DAFF_AUTH_ROUTING_CONFIG } from '../config/public_api';
2020

2121
@Injectable({
2222
providedIn: 'any',
2323
})
24-
export class DaffAuthResetPasswordGuard {
25-
constructor(
26-
private facade: DaffAuthFacade,
27-
@Inject(DAFF_AUTH_ROUTING_CONFIG) private config: DaffAuthRoutingConfig,
28-
) {}
24+
export class DaffAuthResetPasswordGuard implements CanActivate {
25+
readonly facade = inject(DaffAuthFacade);
26+
readonly config = inject(DAFF_AUTH_ROUTING_CONFIG);
27+
readonly platformId = inject(PLATFORM_ID);
28+
readonly router = inject(Router);
29+
30+
canActivate(route: ActivatedRouteSnapshot): boolean | UrlTree {
31+
if (isPlatformServer(this.platformId)) {
32+
return true;
33+
}
2934

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

3337
if (!token) {
34-
return of(false);
38+
return this.router.parseUrl(this.config.resetPasswordRedirectPath);
3539
}
3640

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

39-
return of(true);
43+
return true;
4044
}
4145
}

0 commit comments

Comments
 (0)