@@ -27,7 +27,7 @@ import { AsyncReturnType } from '../utils/TypeHelper';
27
27
import { safeTakeEvery as takeEvery , safeTakeLatest as takeLatest } from './SafeEffects' ;
28
28
29
29
const DISCOVERY_DOCS = [ 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest' ] ;
30
- const SCOPES = 'profile https://www.googleapis.com/auth/drive.file' ;
30
+ const SCOPES = 'profile https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/userinfo.email ' ;
31
31
const UPLOAD_PATH = 'https://www.googleapis.com/upload/drive/v3/files' ;
32
32
33
33
// Special ID value for the Google Drive API.
@@ -36,11 +36,15 @@ const ROOT_ID = 'root';
36
36
const MIME_SOURCE = 'text/plain' ;
37
37
// const MIME_FOLDER = 'application/vnd.google-apps.folder';
38
38
39
+ // TODO: fix all calls to (window.google as any).accounts
39
40
export function * persistenceSaga ( ) : SagaIterator {
41
+ // Starts the function* () for every dispatched LOGOUT_GOOGLE action
42
+ // Same for all takeLatest() calls below, with respective types from PersistenceTypes
40
43
yield takeLatest ( LOGOUT_GOOGLE , function * ( ) {
41
44
yield put ( actions . playgroundUpdatePersistenceFile ( undefined ) ) ;
42
45
yield call ( ensureInitialised ) ;
43
- yield call ( [ gapi . auth2 . getAuthInstance ( ) , 'signOut' ] ) ;
46
+ yield gapi . client . setToken ( null ) ;
47
+ yield handleUserChanged ( null ) ;
44
48
} ) ;
45
49
46
50
yield takeLatest ( PERSISTENCE_OPEN_PICKER , function * ( ) : any {
@@ -307,24 +311,120 @@ const initialisationPromise: Promise<void> = new Promise(res => {
307
311
startInitialisation = res ;
308
312
} ) . then ( initialise ) ;
309
313
310
- function handleUserChanged ( user : gapi . auth2 . GoogleUser ) {
311
- store . dispatch (
312
- actions . setGoogleUser ( user . isSignedIn ( ) ? user . getBasicProfile ( ) . getEmail ( ) : undefined )
313
- ) ;
314
+ const getUserProfileData = async ( accessToken : string ) => {
315
+ const headers = new Headers ( )
316
+ headers . append ( 'Authorization' , `Bearer ${ accessToken } ` )
317
+ const response = await fetch ( 'https://www.googleapis.com/oauth2/v3/userinfo' , {
318
+ headers
319
+ } )
320
+ const data = await response . json ( ) ;
321
+ return data ;
314
322
}
315
323
324
+ async function handleUserChanged ( accessToken : string | null ) {
325
+ if ( accessToken === null ) { // TODO: check if access token is invalid instead of null
326
+ store . dispatch ( actions . setGoogleUser ( undefined ) ) ;
327
+ }
328
+ else {
329
+ const userProfileData = await getUserProfileData ( accessToken )
330
+ const email = userProfileData . email ;
331
+ console . log ( "handleUserChanged" , email ) ;
332
+ store . dispatch ( actions . setGoogleUser ( email ) ) ;
333
+ }
334
+ }
335
+
336
+ let tokenClient : any ;
337
+
316
338
async function initialise ( ) {
317
- await new Promise ( ( resolve , reject ) =>
318
- gapi . load ( 'client:auth2' , { callback : resolve , onerror : reject } )
339
+ // load GIS script
340
+ await new Promise < void > ( ( resolve , reject ) => {
341
+ const scriptTag = document . createElement ( 'script' ) ;
342
+ scriptTag . src = 'https://accounts.google.com/gsi/client' ;
343
+ scriptTag . async = true ;
344
+ scriptTag . defer = true ;
345
+ //scriptTag.nonce = nonce;
346
+ scriptTag . onload = ( ) => {
347
+ console . log ( "success" ) ;
348
+ resolve ( ) ;
349
+ //setScriptLoadedSuccessfully(true);
350
+ //onScriptLoadSuccessRef.current?.();
351
+ } ;
352
+ scriptTag . onerror = ( ev ) => {
353
+ console . log ( "failure" ) ;
354
+ reject ( ev ) ;
355
+ //setScriptLoadedSuccessfully(false);
356
+ //onScriptLoadErrorRef.current?.();
357
+ } ;
358
+
359
+ document . body . appendChild ( scriptTag ) ;
360
+ } ) ;
361
+
362
+ // load and initialize gapi.client
363
+ await new Promise < void > ( ( resolve , reject ) =>
364
+ gapi . load ( 'client' , { callback : ( ) => { console . log ( "gapi.client loaded" ) ; resolve ( ) ; } , onerror : reject } )
319
365
) ;
320
366
await gapi . client . init ( {
321
- apiKey : Constants . googleApiKey ,
322
- clientId : Constants . googleClientId ,
323
- discoveryDocs : DISCOVERY_DOCS ,
324
- scope : SCOPES
367
+ discoveryDocs : DISCOVERY_DOCS
325
368
} ) ;
326
- gapi . auth2 . getAuthInstance ( ) . currentUser . listen ( handleUserChanged ) ;
327
- handleUserChanged ( gapi . auth2 . getAuthInstance ( ) . currentUser . get ( ) ) ;
369
+
370
+ // juju
371
+ // TODO: properly fix types here
372
+ await new Promise ( ( resolve , reject ) => {
373
+ //console.log("At least ur here");
374
+ resolve ( ( window . google as any ) . accounts . oauth2 . initTokenClient ( {
375
+ client_id : Constants . googleClientId ,
376
+ scope : SCOPES ,
377
+ callback : ''
378
+ } ) ) ;
379
+ } ) . then ( ( c ) => {
380
+ //console.log(c);
381
+ tokenClient = c ;
382
+ //console.log(tokenClient.requestAccessToken);
383
+ } ) ;
384
+
385
+ //await console.log("tokenClient", tokenClient);
386
+
387
+
388
+ //await gapi.client.init({
389
+ //apiKey: Constants.googleApiKey,
390
+ //clientId: Constants.googleClientId,
391
+ //discoveryDocs: DISCOVERY_DOCS,
392
+ //scope: SCOPES
393
+ //});
394
+ //gapi.auth2.getAuthInstance().currentUser.listen(handleUserChanged);
395
+ //handleUserChanged(gapi.auth2.getAuthInstance().currentUser.get());
396
+ }
397
+
398
+ // TODO: fix types
399
+ // adapted from https://developers.google.com/identity/oauth2/web/guides/migration-to-gis
400
+ async function getToken ( err : any ) {
401
+
402
+ //if (err.result.error.code == 401 || (err.result.error.code == 403) &&
403
+ // (err.result.error.status == "PERMISSION_DENIED")) {
404
+ if ( err ) { //TODO: fix after debugging
405
+
406
+ // The access token is missing, invalid, or expired, prompt for user consent to obtain one.
407
+ await new Promise ( ( resolve , reject ) => {
408
+ try {
409
+ // Settle this promise in the response callback for requestAccessToken()
410
+ tokenClient . callback = ( resp : any ) => {
411
+ if ( resp . error !== undefined ) {
412
+ reject ( resp ) ;
413
+ }
414
+ // GIS has automatically updated gapi.client with the newly issued access token.
415
+ console . log ( 'gapi.client access token: ' + JSON . stringify ( gapi . client . getToken ( ) ) ) ;
416
+ resolve ( resp ) ;
417
+ } ;
418
+ console . log ( tokenClient . requestAccessToken ) ;
419
+ tokenClient . requestAccessToken ( ) ;
420
+ } catch ( err ) {
421
+ console . log ( err )
422
+ }
423
+ } ) ;
424
+ } else {
425
+ // Errors unrelated to authorization: server errors, exceeding quota, bad requests, and so on.
426
+ throw new Error ( err ) ;
427
+ }
328
428
}
329
429
330
430
function * ensureInitialised ( ) {
@@ -334,9 +434,15 @@ function* ensureInitialised() {
334
434
335
435
function * ensureInitialisedAndAuthorised ( ) {
336
436
yield call ( ensureInitialised ) ;
337
- if ( ! gapi . auth2 . getAuthInstance ( ) . isSignedIn . get ( ) ) {
338
- yield gapi . auth2 . getAuthInstance ( ) . signIn ( ) ;
339
- }
437
+ // only call getToken if there is no token in gapi
438
+ console . log ( gapi . client . getToken ( ) ) ;
439
+ if ( gapi . client . getToken ( ) === null ) {
440
+ yield getToken ( true ) ;
441
+ yield handleUserChanged ( gapi . client . getToken ( ) . access_token ) ;
442
+ } //TODO: fix after debugging
443
+ //if (!gapi.auth2.getAuthInstance().isSignedIn.get()) {
444
+ // yield gapi.auth2.getAuthInstance().signIn();
445
+ //}
340
446
}
341
447
342
448
type PickFileResult =
@@ -372,9 +478,7 @@ function pickFile(
372
478
. setTitle ( title )
373
479
. enableFeature ( google . picker . Feature . NAV_HIDDEN )
374
480
. addView ( view )
375
- . setOAuthToken (
376
- gapi . auth2 . getAuthInstance ( ) . currentUser . get ( ) . getAuthResponse ( ) . access_token
377
- )
481
+ . setOAuthToken ( gapi . client . getToken ( ) . access_token )
378
482
. setAppId ( Constants . googleAppId ! )
379
483
. setDeveloperKey ( Constants . googleApiKey ! )
380
484
. setCallback ( ( data : any ) => {
@@ -519,4 +623,4 @@ function generateBoundary(): string {
519
623
520
624
// End adapted part
521
625
522
- export default persistenceSaga ;
626
+ export default persistenceSaga ;
0 commit comments