Route Guards
Summary
| Guard | Location | Applied to |
|---|---|---|
|
|
The authenticated shell ( |
|
|
Available for dashboard-only routes |
|
|
|
|
|
|
|
|
Module-level permission gating |
|
|
|
|
|
|
|
|
|
|
|
2FA sub-routes |
|
|
|
|
|
|
|
|
Card operations requiring an active supplier |
AuthGuard
Selects isLoggedIn from the store. When false it navigates to
auth/login?returnUrl=<current url> and the observable emits false.
canActivate(route, state): Observable<boolean> {
return this.store.pipe(
select(isLoggedIn),
tap(loggedIn => {
if (!loggedIn) {
this.router.navigateByUrl(
`${URLS_ROUTER.AUTH.LOGIN}?returnUrl=${state.url}`,
).then();
}
}),
);
}
|
The guard reads store state, not |
DashboardStatusGuard
Declared alongside AuthGuard. It checks whether
user.dashboardStatus.status !== SupplierDashboardStatusType.Onboarding and, if
the supplier is onboarding, navigates to /dashboard.
|
The guard returns |
LogOutGuard
The inverse of AuthGuard. Returns true when the user is logged out, otherwise
returns a UrlTree for /auth/login, keeping an authenticated user off the
login and registration screens.
NewPasswordTokenGuard
Guards /auth/new-password. The reset code arrives as the r query parameter.
-
If a session is already active, dispatch
logout()and allow navigation. -
Otherwise call
AuthService.confirmPasswordReset(verificationCode). -
On error, show a
BannerTypes.WARNINGbanner with the translated message and return aUrlTreefor/auth/login. -
On success, return
true.
ModuleGuard
Reads route.data.moduleName, registers it with NgxPermissionsService and
then checks it. Without a moduleName in route data it returns false.
Provided by AppRoutingModule and ReportsRoutingModule.
DocuSignGuard
|
Despite the name, this guard does not check whether a contract is signed. It is the DocuSign return handler: it detects a redirect back from DocuSign and runs the corresponding business flow before the page renders. |
Applied to /dashboard and /product-offerings — the two pages DocuSign is
configured to return to.
canActivate(route, state): Observable<UrlTree | boolean> {
return this.store.select(selectCurrentUserId).pipe(
filter<string>(Boolean),
exhaustMap(supplierKey => {
if (this.docusignFlowInitialized(route.queryParams)) { (1)
return this.runDocuSignVerificationFlow({
flowType: route.queryParams.flowType,
params: {
data: route.queryParams,
event: route.queryParams.event,
supplierKey,
},
}).pipe(
catchError(() => of(false)),
map(() => this.getUrlTree(route.queryParams?.mode)), (2)
take(1),
);
}
return of(true); (3)
}),
take(1),
);
}
| 1 | "Initialized" here means both event and flowType query parameters are
present — the signature of a DocuSign redirect. |
| 2 | After the flow completes, redirect to a clean URL so the query parameters
cannot be replayed. mode === ProductOfferingsList → /product-offerings,
anything else → /default. |
| 3 | Ordinary navigation with no DocuSign parameters passes straight through. |
The flow itself is dispatched by
DocusignVerificationService.initializeFlow(),
which applies the second, localStorage-based replay guard.
HelpCenterRedirectGuard
A navigation-only guard. It tracks
RouterNavigationEvents.HelpCenterLinkClicked with the current user id, opens
https://help.payability.com/hc/en-us in a new tab, and returns false so
Angular never completes the navigation.
static helpCenterUrl = 'https://help.payability.com/hc/en-us';
canActivate(): boolean {
this.eventLoggerService.track({
additionalProperties: { userId: this.userService.getCurrentUserId() },
eventMessage: RouterNavigationEvents.HelpCenterLinkClicked,
});
window.open(HelpCenterRedirectGuard.helpCenterUrl, '_blank');
return false;
}
TwoFactorAuthenticationGuard
Implements CanActivate, CanActivateChild and CanLoad. Delegates to
TwoFactorAuthenticationService.checkTwoFactorAuthenticationState(force), where
force comes from route.data.force2FAConfirmation.
-
A
skipTwoFactorCheckquery parameter bypasses the check entirely. -
If the check fails and
RouteUrlHelperService.prevUrlis empty — i.e. this was a direct entry rather than in-app navigation — it returns aUrlTreefor/dashboardrather than leaving the user on a dead route.
ManageAccountModule applies it with force2FAConfirmation: true, so account
settings always demand a confirmed second factor.
TwoFactorInfoLoadedGuard
A data-readiness guard. It dispatches fetch2FAInfo() and waits for the
loaded2FAInfo action before allowing activation, so 2FA screens never render
against an empty slice.
NgxPermissionsGuard
From ngx-permissions. Used on the top-level /daily-summary-report route:
{
path: 'daily-summary-report',
loadChildren: () => import('.../daily-summary-page.module').then(m => m.DailySummaryModule),
canActivate: [NgxPermissionsGuard],
data: { permissions: { only: ['REPORTS.DAILY_SUMMARY'] } },
}
The dotted string is the hierarchical permission name built by
permissions.const.ts and loaded into NgxPermissionsService by
GlobalSubscriptionsService. See Permissions System.
SellerCardListGuard
Ensures the Seller Card list has something to show. It dispatches
loadPaymentMethods() and loadAirwallexCards(), waits until both slices report
loaded and not loading, then:
-
if the supplier has p-card payment methods or any Airwallex card →
true; -
otherwise →
UrlTreefornewcard, the card-ordering funnel.