11'use strict'
22
33const Router = require ( 'express' ) . Router
4+ const request = require ( 'request' )
45const passport = require ( 'passport' )
56const GithubStrategy = require ( 'passport-github' ) . Strategy
7+ const { InternalOAuthError } = require ( 'passport-oauth2' )
68const config = require ( '../../config' )
79const response = require ( '../../response' )
810const { setReturnToFromReferer, passportGeneralCallback } = require ( '../utils' )
911const { URL } = require ( 'url' )
12+ const { promisify } = require ( 'util' )
13+
14+ const rp = promisify ( request )
1015
1116const githubAuth = module . exports = Router ( )
1217
@@ -15,20 +20,47 @@ function githubUrl (path) {
1520}
1621
1722passport . use ( new GithubStrategy ( {
23+ scope : ( config . github . organizations ?
24+ config . github . scopes . concat ( [ 'read:org' ] ) : config . github . scope ) ,
1825 clientID : config . github . clientID ,
1926 clientSecret : config . github . clientSecret ,
2027 callbackURL : config . serverURL + '/auth/github/callback' ,
2128 authorizationURL : githubUrl ( 'login/oauth/authorize' ) ,
2229 tokenURL : githubUrl ( 'login/oauth/access_token' ) ,
2330 userProfileURL : githubUrl ( 'api/v3/user' )
24- } , passportGeneralCallback ) )
31+ } , async ( accessToken , refreshToken , profile , done ) => {
32+ if ( ! config . github . organizations ) {
33+ return passportGeneralCallback ( accessToken , refreshToken , profile , done )
34+ }
35+ const { statusCode, body : data } = await rp ( {
36+ url : `https://api.github.com/user/orgs` ,
37+ method : 'GET' , json : true , timeout : 2000 ,
38+ headers : {
39+ 'Authorization' : `token ${ accessToken } ` ,
40+ 'User-Agent' : 'nodejs-http'
41+ }
42+ } )
43+ if ( statusCode != 200 ) {
44+ return done ( InternalOAuthError (
45+ `Failed to query organizations for user: ${ profile . username } `
46+ ) )
47+ }
48+ const orgs = data . map ( ( { login} ) => login )
49+ for ( const org of orgs ) {
50+ if ( config . github . organizations . includes ( org ) ) {
51+ return passportGeneralCallback ( accessToken , refreshToken , profile , done )
52+ }
53+ }
54+ return done ( InternalOAuthError (
55+ `User orgs not whitelisted: ${ profile . username } (${ orgs . join ( ',' ) } )`
56+ ) )
57+ } ) )
2558
2659githubAuth . get ( '/auth/github' , function ( req , res , next ) {
2760 setReturnToFromReferer ( req )
2861 passport . authenticate ( 'github' ) ( req , res , next )
2962} )
3063
31- // github auth callback
3264githubAuth . get ( '/auth/github/callback' ,
3365 passport . authenticate ( 'github' , {
3466 successReturnToOrRedirect : config . serverURL + '/' ,
0 commit comments