Merge pull request #10898 from hurxxxx/fix/update-msal-browser-version

fix: update msal browser version
This commit is contained in:
Timothy Jaeryang Baek 2025-03-04 21:56:22 -08:00 committed by GitHub
commit c2eada36f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 88 additions and 52 deletions

22
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "open-webui",
"version": "0.5.19",
"dependencies": {
"@azure/msal-browser": "^4.5.0",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.6",
"@codemirror/language-data": "^6.5.1",
@ -135,6 +136,27 @@
"node": ">=6.0.0"
}
},
"node_modules/@azure/msal-browser": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.5.0.tgz",
"integrity": "sha512-H7mWmu8yI0n0XxhJobrgncXI6IU5h8DKMiWDHL5y+Dc58cdg26GbmaMUehbUkdKAQV2OTiFa4FUa6Fdu/wIxBg==",
"license": "MIT",
"dependencies": {
"@azure/msal-common": "15.2.0"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-common": {
"version": "15.2.0",
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.0.tgz",
"integrity": "sha512-HiYfGAKthisUYqHG1nImCf/uzcyS31wng3o+CycWLIM9chnYJ9Lk6jZ30Y6YiYYpTQ9+z/FGUpiKKekd3Arc0A==",
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/runtime": {
"version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz",

View File

@ -51,6 +51,7 @@
},
"type": "module",
"dependencies": {
"@azure/msal-browser": "^4.5.0",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.6",
"@codemirror/language-data": "^6.5.1",

View File

@ -1,9 +1,12 @@
import { PublicClientApplication } from '@azure/msal-browser';
import type { PopupRequest } from '@azure/msal-browser';
import { v4 as uuidv4 } from 'uuid';
let CLIENT_ID = '';
async function getCredentials() {
if (CLIENT_ID) return;
const response = await fetch('/api/config');
if (!response.ok) {
throw new Error('Failed to fetch OneDrive credentials');
@ -15,63 +18,69 @@ async function getCredentials() {
}
}
function loadMsalScript(): Promise<void> {
return new Promise((resolve, reject) => {
const win = window;
if (win.msal) {
resolve();
return;
}
const script = document.createElement('script');
script.src = 'https://alcdn.msauth.net/browser/2.19.0/js/msal-browser.min.js';
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject(new Error('Failed to load MSAL script'));
document.head.appendChild(script);
});
}
let msalInstance: any;
let msalInstance: PublicClientApplication | null = null;
// Initialize MSAL authentication
async function initializeMsal() {
if (!CLIENT_ID) {
await getCredentials();
}
const msalParams = {
auth: {
authority: 'https://login.microsoftonline.com/consumers',
clientId: CLIENT_ID
}
};
try {
await loadMsalScript();
const win = window;
msalInstance = new win.msal.PublicClientApplication(msalParams);
if (msalInstance.initialize) {
await msalInstance.initialize();
if (!CLIENT_ID) {
await getCredentials();
}
const msalParams = {
auth: {
authority: 'https://login.microsoftonline.com/consumers',
clientId: CLIENT_ID
}
};
if (!msalInstance) {
msalInstance = new PublicClientApplication(msalParams);
if (msalInstance.initialize) {
await msalInstance.initialize();
}
}
return msalInstance;
} catch (error) {
console.error('MSAL initialization error:', error);
throw new Error('MSAL initialization failed: ' + (error instanceof Error ? error.message : String(error)));
}
}
// Retrieve OneDrive access token
async function getToken(): Promise<string> {
const authParams = { scopes: ['OneDrive.ReadWrite'] };
const authParams: PopupRequest = { scopes: ['OneDrive.ReadWrite'] };
let accessToken = '';
try {
await initializeMsal();
msalInstance = await initializeMsal();
if (!msalInstance) {
throw new Error('MSAL not initialized');
}
const resp = await msalInstance.acquireTokenSilent(authParams);
accessToken = resp.accessToken;
} catch (err) {
const resp = await msalInstance.loginPopup(authParams);
msalInstance.setActiveAccount(resp.account);
if (resp.idToken) {
const resp2 = await msalInstance.acquireTokenSilent(authParams);
accessToken = resp2.accessToken;
if (!msalInstance) {
throw new Error('MSAL not initialized');
}
try {
const resp = await msalInstance.loginPopup(authParams);
msalInstance.setActiveAccount(resp.account);
if (resp.idToken) {
const resp2 = await msalInstance.acquireTokenSilent(authParams);
accessToken = resp2.accessToken;
}
} catch (popupError) {
throw new Error('Failed to login: ' + (popupError instanceof Error ? popupError.message : String(popupError)));
}
}
if (!accessToken) {
throw new Error('Failed to acquire access token');
}
return accessToken;
}
@ -97,6 +106,7 @@ const params = {
}
};
// Download file from OneDrive
async function downloadOneDriveFile(fileInfo: any): Promise<Blob> {
const accessToken = await getToken();
@ -164,7 +174,6 @@ export async function openOneDrivePicker(): Promise<any | null> {
throw new Error('Could not retrieve auth token');
}
} catch (err) {
console.error(err);
channelPort?.postMessage({
result: 'error',
error: { code: 'tokenError', message: 'Failed to get token' },
@ -189,7 +198,6 @@ export async function openOneDrivePicker(): Promise<any | null> {
break;
}
default: {
console.warn('Unsupported command:', command);
channelPort?.postMessage({
result: 'error',
error: { code: 'unsupportedCommand', message: command.command },
@ -220,14 +228,17 @@ export async function openOneDrivePicker(): Promise<any | null> {
if (!authToken) {
return reject(new Error('Failed to acquire access token'));
}
pickerWindow = window.open('', 'OneDrivePicker', 'width=800,height=600');
if (!pickerWindow) {
return reject(new Error('Failed to open OneDrive picker window'));
}
const queryString = new URLSearchParams({
filePicker: JSON.stringify(params)
});
const url = `${baseUrl}?${queryString.toString()}`;
const form = pickerWindow.document.createElement('form');
form.setAttribute('action', url);
form.setAttribute('method', 'POST');
@ -236,11 +247,15 @@ export async function openOneDrivePicker(): Promise<any | null> {
input.setAttribute('name', 'access_token');
input.setAttribute('value', authToken);
form.appendChild(input);
pickerWindow.document.body.appendChild(form);
form.submit();
window.addEventListener('message', handleWindowMessage);
} catch (err) {
if (pickerWindow) pickerWindow.close();
if (pickerWindow) {
pickerWindow.close();
}
reject(err);
}
};
@ -251,18 +266,16 @@ export async function openOneDrivePicker(): Promise<any | null> {
// Pick and download file from OneDrive
export async function pickAndDownloadFile(): Promise<{ blob: Blob; name: string } | null> {
try {
const pickerResult = await openOneDrivePicker();
if (!pickerResult || !pickerResult.items || pickerResult.items.length === 0) {
return null;
}
const selectedFile = pickerResult.items[0];
const blob = await downloadOneDriveFile(selectedFile);
return { blob, name: selectedFile.name };
} catch (error) {
console.error('Error occurred during OneDrive file pick/download:', error);
throw error;
const pickerResult = await openOneDrivePicker();
if (!pickerResult || !pickerResult.items || pickerResult.items.length === 0) {
return null;
}
const selectedFile = pickerResult.items[0];
const blob = await downloadOneDriveFile(selectedFile);
return { blob, name: selectedFile.name };
}
export { downloadOneDriveFile };