mesauth-angular
v1.17.2
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
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.6.8 (2026-04-01) - Permission Header Support
- New
withXMaPerm()RxJS operator: ExtractsX-MA-PERMpermission header from HTTP responses, returning{ data, allowedActions }. Use withobserve: 'response'on anyHttpClientcall for zero-overhead permission-gated UI. - New
xMaResource()helper: CombinesrxResourcewith automatic permission extraction for GET endpoints. Returns a signal-based resource with.value().allowedActions. - New
extractXMaPerm()utility: Standalone function to parse theX-MA-PERMheader from anyHttpResponse. - Wildcard
*expansion:extractXMaPermautomatically expands["*"]into all known HTTP methods (GET,POST,PUT,DELETE,PATCH,WEBSOCKET). ALL_ACTIONSconstant: Exported array of all recognized HTTP action strings for permission checks.- Exports:
withXMaPerm,xMaResource,extractXMaPerm,PermissionHeader,RequestConfig,ALL_ACTIONS.
v1.6.0 (2026-03-28) - Approval Module Enhancements
[templateId]locks routing UI: When bound, the routing mode toggle and template dropdown are hidden — the template name is shown as read-only. Role-based steps auto-load candidate pickers fromGET /approval/roles/preview; the requester selects one user per step before submitting. Pass as number binding:[templateId]="6".(approvalSubmitting)output (corrected from single-t typo): Fires before content capture starts. Use it to hide edit controls (*ngIf="!isSubmitting") so they are excluded from the approval snapshot. Angular CD runs after the emit so DOM updates are captured.- Automatic theme support:
<ma-arv-container>appliesThemeServiceinternally — adapts to the app's light/dark theme via@HostBinding('class')with no extra setup. previewRole(orgCode, level)added toMaApprovalService: Fetch candidate users for a role-based approval step.- Callback security: MesAuth.Api sends
X-APP-ID+X-APP-KEYheaders on every callback POST using its own app credentials. Protect callback endpoints with[MesAuth]fromMesAuth.Authorizer.
v1.5.0 (2026-03-24) - Approval Module
- New
<ma-approval-panel>component: Slide-out sidebar with 3 tabs (Processing / Approved / Rejected). Shows all pending approvals requiring action, and recent approved/rejected items. Listens toapprovalEvents$for real-time refresh via SignalR. - New
<ma-arv-container>component: Content capture container for submitting documents for approval. Captures projected<ng-content>as a self-contained HTML document by inlining all computed styles, replacing canvas elements with images, and stripping Angular/script artifacts. Supports ad-hoc step builder and template selector.[templateId]locks routing UI: When bound, the routing mode toggle and template dropdown are hidden — the template name is shown as read-only. Role-based steps auto-load candidate pickers fromGET /approval/roles/preview; the requester selects one user per step before submitting. Pass as number binding:[templateId]="6".(approvalSubmitting)output (corrected from single-t typo): Fires before content capture starts. Use it to hide edit controls (*ngIf="!isSubmitting") so they are excluded from the approval snapshot. Angular CD runs after the emit so DOM updates are captured.- Automatic theme support: Applies
ThemeServiceinternally — adapts to the app's light/dark theme via@HostBinding('class')with no extra setup.
- New
MaApprovalService: Service for all approval API calls —getPendingApprovals(),getMyRequests(),getDashboard(),approve(),reject(),delegate(),getTemplates(),createApproval(),previewRole(orgCode, level), etc. Manual init pattern (same asMesAuthService). - Approval icon in
ma-user-profile: Clipboard/checkmark icon button added between notification bell and avatar. Shows pending count badge. EmitsapprovalClickoutput for panel toggle. approvalEvents$observable inMesAuthService: Real-time SignalR events (ApprovalCompleted,ApprovalStepChanged) exposed as an observable stream.- Callback security: MesAuth.Api sends
X-APP-ID+X-APP-KEYheaders on every callback POST using its own app credentials. Protect callback endpoints with[MesAuth]fromMesAuth.Authorizer. - New exports:
MaApprovalService,MaApprovalPanelComponent,MaArvContainerComponent, and all approval model interfaces/enums.
v1.4.0 (2026-03-20) - Remove Unused Route Registration API
- Removed
registerRoutes(),unregisterRoute(),getRoutesByRole()and related methods fromMesAuthService. Frontend route master/mapping CRUD is handled byMesExtensionSitevia direct HTTP calls, not through the library. getFrontEndRoutes()andUserFrontEndRoutesGrouped/FrontEndRouteinterfaces are retained as the public API for consuming route data.
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
- ✅ Approval Workflows:
<ma-approval-panel>,<ma-arv-container>,MaApprovalServicefor multi-step document approval - 🎨 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).
