modcomms/frontend/services/authService.ts
2025-12-18 16:51:27 +00:00

68 lines
2.3 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> => {
const account = msalInstance.getActiveAccount();
if (!account) {
console.error('No active account found');
return null;
}
try {
// Try silent token acquisition first
const response = await msalInstance.acquireTokenSilent({
...apiTokenRequest,
account,
});
return response.accessToken;
} catch (error) {
if (error instanceof InteractionRequiredAuthError) {
// Fallback to popup if silent fails (e.g., token expired, new consent required)
try {
const response = await msalInstance.acquireTokenPopup(apiTokenRequest);
return response.accessToken;
} catch (popupError) {
console.error('Failed to acquire token via popup:', popupError);
return null;
}
}
console.error('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
};
};