modcomms/frontend/services/authService.ts
michael 04527d65db Add MSAL debug logging to frontend and backend
- Frontend: Set MSAL log level to Info, add [MSAL] prefix
- Frontend: Add [MSAL Auth] logs for token acquisition
- Frontend: Add [MSAL Login] logs for login popup flow
- Backend: Add [MSAL Backend] logs for token verification
- Backend: Add [MSAL Backend] logs for auth dependency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 13:11:30 -06:00

74 lines
2.7 KiB
TypeScript
Executable file

/**
* Authentication service for token management and user info extraction.
*/
import { IPublicClientApplication, InteractionRequiredAuthError } from '@azure/msal-browser';
import { apiTokenRequest } from './authConfig';
/**
* Acquires an access token silently, or via popup if interaction required.
* Use this before making authenticated API calls.
*/
export const getAccessToken = async (msalInstance: IPublicClientApplication): Promise<string | null> => {
console.log('[MSAL Auth] getAccessToken called');
const account = msalInstance.getActiveAccount();
if (!account) {
console.error('[MSAL Auth] No active account found');
return null;
}
console.log('[MSAL Auth] Active account:', account.username);
try {
// Try silent token acquisition first
console.log('[MSAL Auth] Attempting silent token acquisition...');
const response = await msalInstance.acquireTokenSilent({
...apiTokenRequest,
account,
});
console.log('[MSAL Auth] Silent token acquisition successful, expires:', response.expiresOn);
return response.accessToken;
} catch (error) {
if (error instanceof InteractionRequiredAuthError) {
// Fallback to popup if silent fails (e.g., token expired, new consent required)
console.log('[MSAL Auth] Silent acquisition failed, trying popup...');
try {
const response = await msalInstance.acquireTokenPopup(apiTokenRequest);
console.log('[MSAL Auth] Popup token acquisition successful');
return response.accessToken;
} catch (popupError) {
console.error('[MSAL Auth] Failed to acquire token via popup:', popupError);
return null;
}
}
console.error('[MSAL Auth] Failed to acquire token:', error);
return null;
}
};
/**
* User info interface matching Azure AD claims
*/
export interface UserInfo {
name: string;
email: string;
firstName: string;
lastName: string;
accountType: string;
}
/**
* Extract user information from the active account
*/
export const getUserInfo = (msalInstance: IPublicClientApplication): UserInfo | null => {
const account = msalInstance.getActiveAccount();
if (!account) return null;
const idTokenClaims = account.idTokenClaims as Record<string, unknown>;
return {
name: account.name || 'Unknown User',
email: account.username || '',
firstName: (idTokenClaims?.given_name as string) || account.name?.split(' ')[0] || '',
lastName: (idTokenClaims?.family_name as string) || account.name?.split(' ').slice(1).join(' ') || '',
accountType: 'Enterprise User', // Single tenant = enterprise users
};
};