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,48 @@ function githubUrl (path) {
1520}
1621
1722passport . use ( new GithubStrategy ( {
23+ scope : ( config . github . organizations ? config . github . scopes . concat ( [ 'read:org' ] ) : config . github . scope ) ,
1824 clientID : config . github . clientID ,
1925 clientSecret : config . github . clientSecret ,
2026 callbackURL : config . serverURL + '/auth/github/callback' ,
2127 authorizationURL : githubUrl ( 'login/oauth/authorize' ) ,
2228 tokenURL : githubUrl ( 'login/oauth/access_token' ) ,
2329 userProfileURL : githubUrl ( 'api/v3/user' )
24- } , passportGeneralCallback ) )
30+ } , async ( accessToken , refreshToken , profile , done ) => {
31+ if ( ! config . github . organizations ) {
32+ return passportGeneralCallback ( accessToken , refreshToken , profile , done )
33+ }
34+ const { statusCode, body : data } = await rp ( {
35+ url : `https://api.github.com/user/orgs` ,
36+ method : 'GET' ,
37+ json : true ,
38+ timeout : 2000 ,
39+ headers : {
40+ Authorization : `token ${ accessToken } ` ,
41+ 'User-Agent' : 'nodejs-http'
42+ }
43+ } )
44+ if ( statusCode !== 200 ) {
45+ return done ( InternalOAuthError (
46+ `Failed to query organizations for user: ${ profile . username } `
47+ ) )
48+ }
49+ const orgs = data . map ( ( { login } ) => login )
50+ for ( const org of orgs ) {
51+ if ( config . github . organizations . includes ( org ) ) {
52+ return passportGeneralCallback ( accessToken , refreshToken , profile , done )
53+ }
54+ }
55+ return done ( InternalOAuthError (
56+ `User orgs not whitelisted: ${ profile . username } (${ orgs . join ( ',' ) } )`
57+ ) )
58+ } ) )
2559
2660githubAuth . get ( '/auth/github' , function ( req , res , next ) {
2761 setReturnToFromReferer ( req )
2862 passport . authenticate ( 'github' ) ( req , res , next )
2963} )
3064
31- // github auth callback
3265githubAuth . get ( '/auth/github/callback' ,
3366 passport . authenticate ( 'github' , {
3467 successReturnToOrRedirect : config . serverURL + '/' ,
0 commit comments