mesauth-angular
v1.3.5
Published
Angular helper library to connect to a backend API and SignalR hub to surface the current logged-in user and incoming notifications with dark/light theme support
Downloads
334
Maintainers
Readme
mesauth-angular
Angular helper library to connect to a backend API and SignalR hub to surface the current logged-in user and incoming notifications with dark/light theme support.
Changelog
v1.2.3 (2026-02-11) - Fix Register Page Auto-Redirect
- Fixed 401 redirect on public pages: The interceptor now skips the login redirect when the user is on
/register,/forgot-password, or/reset-passwordpages. Previously, unauthenticated users on the register page were incorrectly redirected to login when any API call returned 401.
v1.2.2 (2026-02-06) - Z-Index Fix for Notification UI
- Fixed notification panel z-index: Increased from
1000to1030to appear above CoreUI sticky table headers (z-index: 1020) - Fixed modal overlay z-index: Increased from
9999to1060to maintain proper layering hierarchy - Better integration with CoreUI/Bootstrap: Follows standard z-index scale (sticky: 1020, modals: 1050+, overlays: 1060+)
v1.2.0 (2026-02-05) - Notification & Auth Interceptor Fix
- Removed route-change user polling:
MesAuthServiceno longer re-fetches the user on everyNavigationEndevent. User is fetched once on app init; SignalR handles real-time updates. This eliminates redundant API calls and notification toast spam on every route change. - Removed
fetchInitialNotifications(): Historical notifications were being emitted throughnotifications$Subject on every user refresh, causing toast popups for old notifications. Thenotifications$observable now only carries truly new real-time events from SignalR. refreshUser()returnsObservable: Callers can now subscribe and wait for user data to load before proceeding (e.g., navigate after login). Previously returnedvoid.- Fixed 401 redirect for expired sessions: Removed the
!isAuthenticatedguard from the interceptor's 401 condition. When a session expires, theBehaviorSubjectstill holds stale user data, so this check was blocking the redirect to login. The!isMeAuthPage,!isLoginPage, and!isAuthPageguards are sufficient to prevent redirect loops.
v1.1.0 (2026-01-21) - Major Update
- 🚀 New
provideMesAuth()Function: Simplified setup with a single function call - ✨ Functional Interceptor: New
mesAuthInterceptorfor better compatibility with standalone apps - 📦 Automatic Initialization:
provideMesAuth()handles service initialization viaAPP_INITIALIZER - 🔧 Simplified API: Just pass
apiBaseUrlanduserBaseUrl- no manual DI required
v1.0.1 (2026-01-21)
- 🔧 Internal refactoring for better module compatibility
v0.2.28 (2026-01-19)
- ✨ Enhanced Avatar Support: Direct
avatarPathusage from user data for instant display without backend calls - 🔄 Improved Avatar Refresh: Timestamp-based cache busting prevents request cancellation issues
- 🎯 Better Change Detection: Signal-based user updates with
ChangeDetectorReffor reliable UI updates
v0.2.27 (2026-01-19)
- 🐛 Fixed avatar refresh issues in header components
- 📦 Improved build process and dependencies
Features
- 🔐 Authentication: User login/logout with API integration
- 🔔 Real-time Notifications: SignalR integration for live notifications
- 🎨 Dark/Light Theme: Automatic theme detection and support
- 🖼️ Avatar Support: Direct API-based avatar loading
- 🍞 Toast Notifications: In-app notification toasts
- 🛡️ HTTP Interceptor: Automatic 401/403 error handling with redirects
Quick Start (v1.1.0+)
1. Install
npm install mesauth-angular2. Configure in app.config.ts (Recommended for Angular 14+)
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideMesAuth, mesAuthInterceptor } from 'mesauth-angular';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
withInterceptors([mesAuthInterceptor]) // Handles 401/403 redirects
),
provideMesAuth({
apiBaseUrl: 'https://mes.kefico.vn/auth',
userBaseUrl: 'https://mes.kefico.vn/x' // For login/403 redirects
})
]
};That's it! The library handles:
- Service initialization via
APP_INITIALIZER HttpClientandRouterinjection automatically- 401 → redirects to
{userBaseUrl}/login?returnUrl=... - 403 → redirects to
{userBaseUrl}/403?returnUrl=...
3. Use in Components
import { MesAuthService } from 'mesauth-angular';
@Component({...})
export class MyComponent {
private auth = inject(MesAuthService);
// Observable streams
currentUser$ = this.auth.currentUser$;
notifications$ = this.auth.notifications$;
logout() {
this.auth.logout().subscribe();
}
}Configuration Options
interface MesAuthConfig {
apiBaseUrl: string; // Required: MesAuth API base URL
userBaseUrl?: string; // Optional: Base URL for login/403 redirects
withCredentials?: boolean; // Optional: Send cookies (default: true)
}Theme Support
The library automatically detects and adapts to your application's theme:
Automatic Theme Detection
The library checks for theme indicators on the <html> element:
class="dark"data-theme="dark"theme="dark"data-coreui-theme="dark"
Dynamic Theme Changes
Theme changes are detected in real-time using MutationObserver, so components automatically update when your app switches themes.
Manual Theme Control
import { ThemeService } from 'mesauth-angular';
// Check current theme
const currentTheme = themeService.currentTheme; // 'light' | 'dark'
// Manually set theme
themeService.setTheme('dark');
// Listen for theme changes
themeService.currentTheme$.subscribe(theme => {
console.log('Theme changed to:', theme);
});Avatar Loading
Avatars are loaded efficiently using multiple strategies:
Primary Method: Direct Path Usage
If the user object contains an avatarPath, it's used directly:
- Full URLs: Used as-is (e.g.,
https://example.com/avatar.jpg) - Relative Paths: Combined with API base URL (e.g.,
/uploads/avatar.jpg→{apiBaseUrl}/uploads/avatar.jpg)
Fallback Method: API Endpoint
If no avatarPath is available, avatars are loaded via API:
- API Endpoint:
GET {apiBaseUrl}/auth/{userId}/avatar - Authentication: Uses the same credentials as other API calls
Cache Busting
Avatar URLs include timestamps to prevent browser caching issues during updates:
- Automatic refresh when user data changes
- Manual refresh triggers for upload/delete operations
Fallback Service
- UI Avatars: Generates initials-based avatars if no user data available
- Authentication: Not required for fallback avatars
Components
Note: All components are standalone and can be imported directly.
ma-user-profile
A reusable Angular component for displaying the current user's profile information, with options for navigation and logout.
Description: Renders user details (e.g., name, avatar) fetched via the MesAuthService. Supports custom event handlers for navigation and logout actions.
Inputs: None (data is sourced from the MesAuthService).
Outputs:
onNavigate: Emits an event when the user triggers navigation (e.g., to a profile page). Pass a handler to define behavior.onLogout: Emits an event when the user logs out. Pass a handler to perform logout logic (e.g., clear tokens, redirect).
Usage Example:
<ma-user-profile (onNavigate)="handleNavigation($event)" (onLogout)="handleLogout()"> </ma-user-profile>In your component's TypeScript file:
handleNavigation(event: any) { // Navigate to user profile page this.router.navigate(['/profile']); } handleLogout() { // Perform logout, e.g., clear session and redirect this.mesAuth.logout(); // Assuming a logout method exists this.router.navigate(['/login']); }
ma-notification-panel
A standalone component for displaying a slide-out notification panel with real-time updates.
Description: Shows a list of notifications, allows marking as read/delete, and integrates with toast notifications for new alerts.
Inputs: None.
Outputs: None (uses internal methods for actions).
Usage Example:
<ma-notification-panel #notificationPanel></ma-notification-panel>In your component:
// To open the panel notificationPanel.open();
Migration Guide
Upgrading from v0.x to v1.1.0+
The setup has been greatly simplified. Here's how to migrate:
Before (v0.x):
// app.config.ts - OLD WAY
import { MesAuthModule, MesAuthService } from 'mesauth-angular';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
importProvidersFrom(MesAuthModule),
{ provide: HTTP_INTERCEPTORS, useClass: MesAuthInterceptor, multi: true }
]
};
// app.component.ts - OLD WAY
export class AppComponent {
constructor() {
this.mesAuthService.init({
apiBaseUrl: '...',
userBaseUrl: '...'
}, inject(HttpClient), inject(Router));
}
}After (v1.1.0+):
// app.config.ts - NEW WAY (everything in one place!)
import { provideMesAuth, mesAuthInterceptor } from 'mesauth-angular';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptors([mesAuthInterceptor])),
provideMesAuth({
apiBaseUrl: 'https://mes.kefico.vn/auth',
userBaseUrl: 'https://mes.kefico.vn/x'
})
]
};
// app.component.ts - No init() needed!
export class AppComponent {
// Just inject and use - no manual initialization required
}Key Changes:
provideMesAuth()replacesMesAuthModule+ manualinit()callmesAuthInterceptor(functional) replacesMesAuthInterceptor(class-based)- No need to inject
HttpClientorRoutermanually - Configuration moved from
AppComponenttoapp.config.ts
Troubleshooting
JIT Compiler Error in Production or AOT Mode
If you encounter an error like "The injectable 'MesAuthService' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available," this typically occurs because:
- The package is being imported directly from source code (e.g., during development) without building it first.
- The client app is running in AOT (Ahead-of-Time) compilation mode, which requires pre-compiled libraries.
Solutions:
Build the package for production/AOT compatibility:
- Ensure you have built the package using
npm run build(which uses ng-packagr or similar to generate AOT-ready code). - Install the built package via npm (e.g., from a local tarball or registry) instead of linking to the source folder.
- Ensure you have built the package using
For development (if you must link to source):
- Switch your Angular app to JIT mode by bootstrapping with
@angular/platform-browser-dynamicinstead of@angular/platform-browser.
- Switch your Angular app to JIT mode by bootstrapping with
Verify imports:
- Ensure you're importing from the built package (e.g.,
import { MesAuthService } from 'mesauth-angular';) and not from thesrcfolder.
- Ensure you're importing from the built package (e.g.,
Components Appear Empty
If components like ma-user or ma-user-profile render as empty:
- Ensure
provideMesAuth()is called in yourapp.config.ts. - Check browser console for logs from components.
- If
currentUseris null, the component shows a login button—verify the API returns user data.
Notes
- The service expects an endpoint
GET {apiBaseUrl}/auth/methat returns the current user. - Avatar endpoint:
GET {apiBaseUrl}/auth/{userId}/avatar - SignalR events used:
ReceiveNotification(adjust to your backend).
