@@ -31,10 +31,11 @@ catch(e) {}
31
31
var execGit = require ( './exec-git' ) ;
32
32
33
33
function createRemoteStrings ( auth , hostname ) {
34
- var authString = auth ? ( encodeURIComponent ( auth . username ) + ':' + encodeURIComponent ( auth . password ) + '@' ) : '' ;
34
+ var authString = auth . username ? ( encodeURIComponent ( auth . username ) + ':' + encodeURIComponent ( auth . password ) + '@' ) : '' ;
35
35
hostname = hostname || 'github.com' ;
36
36
37
37
this . remoteString = 'https://' + authString + hostname + '/' ;
38
+ this . authSuffix = auth . token ? '?access_token=' + auth . token : '' ;
38
39
39
40
if ( hostname == 'github.com' )
40
41
this . apiRemoteString = 'https://' + authString + 'api.github.com/' ;
@@ -44,10 +45,6 @@ function createRemoteStrings(auth, hostname) {
44
45
this . apiRemoteString = 'https://' + authString + hostname + '/api/v3/' ;
45
46
}
46
47
47
- // avoid storing passwords as plain text in config
48
- function encodeCredentials ( auth ) {
49
- return new Buffer ( auth . username + ':' + auth . password ) . toString ( 'base64' ) ;
50
- }
51
48
function decodeCredentials ( str ) {
52
49
var auth = new Buffer ( str , 'base64' ) . toString ( 'utf8' ) . split ( ':' ) ;
53
50
@@ -80,6 +77,10 @@ function readNetrc(hostname) {
80
77
}
81
78
}
82
79
80
+ function isGithubToken ( token ) {
81
+ return token . match ( / [ 0 - 9 a - f ] { 40 } / ) ;
82
+ }
83
+
83
84
var GithubLocation = function ( options , ui ) {
84
85
85
86
// ensure git is installed
@@ -97,19 +98,15 @@ var GithubLocation = function(options, ui) {
97
98
this . versionString = options . versionString + '.1' ;
98
99
99
100
// Give the environment precedence over options object
100
- if ( process . env . JSPM_GITHUB_AUTH_TOKEN ) {
101
- options . auth = process . env . JSPM_GITHUB_AUTH_TOKEN ;
102
- } else if ( options . username && ! options . auth ) {
103
- options . auth = encodeCredentials ( options ) ;
104
- // NB deprecate old auth eventually
105
- // delete options.username;
106
- // delete options.password;
107
- }
101
+ var auth = process . env . JSPM_GITHUB_AUTH_TOKEN || options . auth ;
108
102
109
- if ( typeof options . auth == 'string' ) {
110
- this . auth = decodeCredentials ( options . auth ) ;
111
- }
112
- else {
103
+ if ( auth ) {
104
+ if ( isGithubToken ( auth ) ) {
105
+ this . auth = { token : auth } ;
106
+ } else {
107
+ this . auth = decodeCredentials ( auth ) ;
108
+ }
109
+ } else {
113
110
this . auth = readNetrc ( options . hostname ) ;
114
111
}
115
112
@@ -147,7 +144,7 @@ var GithubLocation = function(options, ui) {
147
144
148
145
this . remote = options . remote ;
149
146
150
- createRemoteStrings . call ( this , this . auth , options . hostname ) ;
147
+ createRemoteStrings . call ( this , this . auth || { } , options . hostname ) ;
151
148
} ;
152
149
153
150
function clearDir ( dir ) {
@@ -198,20 +195,14 @@ function configureCredentials(config, ui) {
198
195
199
196
return Promise . resolve ( )
200
197
. then ( function ( ) {
201
- ui . log ( 'info' , 'If using two-factor authentication or to avoid using your password you can generate an access token at %https://' + ( config . hostname || 'github.com' ) + '/settings/tokens%. Ensure it has `public_repo` scope access.' ) ;
202
- return ui . input ( 'Enter your GitHub username' ) ;
203
- } )
204
- . then ( function ( username ) {
205
- auth . username = username ;
206
- if ( auth . username )
207
- return ui . input ( 'Enter your GitHub password or access token' , null , true ) ;
198
+ ui . log ( 'info' , 'You can generate an access token at %https://' + ( config . hostname || 'github.com' ) + '/settings/tokens%.' ) ;
199
+ return ui . input ( 'Enter your GitHub access token' ) ;
208
200
} )
209
- . then ( function ( password ) {
210
- auth . password = password ;
211
- if ( ! auth . username )
212
- return false ;
213
-
214
- return ui . confirm ( 'Would you like to test these credentials?' , true ) ;
201
+ . then ( function ( token ) {
202
+ auth . token = token ;
203
+ if ( auth . token ) {
204
+ return ui . confirm ( 'Would you like to test these credentials?' , true ) ;
205
+ }
215
206
} )
216
207
. then ( function ( test ) {
217
208
if ( ! test )
@@ -223,7 +214,7 @@ function configureCredentials(config, ui) {
223
214
createRemoteStrings . call ( remotes , auth , config . hostname ) ;
224
215
225
216
return asp ( request ) ( {
226
- uri : remotes . apiRemoteString + 'user' ,
217
+ uri : remotes . apiRemoteString + 'user' + remotes . authSuffix ,
227
218
headers : {
228
219
'User-Agent' : 'jspm' ,
229
220
'Accept' : 'application/vnd.github.v3+json'
@@ -234,7 +225,7 @@ function configureCredentials(config, ui) {
234
225
} )
235
226
. then ( function ( res ) {
236
227
if ( res . statusCode == 401 ) {
237
- ui . log ( 'warn' , 'Provided GitHub credentials are not authorized, try re-entering your password or access token.' ) ;
228
+ ui . log ( 'warn' , 'Provided GitHub credentials are not authorized, try re-entering your access token.' ) ;
238
229
}
239
230
else if ( res . statusCode != 200 ) {
240
231
ui . log ( 'warn' , 'Invalid response code, %' + res . statusCode + '%' ) ;
@@ -253,10 +244,10 @@ function configureCredentials(config, ui) {
253
244
. then ( function ( redo ) {
254
245
if ( redo )
255
246
return configureCredentials ( config , ui ) ;
256
- return encodeCredentials ( auth ) ;
247
+ return auth . token ;
257
248
} ) ;
258
- else if ( auth . username )
259
- return encodeCredentials ( auth ) ;
249
+ else if ( auth . token )
250
+ return auth . token ;
260
251
else
261
252
return null ;
262
253
} ) ;
@@ -302,14 +293,15 @@ GithubLocation.prototype = {
302
293
locate : function ( repo ) {
303
294
var self = this ;
304
295
var remoteString = this . remoteString ;
296
+ var authSuffix = this . authSuffix ;
305
297
306
298
if ( repo . split ( '/' ) . length !== 2 )
307
299
throw "GitHub packages must be of the form `owner/repo`." ;
308
300
309
301
// request the repo to check that it isn't a redirect
310
302
return new Promise ( function ( resolve , reject ) {
311
303
request ( extend ( {
312
- uri : remoteString + repo ,
304
+ uri : remoteString + repo + authSuffix ,
313
305
headers : {
314
306
'User-Agent' : 'jspm'
315
307
} ,
@@ -352,8 +344,7 @@ GithubLocation.prototype = {
352
344
execGit ( 'ls-remote ' + remoteString . replace ( / ( [ ' " ( ) ] ) / g, '\\\$1' ) + repo + '.git refs/tags/* refs/heads/*' , execOpt , function ( err , stdout , stderr ) {
353
345
if ( err ) {
354
346
if ( err . toString ( ) . indexOf ( 'not found' ) == - 1 ) {
355
- // dont show plain text passwords in error
356
- var error = new Error ( stderr . toString ( ) . replace ( remoteString , '' ) ) ;
347
+ var error = new Error ( stderr ) ;
357
348
error . hideStack = true ;
358
349
error . retriable = true ;
359
350
reject ( error ) ;
@@ -410,7 +401,7 @@ GithubLocation.prototype = {
410
401
var ui = this . ui ;
411
402
412
403
return asp ( request ) ( {
413
- uri : this . apiRemoteString + 'repos/' + repo + '/contents/package.json' ,
404
+ uri : this . apiRemoteString + 'repos/' + repo + '/contents/package.json' + this . authSuffix ,
414
405
headers : {
415
406
'User-Agent' : 'jspm' ,
416
407
'Accept' : 'application/vnd.github.v3.raw'
@@ -546,13 +537,14 @@ GithubLocation.prototype = {
546
537
var execOpt = this . execOpt ;
547
538
var max_repo_size = this . max_repo_size ;
548
539
var remoteString = this . remoteString ;
540
+ var authSuffix = this . authSuffix ;
549
541
550
542
var self = this ;
551
543
552
544
// Download from the git archive
553
545
return new Promise ( function ( resolve , reject ) {
554
546
request ( {
555
- uri : remoteString + repo + '/archive/' + version + '.tar.gz' ,
547
+ uri : remoteString + repo + '/archive/' + version + '.tar.gz' + authSuffix ,
556
548
headers : { 'accept' : 'application/octet-stream' } ,
557
549
strictSSL : self . defaultRequestOptions . strictSSL
558
550
} )
0 commit comments