1+ import { PublicClientApplication } from '@azure/msal-browser' ;
2+ import type { PopupRequest } from '@azure/msal-browser' ;
13import { v4 as uuidv4 } from 'uuid' ;
24
35let CLIENT_ID = '' ;
46
57async function getCredentials ( ) {
68 if ( CLIENT_ID ) return ;
9+
710 const response = await fetch ( '/api/config' ) ;
811 if ( ! response . ok ) {
912 throw new Error ( 'Failed to fetch OneDrive credentials' ) ;
@@ -15,63 +18,69 @@ async function getCredentials() {
1518 }
1619}
1720
18- function loadMsalScript ( ) : Promise < void > {
19- return new Promise ( ( resolve , reject ) => {
20- const win = window ;
21- if ( win . msal ) {
22- resolve ( ) ;
23- return ;
24- }
25- const script = document . createElement ( 'script' ) ;
26- script . src = 'https://alcdn.msauth.net/browser/2.19.0/js/msal-browser.min.js' ;
27- script . async = true ;
28- script . onload = ( ) => resolve ( ) ;
29- script . onerror = ( ) => reject ( new Error ( 'Failed to load MSAL script' ) ) ;
30- document . head . appendChild ( script ) ;
31- } ) ;
32- }
3321
34- let msalInstance : any ;
22+ let msalInstance : PublicClientApplication | null = null ;
3523
3624// Initialize MSAL authentication
3725async function initializeMsal ( ) {
38- if ( ! CLIENT_ID ) {
39- await getCredentials ( ) ;
40- }
41- const msalParams = {
42- auth : {
43- authority : 'https://login.microsoftonline.com/consumers' ,
44- clientId : CLIENT_ID
45- }
46- } ;
4726 try {
48- await loadMsalScript ( ) ;
49- const win = window ;
50- msalInstance = new win . msal . PublicClientApplication ( msalParams ) ;
51- if ( msalInstance . initialize ) {
52- await msalInstance . initialize ( ) ;
27+ if ( ! CLIENT_ID ) {
28+ await getCredentials ( ) ;
29+ }
30+
31+ const msalParams = {
32+ auth : {
33+ authority : 'https://login.microsoftonline.com/consumers' ,
34+ clientId : CLIENT_ID
35+ }
36+ } ;
37+
38+ if ( ! msalInstance ) {
39+ msalInstance = new PublicClientApplication ( msalParams ) ;
40+ if ( msalInstance . initialize ) {
41+ await msalInstance . initialize ( ) ;
42+ }
5343 }
44+
45+ return msalInstance ;
5446 } catch ( error ) {
55- console . error ( 'MSAL initialization error:' , error ) ;
47+ throw new Error ( 'MSAL initialization failed: ' + ( error instanceof Error ? error . message : String ( error ) ) ) ;
5648 }
5749}
5850
5951// Retrieve OneDrive access token
6052async function getToken ( ) : Promise < string > {
61- const authParams = { scopes : [ 'OneDrive.ReadWrite' ] } ;
53+ const authParams : PopupRequest = { scopes : [ 'OneDrive.ReadWrite' ] } ;
6254 let accessToken = '' ;
6355 try {
64- await initializeMsal ( ) ;
56+ msalInstance = await initializeMsal ( ) ;
57+ if ( ! msalInstance ) {
58+ throw new Error ( 'MSAL not initialized' ) ;
59+ }
60+
6561 const resp = await msalInstance . acquireTokenSilent ( authParams ) ;
6662 accessToken = resp . accessToken ;
6763 } catch ( err ) {
68- const resp = await msalInstance . loginPopup ( authParams ) ;
69- msalInstance . setActiveAccount ( resp . account ) ;
70- if ( resp . idToken ) {
71- const resp2 = await msalInstance . acquireTokenSilent ( authParams ) ;
72- accessToken = resp2 . accessToken ;
64+ if ( ! msalInstance ) {
65+ throw new Error ( 'MSAL not initialized' ) ;
66+ }
67+
68+ try {
69+ const resp = await msalInstance . loginPopup ( authParams ) ;
70+ msalInstance . setActiveAccount ( resp . account ) ;
71+ if ( resp . idToken ) {
72+ const resp2 = await msalInstance . acquireTokenSilent ( authParams ) ;
73+ accessToken = resp2 . accessToken ;
74+ }
75+ } catch ( popupError ) {
76+ throw new Error ( 'Failed to login: ' + ( popupError instanceof Error ? popupError . message : String ( popupError ) ) ) ;
7377 }
7478 }
79+
80+ if ( ! accessToken ) {
81+ throw new Error ( 'Failed to acquire access token' ) ;
82+ }
83+
7584 return accessToken ;
7685}
7786
@@ -97,6 +106,7 @@ const params = {
97106 }
98107} ;
99108
109+
100110// Download file from OneDrive
101111async function downloadOneDriveFile ( fileInfo : any ) : Promise < Blob > {
102112 const accessToken = await getToken ( ) ;
@@ -164,7 +174,6 @@ export async function openOneDrivePicker(): Promise<any | null> {
164174 throw new Error ( 'Could not retrieve auth token' ) ;
165175 }
166176 } catch ( err ) {
167- console . error ( err ) ;
168177 channelPort ?. postMessage ( {
169178 result : 'error' ,
170179 error : { code : 'tokenError' , message : 'Failed to get token' } ,
@@ -189,7 +198,6 @@ export async function openOneDrivePicker(): Promise<any | null> {
189198 break ;
190199 }
191200 default : {
192- console . warn ( 'Unsupported command:' , command ) ;
193201 channelPort ?. postMessage ( {
194202 result : 'error' ,
195203 error : { code : 'unsupportedCommand' , message : command . command } ,
@@ -220,14 +228,17 @@ export async function openOneDrivePicker(): Promise<any | null> {
220228 if ( ! authToken ) {
221229 return reject ( new Error ( 'Failed to acquire access token' ) ) ;
222230 }
231+
223232 pickerWindow = window . open ( '' , 'OneDrivePicker' , 'width=800,height=600' ) ;
224233 if ( ! pickerWindow ) {
225234 return reject ( new Error ( 'Failed to open OneDrive picker window' ) ) ;
226235 }
236+
227237 const queryString = new URLSearchParams ( {
228238 filePicker : JSON . stringify ( params )
229239 } ) ;
230240 const url = `${ baseUrl } ?${ queryString . toString ( ) } ` ;
241+
231242 const form = pickerWindow . document . createElement ( 'form' ) ;
232243 form . setAttribute ( 'action' , url ) ;
233244 form . setAttribute ( 'method' , 'POST' ) ;
@@ -236,11 +247,15 @@ export async function openOneDrivePicker(): Promise<any | null> {
236247 input . setAttribute ( 'name' , 'access_token' ) ;
237248 input . setAttribute ( 'value' , authToken ) ;
238249 form . appendChild ( input ) ;
250+
239251 pickerWindow . document . body . appendChild ( form ) ;
240252 form . submit ( ) ;
253+
241254 window . addEventListener ( 'message' , handleWindowMessage ) ;
242255 } catch ( err ) {
243- if ( pickerWindow ) pickerWindow . close ( ) ;
256+ if ( pickerWindow ) {
257+ pickerWindow . close ( ) ;
258+ }
244259 reject ( err ) ;
245260 }
246261 } ;
@@ -251,18 +266,16 @@ export async function openOneDrivePicker(): Promise<any | null> {
251266
252267// Pick and download file from OneDrive
253268export async function pickAndDownloadFile ( ) : Promise < { blob : Blob ; name : string } | null > {
254- try {
255- const pickerResult = await openOneDrivePicker ( ) ;
256- if ( ! pickerResult || ! pickerResult . items || pickerResult . items . length === 0 ) {
257- return null ;
258- }
259- const selectedFile = pickerResult . items [ 0 ] ;
260- const blob = await downloadOneDriveFile ( selectedFile ) ;
261- return { blob, name : selectedFile . name } ;
262- } catch ( error ) {
263- console . error ( 'Error occurred during OneDrive file pick/download:' , error ) ;
264- throw error ;
269+ const pickerResult = await openOneDrivePicker ( ) ;
270+
271+ if ( ! pickerResult || ! pickerResult . items || pickerResult . items . length === 0 ) {
272+ return null ;
265273 }
274+
275+ const selectedFile = pickerResult . items [ 0 ] ;
276+ const blob = await downloadOneDriveFile ( selectedFile ) ;
277+
278+ return { blob, name : selectedFile . name } ;
266279}
267280
268281export { downloadOneDriveFile } ;
0 commit comments