171 lines
4.4 KiB
JavaScript
171 lines
4.4 KiB
JavaScript
/**
|
|
* Microsoft Authentication Library (MSAL) wrapper for SSO authentication
|
|
* Provides authentication functions for the video optimizer application
|
|
*/
|
|
|
|
let msalInstance = null;
|
|
let msalConfig = null;
|
|
|
|
const loginRequest = {
|
|
scopes: ["User.Read"]
|
|
};
|
|
|
|
/**
|
|
* Initialize MSAL with configuration from backend
|
|
* @param {Object} config - Azure AD configuration from /api/config
|
|
*/
|
|
async function initAuth(config) {
|
|
if (!config || !config.AZURE_CLIENT_ID || !config.AZURE_TENANT_ID) {
|
|
throw new Error('Invalid Azure AD configuration');
|
|
}
|
|
|
|
msalConfig = {
|
|
auth: {
|
|
clientId: config.AZURE_CLIENT_ID,
|
|
authority: `https://login.microsoftonline.com/${config.AZURE_TENANT_ID}`,
|
|
redirectUri: config.REDIRECT_URI || window.location.origin
|
|
},
|
|
cache: {
|
|
cacheLocation: "sessionStorage", // Re-login required after browser close
|
|
storeAuthStateInCookie: false
|
|
}
|
|
};
|
|
|
|
// Initialize MSAL instance
|
|
msalInstance = new msal.PublicClientApplication(msalConfig);
|
|
|
|
// Initialize the MSAL instance (required in MSAL v3.x)
|
|
await msalInstance.initialize();
|
|
|
|
// Handle redirect promise
|
|
try {
|
|
const response = await msalInstance.handleRedirectPromise();
|
|
if (response) {
|
|
console.log('Authentication successful:', response);
|
|
}
|
|
} catch (error) {
|
|
console.error('Authentication error:', error);
|
|
|
|
// Check if it's an unauthorized user error (not in tenant)
|
|
if (error.errorCode === 'user_cancelled' ||
|
|
error.errorCode === 'access_denied' ||
|
|
error.errorMessage?.includes('AADSTS50020')) {
|
|
throw new Error('Unauthorized: You are not authorized to access this application. Please contact your administrator.');
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if user is authenticated
|
|
* @returns {boolean}
|
|
*/
|
|
function isAuthenticated() {
|
|
if (!msalInstance) {
|
|
return false;
|
|
}
|
|
const accounts = msalInstance.getAllAccounts();
|
|
return accounts.length > 0;
|
|
}
|
|
|
|
/**
|
|
* Get the current user account
|
|
* @returns {Object|null}
|
|
*/
|
|
function getAccount() {
|
|
if (!msalInstance) {
|
|
return null;
|
|
}
|
|
const accounts = msalInstance.getAllAccounts();
|
|
return accounts.length > 0 ? accounts[0] : null;
|
|
}
|
|
|
|
/**
|
|
* Get user email
|
|
* @returns {string|null}
|
|
*/
|
|
function getUserEmail() {
|
|
const account = getAccount();
|
|
return account ? (account.username || account.email || '') : null;
|
|
}
|
|
|
|
/**
|
|
* Get user display name
|
|
* @returns {string|null}
|
|
*/
|
|
function getUserName() {
|
|
const account = getAccount();
|
|
return account ? (account.name || account.username || '') : null;
|
|
}
|
|
|
|
/**
|
|
* Login with redirect
|
|
*/
|
|
async function login() {
|
|
if (!msalInstance) {
|
|
throw new Error('MSAL not initialized. Call initAuth() first.');
|
|
}
|
|
|
|
try {
|
|
await msalInstance.loginRedirect(loginRequest);
|
|
} catch (error) {
|
|
console.error('Login failed:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Logout with redirect
|
|
*/
|
|
async function logout() {
|
|
if (!msalInstance) {
|
|
throw new Error('MSAL not initialized. Call initAuth() first.');
|
|
}
|
|
|
|
try {
|
|
await msalInstance.logoutRedirect({
|
|
postLogoutRedirectUri: window.location.origin
|
|
});
|
|
} catch (error) {
|
|
console.error('Logout failed:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get access token (if needed for API calls)
|
|
* @returns {Promise<string>}
|
|
*/
|
|
async function getAccessToken() {
|
|
if (!msalInstance) {
|
|
throw new Error('MSAL not initialized. Call initAuth() first.');
|
|
}
|
|
|
|
const account = getAccount();
|
|
if (!account) {
|
|
throw new Error('No authenticated user found');
|
|
}
|
|
|
|
try {
|
|
const response = await msalInstance.acquireTokenSilent({
|
|
...loginRequest,
|
|
account: account
|
|
});
|
|
return response.accessToken;
|
|
} catch (error) {
|
|
console.error('Token acquisition failed:', error);
|
|
// If silent token acquisition fails, redirect to login
|
|
await msalInstance.acquireTokenRedirect(loginRequest);
|
|
}
|
|
}
|
|
|
|
// Export functions to window object for global access
|
|
window.initAuth = initAuth;
|
|
window.isAuthenticated = isAuthenticated;
|
|
window.getAccount = getAccount;
|
|
window.getUserEmail = getUserEmail;
|
|
window.getUserName = getUserName;
|
|
window.login = login;
|
|
window.logout = logout;
|
|
window.getAccessToken = getAccessToken;
|