1
+ 'use strict'
2
+
1
3
/**
2
4
* Module dependencies.
3
5
*/
4
- var passport = require ( 'passport' )
5
- var co = require ( 'co' )
6
+ const passport = require ( 'passport' )
6
7
7
8
/**
8
9
* Passport's default/connect middleware.
9
10
*/
10
- var _initialize = require ( 'passport/lib/middleware/initialize' )
11
- var _authenticate = require ( 'passport/lib/middleware/authenticate' )
11
+ const _initialize = require ( 'passport/lib/middleware/initialize' )
12
+ const _authenticate = require ( 'passport/lib/middleware/authenticate' )
13
+ const createReqMock = require ( './request' ) . create
12
14
13
15
/**
14
16
* Passport's initialization middleware for Koa.
@@ -17,42 +19,46 @@ var _authenticate = require('passport/lib/middleware/authenticate')
17
19
* @api private
18
20
*/
19
21
function initialize ( passport ) {
20
- var middleware = _initialize ( passport )
21
- return function * passportInitialize ( next ) {
22
- var ctx = this
23
-
22
+ const middleware = promisify ( _initialize ( passport ) )
23
+ return function passportInitialize ( ctx , next ) {
24
24
// koa <-> connect compatibility:
25
- this . passport = { }
26
- var userProperty = passport . _userProperty || 'user'
25
+ const userProperty = passport . _userProperty || 'user'
27
26
// check ctx.req has the userProperty
28
27
if ( ! ctx . req . hasOwnProperty ( userProperty ) ) {
29
28
Object . defineProperty ( ctx . req , userProperty , {
30
29
enumerable : true ,
31
30
get : function ( ) {
32
- return ctx . passport [ userProperty ]
31
+ return ctx . state [ userProperty ]
33
32
} ,
34
33
set : function ( val ) {
35
- ctx . passport [ userProperty ] = val
34
+ ctx . state [ userProperty ] = val
36
35
}
37
36
} )
38
37
}
39
38
40
- var req = createReqMock ( ctx )
39
+ // create mock object for express' req object
40
+ const req = createReqMock ( ctx )
41
41
42
- // add aliases for passport's request extensions to Koa's context
43
- var login = ctx . req . login
44
- var logout = ctx . req . logout
45
42
43
+ // add Promise-based login method
44
+ const login = req . login
46
45
ctx . login = ctx . logIn = function ( user , options ) {
47
- return login . bind ( req , user , options )
46
+ return new Promise ( ( resolve , reject ) => {
47
+ login . call ( req , user , options , err => {
48
+ if ( err ) reject ( err )
49
+ else resolve ( )
50
+ } )
51
+ } )
48
52
}
49
- ctx . req . login = ctx . req . logIn = login . bind ( req )
50
- ctx . logout = ctx . logOut = ctx . req . logout = ctx . req . logOut = logout . bind ( req )
51
- ctx . isAuthenticated = ctx . req . isAuthenticated = ctx . req . isAuthenticated . bind ( req )
52
- ctx . isUnauthenticated = ctx . req . isUnauthenticated = ctx . req . isUnauthenticated . bind ( req )
53
53
54
- yield middleware . bind ( middleware , req , ctx )
55
- yield next
54
+ // add aliases for passport's request extensions to Koa's context
55
+ ctx . logout = ctx . logOut = req . logout . bind ( req )
56
+ ctx . isAuthenticated = req . isAuthenticated . bind ( req )
57
+ ctx . isUnauthenticated = req . isUnauthenticated . bind ( req )
58
+
59
+ return middleware ( req , ctx ) . then ( function ( ) {
60
+ return next ( )
61
+ } )
56
62
}
57
63
}
58
64
@@ -74,47 +80,40 @@ function authenticate(passport, name, options, callback) {
74
80
options = options || { }
75
81
76
82
if ( callback ) {
77
- if ( callback . constructor . name !== 'GeneratorFunction' ) {
78
- throw TypeError ( 'Your custom authentication callback must be a Generator Function' )
79
- }
80
-
81
83
// When the callback is set, neither `next`, `res.redirect` or `res.end`
82
84
// are called. That is, a workaround to catch the `callback` is required.
83
85
// The `passportAuthenticate()` method below will therefore set
84
- // `callback.done`. Then, once the authentication finishes, the modified
85
- // callback yields the original one and afterwards triggers `callback.done`
86
- // to inform `passportAuthenticate()` that we are ready.
87
- var _callback = callback
88
- callback = co . wrap ( function * ( err , user , info , status ) {
89
- try {
90
- yield _callback ( err , user , info , status )
91
- callback . done ( null , false )
92
- } catch ( err ) {
93
- callback . done ( err ) ;
94
- }
95
- } )
86
+ // `callback.resolve` and `callback.reject`. Then, once the authentication
87
+ // finishes, the modified callback calls the original one and afterwards
88
+ // triggers either `callback.resolve` or `callback.reject` to inform
89
+ // `passportAuthenticate()` that we are ready.
90
+ const _callback = callback
91
+ callback = function ( err , user , info , status ) {
92
+ Promise . resolve ( _callback ( err , user , info , status ) )
93
+ . then ( ( ) => callback . resolve ( false ) )
94
+ . catch ( err => callback . reject ( err ) )
95
+ }
96
96
}
97
97
98
- var middleware = _authenticate ( passport , name , options , callback )
99
- return function * passportAuthenticate ( next ) {
100
- var ctx = this
98
+ const middleware = promisify ( _authenticate ( passport , name , options , callback ) )
101
99
100
+ return function passportAuthenticate ( ctx , next ) {
102
101
// this functions wraps the connect middleware
103
102
// to catch `next`, `res.redirect` and `res.end` calls
104
- var cont = yield function ( done ) {
103
+ const p = new Promise ( ( resolve , reject ) => {
105
104
// mock the `req` object
106
- var req = createReqMock ( ctx )
105
+ const req = createReqMock ( ctx )
107
106
108
107
// mock the `res` object
109
- var res = {
108
+ const res = {
110
109
redirect : function ( url ) {
111
110
ctx . redirect ( url )
112
- done ( null , false )
111
+ resolve ( false )
113
112
} ,
114
113
setHeader : ctx . set . bind ( ctx ) ,
115
114
end : function ( content ) {
116
115
if ( content ) ctx . body = content
117
- done ( null , false )
116
+ resolve ( false )
118
117
} ,
119
118
set statusCode ( status ) {
120
119
ctx . status = status
@@ -124,19 +123,23 @@ function authenticate(passport, name, options, callback) {
124
123
}
125
124
}
126
125
126
+ // update the custom callback above
127
127
if ( callback ) {
128
- callback . done = done
128
+ callback . resolve = resolve
129
+ callback . reject = reject
129
130
}
130
131
131
132
// call the connect middleware
132
- middleware ( req , res , done )
133
- }
133
+ middleware ( req , res ) . then ( resolve , reject )
134
+ } )
134
135
135
- // cont equals `false` when `res.redirect` or `res.end` got called
136
- // in this case, yield next to continue through Koa's middleware stack
137
- if ( cont !== false ) {
138
- yield next
139
- }
136
+ return p . then ( cont => {
137
+ // cont equals `false` when `res.redirect` or `res.end` got called
138
+ // in this case, call next to continue through Koa's middleware stack
139
+ if ( cont !== false ) {
140
+ return next ( )
141
+ }
142
+ } )
140
143
}
141
144
}
142
145
@@ -169,15 +172,19 @@ function authorize(passport, name, options, callback) {
169
172
*/
170
173
module . exports = function ( ) {
171
174
return {
172
- initialize : initialize ,
175
+ initialize : initialize ,
173
176
authenticate : authenticate ,
174
- authorize : authorize
177
+ authorize : authorize
175
178
}
176
179
}
177
180
178
- // create request mock
179
- var properties = require ( './request' )
180
- function createReqMock ( ctx ) {
181
- var req = Object . create ( ctx . request , properties )
182
- return req
181
+ function promisify ( expressMiddleware ) {
182
+ return function ( req , res ) {
183
+ return new Promise ( function ( resolve , reject ) {
184
+ expressMiddleware ( req , res , function ( err , result ) {
185
+ if ( err ) reject ( err )
186
+ else resolve ( result )
187
+ } )
188
+ } )
189
+ }
183
190
}
0 commit comments