mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
chore: format
This commit is contained in:
@@ -279,9 +279,9 @@ export const generateInitialsImage = (name) => {
|
||||
const initials =
|
||||
sanitizedName.length > 0
|
||||
? sanitizedName[0] +
|
||||
(sanitizedName.split(' ').length > 1
|
||||
? sanitizedName[sanitizedName.lastIndexOf(' ') + 1]
|
||||
: '')
|
||||
(sanitizedName.split(' ').length > 1
|
||||
? sanitizedName[sanitizedName.lastIndexOf(' ') + 1]
|
||||
: '')
|
||||
: '';
|
||||
|
||||
ctx.fillText(initials.toUpperCase(), canvas.width / 2, canvas.height / 2);
|
||||
@@ -348,10 +348,10 @@ export const compareVersion = (latest, current) => {
|
||||
return current === '0.0.0'
|
||||
? false
|
||||
: current.localeCompare(latest, undefined, {
|
||||
numeric: true,
|
||||
sensitivity: 'case',
|
||||
caseFirst: 'upper'
|
||||
}) < 0;
|
||||
numeric: true,
|
||||
sensitivity: 'case',
|
||||
caseFirst: 'upper'
|
||||
}) < 0;
|
||||
};
|
||||
|
||||
export const findWordIndices = (text) => {
|
||||
|
||||
@@ -1,266 +1,266 @@
|
||||
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');
|
||||
}
|
||||
const config = await response.json();
|
||||
CLIENT_ID = config.onedrive?.client_id;
|
||||
if (!CLIENT_ID) {
|
||||
throw new Error('OneDrive client ID not configured');
|
||||
}
|
||||
if (CLIENT_ID) return;
|
||||
const response = await fetch('/api/config');
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch OneDrive credentials');
|
||||
}
|
||||
const config = await response.json();
|
||||
CLIENT_ID = config.onedrive?.client_id;
|
||||
if (!CLIENT_ID) {
|
||||
throw new Error('OneDrive client ID not configured');
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
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;
|
||||
|
||||
// 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();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('MSAL initialization error:', error);
|
||||
}
|
||||
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();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('MSAL initialization error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve OneDrive access token
|
||||
async function getToken(): Promise<string> {
|
||||
const authParams = { scopes: ['OneDrive.ReadWrite'] };
|
||||
let accessToken = '';
|
||||
try {
|
||||
await initializeMsal();
|
||||
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;
|
||||
}
|
||||
}
|
||||
return accessToken;
|
||||
const authParams = { scopes: ['OneDrive.ReadWrite'] };
|
||||
let accessToken = '';
|
||||
try {
|
||||
await initializeMsal();
|
||||
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;
|
||||
}
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
const baseUrl = "https://onedrive.live.com/picker";
|
||||
const baseUrl = 'https://onedrive.live.com/picker';
|
||||
const params = {
|
||||
sdk: '8.0',
|
||||
entry: {
|
||||
oneDrive: {
|
||||
files: {}
|
||||
}
|
||||
},
|
||||
authentication: {},
|
||||
messaging: {
|
||||
origin: window?.location?.origin,
|
||||
channelId: crypto.randomUUID()
|
||||
},
|
||||
typesAndSources: {
|
||||
mode: 'files',
|
||||
pivots: {
|
||||
oneDrive: true,
|
||||
recent: true
|
||||
}
|
||||
}
|
||||
sdk: '8.0',
|
||||
entry: {
|
||||
oneDrive: {
|
||||
files: {}
|
||||
}
|
||||
},
|
||||
authentication: {},
|
||||
messaging: {
|
||||
origin: window?.location?.origin,
|
||||
channelId: crypto.randomUUID()
|
||||
},
|
||||
typesAndSources: {
|
||||
mode: 'files',
|
||||
pivots: {
|
||||
oneDrive: true,
|
||||
recent: true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Download file from OneDrive
|
||||
async function downloadOneDriveFile(fileInfo: any): Promise<Blob> {
|
||||
const accessToken = await getToken();
|
||||
if (!accessToken) {
|
||||
throw new Error('Unable to retrieve OneDrive access token.');
|
||||
}
|
||||
const fileInfoUrl = `${fileInfo["@sharePoint.endpoint"]}/drives/${fileInfo.parentReference.driveId}/items/${fileInfo.id}`;
|
||||
const response = await fetch(fileInfoUrl, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch file information.');
|
||||
}
|
||||
const fileData = await response.json();
|
||||
const downloadUrl = fileData['@content.downloadUrl'];
|
||||
const downloadResponse = await fetch(downloadUrl);
|
||||
if (!downloadResponse.ok) {
|
||||
throw new Error('Failed to download file.');
|
||||
}
|
||||
return await downloadResponse.blob();
|
||||
const accessToken = await getToken();
|
||||
if (!accessToken) {
|
||||
throw new Error('Unable to retrieve OneDrive access token.');
|
||||
}
|
||||
const fileInfoUrl = `${fileInfo['@sharePoint.endpoint']}/drives/${fileInfo.parentReference.driveId}/items/${fileInfo.id}`;
|
||||
const response = await fetch(fileInfoUrl, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch file information.');
|
||||
}
|
||||
const fileData = await response.json();
|
||||
const downloadUrl = fileData['@content.downloadUrl'];
|
||||
const downloadResponse = await fetch(downloadUrl);
|
||||
if (!downloadResponse.ok) {
|
||||
throw new Error('Failed to download file.');
|
||||
}
|
||||
return await downloadResponse.blob();
|
||||
}
|
||||
|
||||
// Open OneDrive file picker and return selected file metadata
|
||||
export async function openOneDrivePicker(): Promise<any | null> {
|
||||
if (typeof window === 'undefined') {
|
||||
throw new Error('Not in browser environment');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let pickerWindow: Window | null = null;
|
||||
let channelPort: MessagePort | null = null;
|
||||
if (typeof window === 'undefined') {
|
||||
throw new Error('Not in browser environment');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let pickerWindow: Window | null = null;
|
||||
let channelPort: MessagePort | null = null;
|
||||
|
||||
const handleWindowMessage = (event: MessageEvent) => {
|
||||
if (event.source !== pickerWindow) return;
|
||||
const message = event.data;
|
||||
if (message?.type === 'initialize' && message?.channelId === params.messaging.channelId) {
|
||||
channelPort = event.ports?.[0];
|
||||
if (!channelPort) return;
|
||||
channelPort.addEventListener('message', handlePortMessage);
|
||||
channelPort.start();
|
||||
channelPort.postMessage({ type: 'activate' });
|
||||
}
|
||||
};
|
||||
const handleWindowMessage = (event: MessageEvent) => {
|
||||
if (event.source !== pickerWindow) return;
|
||||
const message = event.data;
|
||||
if (message?.type === 'initialize' && message?.channelId === params.messaging.channelId) {
|
||||
channelPort = event.ports?.[0];
|
||||
if (!channelPort) return;
|
||||
channelPort.addEventListener('message', handlePortMessage);
|
||||
channelPort.start();
|
||||
channelPort.postMessage({ type: 'activate' });
|
||||
}
|
||||
};
|
||||
|
||||
const handlePortMessage = async (portEvent: MessageEvent) => {
|
||||
const portData = portEvent.data;
|
||||
switch (portData.type) {
|
||||
case 'notification':
|
||||
break;
|
||||
case 'command': {
|
||||
channelPort?.postMessage({ type: 'acknowledge', id: portData.id });
|
||||
const command = portData.data;
|
||||
switch (command.command) {
|
||||
case 'authenticate': {
|
||||
try {
|
||||
const newToken = await getToken();
|
||||
if (newToken) {
|
||||
channelPort?.postMessage({
|
||||
type: 'result',
|
||||
id: portData.id,
|
||||
data: { result: 'token', token: newToken }
|
||||
});
|
||||
} else {
|
||||
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' },
|
||||
isExpected: true
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'close': {
|
||||
cleanup();
|
||||
resolve(null);
|
||||
break;
|
||||
}
|
||||
case 'pick': {
|
||||
channelPort?.postMessage({
|
||||
type: 'result',
|
||||
id: portData.id,
|
||||
data: { result: 'success' }
|
||||
});
|
||||
cleanup();
|
||||
resolve(command);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.warn('Unsupported command:', command);
|
||||
channelPort?.postMessage({
|
||||
result: 'error',
|
||||
error: { code: 'unsupportedCommand', message: command.command },
|
||||
isExpected: true
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
const handlePortMessage = async (portEvent: MessageEvent) => {
|
||||
const portData = portEvent.data;
|
||||
switch (portData.type) {
|
||||
case 'notification':
|
||||
break;
|
||||
case 'command': {
|
||||
channelPort?.postMessage({ type: 'acknowledge', id: portData.id });
|
||||
const command = portData.data;
|
||||
switch (command.command) {
|
||||
case 'authenticate': {
|
||||
try {
|
||||
const newToken = await getToken();
|
||||
if (newToken) {
|
||||
channelPort?.postMessage({
|
||||
type: 'result',
|
||||
id: portData.id,
|
||||
data: { result: 'token', token: newToken }
|
||||
});
|
||||
} else {
|
||||
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' },
|
||||
isExpected: true
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'close': {
|
||||
cleanup();
|
||||
resolve(null);
|
||||
break;
|
||||
}
|
||||
case 'pick': {
|
||||
channelPort?.postMessage({
|
||||
type: 'result',
|
||||
id: portData.id,
|
||||
data: { result: 'success' }
|
||||
});
|
||||
cleanup();
|
||||
resolve(command);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.warn('Unsupported command:', command);
|
||||
channelPort?.postMessage({
|
||||
result: 'error',
|
||||
error: { code: 'unsupportedCommand', message: command.command },
|
||||
isExpected: true
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function cleanup() {
|
||||
window.removeEventListener('message', handleWindowMessage);
|
||||
if (channelPort) {
|
||||
channelPort.removeEventListener('message', handlePortMessage);
|
||||
}
|
||||
if (pickerWindow) {
|
||||
pickerWindow.close();
|
||||
pickerWindow = null;
|
||||
}
|
||||
}
|
||||
function cleanup() {
|
||||
window.removeEventListener('message', handleWindowMessage);
|
||||
if (channelPort) {
|
||||
channelPort.removeEventListener('message', handlePortMessage);
|
||||
}
|
||||
if (pickerWindow) {
|
||||
pickerWindow.close();
|
||||
pickerWindow = null;
|
||||
}
|
||||
}
|
||||
|
||||
const initializePicker = async () => {
|
||||
try {
|
||||
const authToken = await getToken();
|
||||
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');
|
||||
const input = pickerWindow.document.createElement('input');
|
||||
input.setAttribute('type', 'hidden');
|
||||
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();
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
const initializePicker = async () => {
|
||||
try {
|
||||
const authToken = await getToken();
|
||||
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');
|
||||
const input = pickerWindow.document.createElement('input');
|
||||
input.setAttribute('type', 'hidden');
|
||||
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();
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
|
||||
initializePicker();
|
||||
});
|
||||
initializePicker();
|
||||
});
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
export { downloadOneDriveFile };
|
||||
|
||||
Reference in New Issue
Block a user