This commit is contained in:
Chris Chen
2026-05-25 17:32:18 -07:00
parent 9b28fbcfb6
commit d5648315a0
262 changed files with 32074 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
# Authentication Guard System
This implementation provides a complete authentication system that automatically detects if a user is logged in and redirects to the login page if not.
## Components
### AuthGuard (`auth.guard.ts`)
- **Purpose**: Protects routes that require authentication
- **Functionality**:
- Checks if user is authenticated using `AuthService.isAuthenticated()`
- Stores attempted URL for redirect after login
- Redirects to `/login` if not authenticated
- Allows access if authenticated
### LoginPage (`login-page.ts`)
- **Purpose**: Full-page login interface for routing
- **Features**:
- Beautiful landing page with company branding
- Integrated login dialog
- Demo credentials display
- Automatic redirect after successful login
- Prevents access if already logged in
## How It Works
### 1. Route Protection
All protected routes use the `AuthGuard`:
```typescript
{ path: 'dashboard', component: Dashboard, canActivate: [AuthGuard] }
```
### 2. Authentication Flow
1. User tries to access protected route
2. `AuthGuard` checks authentication status
3. If not authenticated:
- Stores attempted URL
- Redirects to `/login`
4. If authenticated:
- Allows access to requested route
### 3. Login Process
1. User lands on `/login` page
2. Clicks "Sign In" button
3. Login dialog opens with MFA support
4. After successful login:
- User data stored in localStorage
- Redirected to originally requested URL or dashboard
### 4. Logout Process
1. User clicks logout from header dropdown
2. `AuthService.logout()` clears user data
3. Redirected to `/login` page
## User State Management
### AuthService Features
- **Persistent Login**: User stays logged in across browser sessions
- **State Management**: Reactive user state with RxJS
- **Redirect URLs**: Remembers where user was trying to go
- **localStorage**: Automatic persistence and restoration
### Header Integration
- **Dynamic User Menu**: Shows different options based on auth state
- **User Information**: Displays current user name/email
- **Logout Button**: Easy access to logout functionality
## Route Structure
```
/login - Public login page
/dashboard - Protected (requires auth)
/schedule - Protected (requires auth)
/patients - Protected (requires auth)
... - All other routes protected
/** - Catch-all redirects to /login
```
## Usage Examples
### Adding New Protected Routes
```typescript
{ path: 'new-feature', component: NewFeatureComponent, canActivate: [AuthGuard] }
```
### Checking Auth State in Components
```typescript
constructor(private authService: AuthService) {}
ngOnInit() {
this.authService.currentUser$.subscribe(user => {
if (user) {
// User is logged in
} else {
// User is not logged in
}
});
}
```
### Manual Logout
```typescript
this.authService.logout();
this.router.navigate(['/login']);
```
## Security Features
- **Route Protection**: All sensitive routes are protected
- **Persistent Sessions**: Users stay logged in across browser sessions
- **Automatic Redirects**: Seamless user experience
- **State Validation**: Authentication state is checked on every route change
- **Clean Logout**: Complete session cleanup on logout
## Testing
Use these test credentials:
- **Direct Login**: `user@example.com` / `password123`
- **MFA Required**: `admin@example.com` / `password123` / `123456`
The system will automatically redirect unauthenticated users to the login page and remember where they were trying to go.
+32
View File
@@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { AuthService } from '../../shared/services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
private authService: AuthService,
private router: Router
) { }
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
// Check if user is authenticated
if (this.authService.isAuthenticated()) {
return true;
}
// Store the attempted URL for redirecting after login
this.authService.setRedirectUrl(state.url);
// Redirect to login page
this.router.navigate(['/login']);
return false;
}
}