Hone logo
Hone
Problems

Secure Angular Routes with Route Guards

Route guards are a crucial component of Angular applications, enabling you to control access to specific routes based on various conditions, such as user authentication or authorization. This challenge will guide you in implementing both CanActivate and CanDeactivate route guards to enhance the security and user experience of your Angular application.

Problem Description

You are tasked with creating an Angular application with two routes: /admin and /profile. The /admin route should only be accessible to authenticated users (simulated by a boolean isAuthenticated flag). The /profile route should prevent users from navigating away if they have unsaved changes in a form (simulated by a boolean hasUnsavedChanges). You need to implement CanActivate and CanDeactivate guards to enforce these restrictions.

Key Requirements:

  • CanActivate Guard for /admin: The AdminGuard should prevent access to the /admin route if isAuthenticated is false.
  • CanDeactivate Guard for /profile: The ProfileGuard should prompt the user to confirm if they want to leave the /profile route if hasUnsavedChanges is true. If the user confirms, navigation should be allowed; otherwise, it should be prevented.
  • Simulated Authentication and Unsaved Changes: For simplicity, use a global isAuthenticated flag (boolean) and a hasUnsavedChanges flag (boolean) to represent authentication status and form changes. These flags should be easily accessible within your guards.
  • User Confirmation: When CanDeactivate is triggered, display a confirmation dialog to the user. The dialog should have "Stay" and "Leave" buttons.
  • Clear Navigation: The application should navigate to the /profile route when the user clicks the "Leave" button in the confirmation dialog.

Expected Behavior:

  • Attempting to access /admin when isAuthenticated is false should redirect the user to a designated "Unauthorized" route (e.g., /unauthorized).
  • Attempting to navigate away from /profile when hasUnsavedChanges is true should display a confirmation dialog.
  • Clicking "Stay" in the confirmation dialog should prevent navigation.
  • Clicking "Leave" in the confirmation dialog should allow navigation to the intended route.

Edge Cases to Consider:

  • What happens if the user refreshes the page while on the /admin route and isAuthenticated is false? (The guard should still prevent access).
  • How should the confirmation dialog be styled and presented to the user? (Basic functionality is sufficient for this challenge).
  • What happens if the user closes the browser window/tab while the confirmation dialog is open? (The guard should still prevent navigation, although the dialog might not be visible).

Examples

Example 1:

Input: isAuthenticated = false, User attempts to navigate to /admin
Output: User is redirected to /unauthorized
Explanation: AdminGuard prevents access because the user is not authenticated.

Example 2:

Input: isAuthenticated = true, hasUnsavedChanges = true, User attempts to navigate away from /profile
Output: A confirmation dialog appears with "Stay" and "Leave" buttons.
Explanation: ProfileGuard triggers the CanDeactivate guard.

Example 3:

Input: isAuthenticated = true, hasUnsavedChanges = false, User attempts to navigate away from /profile
Output: User is navigated away from /profile without any confirmation.
Explanation: ProfileGuard does not trigger the CanDeactivate guard because there are no unsaved changes.

Constraints

  • The application should be a functional Angular application.
  • Use Angular's built-in routing and guard mechanisms.
  • The isAuthenticated and hasUnsavedChanges flags should be easily accessible (e.g., through a service).
  • The confirmation dialog should be implemented using Angular Material Dialog or a similar component library. Basic styling is acceptable.
  • Focus on the core logic of the guards; elaborate UI/UX is not the primary focus.
  • The application should be relatively simple and easy to understand.

Notes

  • Consider using Angular's ActivatedRoute and Router services within your guards to handle navigation.
  • The CanActivate guard should return a boolean or a Promise<boolean>.
  • The CanDeactivate guard should return a boolean or a Promise<boolean>.
  • Think about how to best structure your code to keep the guards clean and maintainable.
  • You can simulate the "Unauthorized" route by simply displaying a message. No need to create a separate component for it.
  • Remember to import necessary modules (e.g., RouterModule, MatDialogModule).
Loading editor...
typescript