1010
1111/* eslint-disable header/header */
1212
13+ import * as http from 'http' ;
14+ import * as https from 'https' ;
1315import * as k8s from '@kubernetes/client-node' ;
1416import * as fs from 'fs-extra' ;
1517import { inject , injectable } from 'inversify' ;
@@ -67,6 +69,14 @@ export class GithubServiceImpl implements GithubService {
6769 }
6870
6971 private async fetchGithubUser ( token : string ) : Promise < { user : GithubUser ; scopes : string [ ] } > {
72+ try {
73+ return await this . fetchGithubUserWithFetch ( token ) ;
74+ } catch {
75+ return await this . fetchGithubUserWithHttps ( token ) ;
76+ }
77+ }
78+
79+ private async fetchGithubUserWithFetch ( token : string ) : Promise < { user : GithubUser ; scopes : string [ ] } > {
7080 const response = await fetch ( 'https://api.github.com/user' , {
7181 headers : { Authorization : `Bearer ${ token } ` } ,
7282 } ) ;
@@ -83,6 +93,46 @@ export class GithubServiceImpl implements GithubService {
8393 return { user, scopes } ;
8494 }
8595
96+ private fetchGithubUserWithHttps ( token : string ) : Promise < { user : GithubUser ; scopes : string [ ] } > {
97+ const url = 'https://api.github.com/user' ;
98+ return new Promise ( ( resolve , reject ) => {
99+ const module = url . startsWith ( 'https:' ) ? https : http ;
100+ const req = module . request ( url , {
101+ method : 'GET' ,
102+ headers : {
103+ 'Authorization' : `Bearer ${ token } ` ,
104+ 'User-Agent' : 'che-code' ,
105+ 'Accept' : 'application/json' ,
106+ } ,
107+ } , ( res ) => {
108+ const chunks : Buffer [ ] = [ ] ;
109+ res . on ( 'data' , ( chunk : Buffer ) => chunks . push ( chunk ) ) ;
110+ res . on ( 'end' , ( ) => {
111+ const body = Buffer . concat ( chunks ) . toString ( ) ;
112+ if ( ! res . statusCode || res . statusCode < 200 || res . statusCode >= 300 ) {
113+ reject ( new Error ( `GitHub user request failed: ${ res . statusCode } ${ res . statusMessage } - ${ body } ` ) ) ;
114+ return ;
115+ }
116+ try {
117+ const user = JSON . parse ( body ) as GithubUser ;
118+ const scopesHeader = res . headers [ 'x-oauth-scopes' ] ?? '' ;
119+ const scopes = ( Array . isArray ( scopesHeader ) ? scopesHeader [ 0 ] : scopesHeader )
120+ . split ( ', ' )
121+ . map ( scope => scope . trim ( ) )
122+ . filter ( scope => scope . length > 0 ) ;
123+ resolve ( { user, scopes } ) ;
124+ } catch ( err ) {
125+ reject ( err ) ;
126+ }
127+ } ) ;
128+ res . on ( 'error' , reject ) ;
129+ } ) ;
130+ req . setTimeout ( 60 * 1000 ) ;
131+ req . on ( 'error' , reject ) ;
132+ req . end ( ) ;
133+ } ) ;
134+ }
135+
86136 async persistDeviceAuthToken ( token : string ) : Promise < void > {
87137 this . token = token ;
88138 this . logger . info ( `Github Service: adding token to the device-authentication secret...` ) ;
0 commit comments