import qs from 'qs' ; import url from 'url' ; import { constants , GitHubAppType , OAuthResponseData } from '@devhub/core' ; import { Linking } from '../linking' ; import { Platform } from '../platform/index.web' ; import { getUrlParamsIfMatches , listenForNextMessageData , listenForNextUrl , } from './helpers' ; const schemaRedirectUri = Platform . isElectron ? constants . APP_DEEP_LINK_URLS . github_oauth : undefined ; function getPopupTarget ( ) { const currentURL = Linking . getCurrentURL ( ) ; const query = qs . parse ( url . parse ( currentURL ) . query || '' ) ; return ! __DEV__ && ( Platform . realOS === 'ios' || Platform . realOS === 'android' || query . installation_id || Platform . isStandalone || ( navigator . userAgent || '' ) . includes ( 'Edge' ) ) ? '_self' : '_blank' ; } function popupWindow ( uri , w = 500 , h = 600 ) { const left = ( window . screen . width - w ) / 2 ; const top = ( window . screen . height - h ) / 2 ; return window . open ( uri , getPopupTarget ( ) , `resizable=yes, width=${ w }, height=${ h }, top=${ top }, left=${ left }` ) ; } export async function executeOAuth ( gitHubAppType , options = { } ) { const { appToken , scope } = options ; const scopeStr = ( scope || [ ] ) . join ( ' ' ) . trim ( ) ; const querystring = qs . stringify ( { app_token : appToken , github_app_type : gitHubAppType , is_electron : Platform . isElectron , platform : Platform . OS , redirect_uri : schemaRedirectUri || ( Platform . OS === 'web' && getPopupTarget ( ) === '_self' && window . location . origin ) || '' , scope : scopeStr , } ) ; const popup = popupWindow ( `${ constants . API_BASE_URL }/github/oauth?${ querystring }` ) ; try { let params ; if ( schemaRedirectUri && ( await Linking . canOpenURL ( schemaRedirectUri ) ) ) { const uri = await listenForNextUrl ( ) ; params = getUrlParamsIfMatches ( uri , schemaRedirectUri ) ; } else { params = await listenForNextMessageData ( popup ) ; } if ( ! ( params && params . app_token && params . github_token ) ) { throw new Error ( 'Login failed: No access token received.' ) ; } return params ; } catch ( e ) { if ( popup && popup !== window ) popup . close ( ) ; throw e ; } }