@midwayjs/passport 3.4.0-beta.7 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,393 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PassportMiddleware = exports.PassportStrategy = void 0;
13
+ const decorator_1 = require("@midwayjs/decorator");
14
+ const interface_1 = require("../interface");
15
+ const core_1 = require("@midwayjs/core");
16
+ const authenticator_1 = require("./authenticator");
17
+ const strategy_1 = require("./strategy");
18
+ const request_1 = require("./request");
19
+ function PassportStrategy(Strategy, name) {
20
+ class InnerStrategyAbstractClass extends strategy_1.AbstractStrategyWrapper {
21
+ async init() {
22
+ const cb = async (...params) => {
23
+ const done = params[params.length - 1];
24
+ try {
25
+ const result = await this.validate(...params);
26
+ if (Array.isArray(result)) {
27
+ done(null, ...result);
28
+ }
29
+ else {
30
+ done(null, result);
31
+ }
32
+ }
33
+ catch (err) {
34
+ done(err, null);
35
+ }
36
+ };
37
+ this.strategy = new Strategy(this.getStrategyOptions(), cb);
38
+ if (name) {
39
+ this.passport.use(name, this.strategy);
40
+ }
41
+ else {
42
+ this.passport.use(this.strategy);
43
+ }
44
+ if (this['serializeUser']) {
45
+ this.passport.serializeUser(this['serializeUser']);
46
+ }
47
+ if (this['deserializeUser']) {
48
+ this.passport.deserializeUser(this['deserializeUser']);
49
+ }
50
+ if (this['transformAuthInfo']) {
51
+ this.passport.transformAuthInfo(this['transformAuthInfo']);
52
+ }
53
+ }
54
+ getStrategy() {
55
+ return this.strategy;
56
+ }
57
+ }
58
+ __decorate([
59
+ (0, decorator_1.Inject)(),
60
+ __metadata("design:type", authenticator_1.PassportAuthenticator)
61
+ ], InnerStrategyAbstractClass.prototype, "passport", void 0);
62
+ __decorate([
63
+ (0, decorator_1.Init)(),
64
+ __metadata("design:type", Function),
65
+ __metadata("design:paramtypes", []),
66
+ __metadata("design:returntype", Promise)
67
+ ], InnerStrategyAbstractClass.prototype, "init", null);
68
+ return InnerStrategyAbstractClass;
69
+ }
70
+ exports.PassportStrategy = PassportStrategy;
71
+ function PassportMiddleware(strategy) {
72
+ class InnerPassportMiddleware extends interface_1.AbstractPassportMiddleware {
73
+ resolve() {
74
+ return this.authenticate(this.getAuthenticateOptions());
75
+ }
76
+ getAuthenticateOptions() {
77
+ return undefined;
78
+ }
79
+ authenticate(options) {
80
+ if (!Array.isArray(strategy)) {
81
+ strategy = [strategy];
82
+ }
83
+ if (this.passport.isExpressMode()) {
84
+ return async function passportAuthenticate(req, res, next) {
85
+ // init req method
86
+ this.attachRequestMethod(req);
87
+ // merge options with default options
88
+ const authOptions = {
89
+ ...this.passportConfig,
90
+ ...options,
91
+ };
92
+ const strategyList = [];
93
+ for (const strategySingle of strategy) {
94
+ // got strategy
95
+ const strategyInstance = await this.app
96
+ .getApplicationContext()
97
+ .getAsync(strategySingle);
98
+ strategyList.push(strategyInstance.getStrategy());
99
+ }
100
+ // authenticate
101
+ const authenticate = this.passport.authenticate(strategyList, authOptions);
102
+ const authenticateResult = await authenticate(req);
103
+ // success
104
+ if (authenticateResult.successResult) {
105
+ const breakNext = await this.onceSucceed(options, authenticateResult.successResult.user, authenticateResult.successResult.info, req, res);
106
+ if (breakNext) {
107
+ return;
108
+ }
109
+ }
110
+ else if (authenticateResult.redirectResult) {
111
+ // redirect
112
+ res.statusCode = authenticateResult.redirectResult.status || 302;
113
+ res.setHeader('Location', authenticateResult.redirectResult.url);
114
+ res.setHeader('Content-Length', '0');
115
+ res.end();
116
+ return;
117
+ }
118
+ else {
119
+ try {
120
+ this.allFailed(options, authenticateResult.failResult, req, res);
121
+ }
122
+ catch (err) {
123
+ next(err);
124
+ return;
125
+ }
126
+ }
127
+ next();
128
+ }.bind(this);
129
+ }
130
+ else {
131
+ return async function passportAuthenticate(ctx, next) {
132
+ // koa <-> connect compatibility:
133
+ const userProperty = this.passport.getUserProperty();
134
+ // create mock object for express' req object
135
+ const req = (0, request_1.create)(ctx, userProperty);
136
+ // init req method
137
+ this.attachRequestMethod(req);
138
+ // add Promise-based login method
139
+ const login = req.login;
140
+ ctx.login = ctx.logIn = function (user, options) {
141
+ return new Promise((resolve, reject) => {
142
+ login.call(req, user, options, err => {
143
+ if (err)
144
+ reject(err);
145
+ else
146
+ resolve();
147
+ });
148
+ });
149
+ };
150
+ // add aliases for passport's request extensions to Koa's context
151
+ ctx.logout = ctx.logOut = req.logout.bind(req);
152
+ ctx.isAuthenticated = req.isAuthenticated.bind(req);
153
+ ctx.isUnauthenticated = req.isUnauthenticated.bind(req);
154
+ // merge options with default options
155
+ const authOptions = {
156
+ ...this.passportConfig,
157
+ ...options,
158
+ };
159
+ const strategyList = [];
160
+ for (const strategySingle of strategy) {
161
+ // got strategy
162
+ const strategyInstance = await this.app
163
+ .getApplicationContext()
164
+ .getAsync(strategySingle);
165
+ strategyList.push(strategyInstance.getStrategy());
166
+ }
167
+ // authenticate
168
+ const authenticate = this.passport.authenticate(strategyList, authOptions);
169
+ const authenticateResult = await authenticate(req);
170
+ // success
171
+ if (authenticateResult.successResult) {
172
+ const breakNext = await this.onceSucceed(options, authenticateResult.successResult.user, authenticateResult.successResult.info, req, ctx);
173
+ if (breakNext) {
174
+ return;
175
+ }
176
+ }
177
+ else if (authenticateResult.redirectResult) {
178
+ // redirect
179
+ ctx.status = authenticateResult.redirectResult.status || 302;
180
+ ctx.set('Location', authenticateResult.redirectResult.url);
181
+ ctx.set('Content-Length', '0');
182
+ return;
183
+ }
184
+ else {
185
+ this.allFailed(options, authenticateResult.failResult, req, {
186
+ end(data) {
187
+ ctx.body = data;
188
+ },
189
+ redirect(url) {
190
+ ctx.redirect(url);
191
+ },
192
+ });
193
+ return;
194
+ }
195
+ await next();
196
+ }.bind(this);
197
+ }
198
+ }
199
+ static getName() {
200
+ return 'passport';
201
+ }
202
+ async onceSucceed(options, user, info, req, res) {
203
+ let msg;
204
+ // if (options.successFlash) {
205
+ // let flash: any = options.successFlash;
206
+ // if (typeof flash === 'string') {
207
+ // flash = { type: 'success', message: flash };
208
+ // }
209
+ // flash.type = flash.type || 'success';
210
+ //
211
+ // const type = flash.type || info.type || 'success';
212
+ // msg = flash.message || info.message || info;
213
+ // if (typeof msg === 'string') {
214
+ // req.flash && req.flash(type, msg);
215
+ // }
216
+ // }
217
+ if (options.successMessage) {
218
+ msg = options.successMessage;
219
+ if (typeof msg === 'boolean') {
220
+ msg = info.message || info;
221
+ }
222
+ if (typeof msg === 'string') {
223
+ req.session.messages = req.session.messages || [];
224
+ req.session.messages.push(msg);
225
+ }
226
+ }
227
+ if (options.assignProperty) {
228
+ req[options.assignProperty] = user;
229
+ return;
230
+ }
231
+ await req.logIn(user, options);
232
+ if (options.authInfo !== false) {
233
+ await new Promise((resolve, reject) => {
234
+ this.passport.transformAuthInfo(info, req, (err, tinfo) => {
235
+ if (err) {
236
+ reject(err);
237
+ }
238
+ else {
239
+ req.authInfo = tinfo;
240
+ resolve();
241
+ }
242
+ });
243
+ });
244
+ }
245
+ if (options.successReturnToOrRedirect) {
246
+ let url = options.successReturnToOrRedirect;
247
+ if (req.session && req.session.returnTo) {
248
+ url = req.session.returnTo;
249
+ delete req.session.returnTo;
250
+ }
251
+ res.redirect(url);
252
+ return true;
253
+ }
254
+ if (options.successRedirect) {
255
+ res.redirect(options.successRedirect);
256
+ return true;
257
+ }
258
+ }
259
+ allFailed(options, failResult, req, res) {
260
+ // Strategies are ordered by priority. For the purpose of flashing a
261
+ // message, the first failure will be displayed.
262
+ let failure = failResult.failures[0] || {}, challenge = (failure === null || failure === void 0 ? void 0 : failure.challenge) || {}, msg;
263
+ // if (options.failureFlash) {
264
+ // let flash: any = options.failureFlash;
265
+ // if (typeof flash === 'string') {
266
+ // flash = { type: 'error', message: flash };
267
+ // }
268
+ // flash.type = flash.type || 'error';
269
+ //
270
+ // const type = flash.type || challenge.type || 'error';
271
+ // msg = flash.message || challenge.message || challenge;
272
+ // if (typeof msg === 'string') {
273
+ // req.flash && req.flash(type, msg);
274
+ // }
275
+ // }
276
+ if (options.failureMessage) {
277
+ msg = options.failureMessage;
278
+ if (typeof msg === 'boolean') {
279
+ msg = challenge.message || challenge;
280
+ }
281
+ if (typeof msg === 'string') {
282
+ req.session.messages = req.session.messages || [];
283
+ req.session.messages.push(msg);
284
+ }
285
+ }
286
+ if (options.failureRedirect) {
287
+ return res.redirect(options.failureRedirect);
288
+ }
289
+ // When failure handling is not delegated to the application, the default
290
+ // is to respond with 401 Unauthorized. Note that the WWW-Authenticate
291
+ // header will be set according to the strategies in use (see
292
+ // actions#fail). If multiple strategies failed, each of their challenges
293
+ // will be included in the response.
294
+ const rchallenge = [];
295
+ let rstatus, status;
296
+ for (let j = 0, len = failResult.failures.length; j < len; j++) {
297
+ failure = failResult.failures[j];
298
+ challenge = failure.challenge;
299
+ status = failure.status;
300
+ rstatus = rstatus || status;
301
+ if (typeof challenge === 'string') {
302
+ rchallenge.push(challenge);
303
+ }
304
+ }
305
+ res.statusCode = rstatus || 401;
306
+ // eslint-disable-next-line eqeqeq
307
+ if (res.statusCode === 401 && rchallenge.length) {
308
+ res.setHeader('WWW-Authenticate', rchallenge);
309
+ }
310
+ // if (options.failWithError) {
311
+ // throw new httpError.UnauthorizedError();
312
+ // }
313
+ throw new core_1.httpError.UnauthorizedError();
314
+ }
315
+ attachRequestMethod(req) {
316
+ // init req method
317
+ req.login = req.logIn = (user, options, done) => {
318
+ if (typeof options === 'function') {
319
+ done = options;
320
+ options = {};
321
+ }
322
+ options = options || {};
323
+ const property = this.passport.getUserProperty();
324
+ req[property] = user;
325
+ if (this.passport.isEnableSession()) {
326
+ return this.passport.logInToSession(req, user).catch(err => {
327
+ req[property] = null;
328
+ if (done) {
329
+ done(err);
330
+ }
331
+ else {
332
+ throw err;
333
+ }
334
+ });
335
+ }
336
+ else {
337
+ return Promise.resolve().then(() => {
338
+ if (done) {
339
+ done();
340
+ }
341
+ });
342
+ }
343
+ };
344
+ req.logout = req.logOut = (options, done) => {
345
+ if (typeof options === 'function') {
346
+ done = options;
347
+ options = {};
348
+ }
349
+ options = options || {};
350
+ req[this.passport.getUserProperty()] = null;
351
+ if (this.passport.isEnableSession()) {
352
+ return this.passport.logOutFromSession(req, options).catch(err => {
353
+ if (done) {
354
+ done(err);
355
+ }
356
+ else {
357
+ throw err;
358
+ }
359
+ });
360
+ }
361
+ else {
362
+ return Promise.resolve().then(() => {
363
+ if (done) {
364
+ done();
365
+ }
366
+ });
367
+ }
368
+ };
369
+ req.isAuthenticated = () => {
370
+ const property = this.passport.getUserProperty();
371
+ return !!this[property];
372
+ };
373
+ req.isUnauthenticated = () => {
374
+ return !req.isAuthenticated();
375
+ };
376
+ }
377
+ }
378
+ __decorate([
379
+ (0, decorator_1.Config)('passport'),
380
+ __metadata("design:type", Object)
381
+ ], InnerPassportMiddleware.prototype, "passportConfig", void 0);
382
+ __decorate([
383
+ (0, decorator_1.App)(),
384
+ __metadata("design:type", Object)
385
+ ], InnerPassportMiddleware.prototype, "app", void 0);
386
+ __decorate([
387
+ (0, decorator_1.Inject)(),
388
+ __metadata("design:type", authenticator_1.PassportAuthenticator)
389
+ ], InnerPassportMiddleware.prototype, "passport", void 0);
390
+ return InnerPassportMiddleware;
391
+ }
392
+ exports.PassportMiddleware = PassportMiddleware;
393
+ //# sourceMappingURL=passport.service.js.map
@@ -0,0 +1,19 @@
1
+ /*!
2
+ * pause
3
+ * Copyright(c) 2012 TJ Holowaychuk
4
+ * Copyright(c) 2015 Douglas Christopher Wilson
5
+ * MIT Licensed
6
+ */
7
+ /// <reference types="node" />
8
+ import { Stream } from 'stream';
9
+ /**
10
+ * Pause the data events on a stream.
11
+ *
12
+ * @param {object} stream
13
+ * @public
14
+ */
15
+ export declare function pause(stream: Stream): {
16
+ end: () => void;
17
+ resume: () => void;
18
+ };
19
+ //# sourceMappingURL=pause.d.ts.map
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /*!
3
+ * pause
4
+ * Copyright(c) 2012 TJ Holowaychuk
5
+ * Copyright(c) 2015 Douglas Christopher Wilson
6
+ * MIT Licensed
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.pause = void 0;
10
+ /**
11
+ * Pause the data events on a stream.
12
+ *
13
+ * @param {object} stream
14
+ * @public
15
+ */
16
+ function pause(stream) {
17
+ const events = [];
18
+ const onData = createEventListener('data', events);
19
+ const onEnd = createEventListener('end', events);
20
+ // buffer data
21
+ stream.on('data', onData);
22
+ // buffer end
23
+ stream.on('end', onEnd);
24
+ return {
25
+ end: function end() {
26
+ stream.removeListener('data', onData);
27
+ stream.removeListener('end', onEnd);
28
+ },
29
+ resume: function resume() {
30
+ this.end();
31
+ for (let i = 0; i < events.length; i++) {
32
+ // eslint-disable-next-line prefer-spread
33
+ stream.emit.apply(stream, events[i]);
34
+ }
35
+ },
36
+ };
37
+ }
38
+ exports.pause = pause;
39
+ function createEventListener(name, events) {
40
+ return function onEvent() {
41
+ const args = new Array(arguments.length + 1);
42
+ args[0] = name;
43
+ for (let i = 0; i < arguments.length; i++) {
44
+ // eslint-disable-next-line prefer-rest-params
45
+ args[i + 1] = arguments[i];
46
+ }
47
+ events.push(args);
48
+ };
49
+ }
50
+ //# sourceMappingURL=pause.js.map
@@ -0,0 +1,2 @@
1
+ export declare function create(ctx: any, userProperty: any): any;
2
+ //# sourceMappingURL=request.d.ts.map
@@ -1,4 +1,7 @@
1
+ "use strict";
1
2
  /* eslint-disable */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.create = void 0;
2
5
  // Koa and Express are fundamental different in how they deal with extensions
3
6
  // to the incoming request.
4
7
  // Express pollutes Node's IncomingRequest directly, while Koa keeps Node's
@@ -116,31 +119,20 @@ function getObject(ctx, key) {
116
119
  }
117
120
  return undefined;
118
121
  }
119
- const IncomingMessageExt = require('passport/lib/http/request');
120
- exports.create = function (ctx, userProperty) {
122
+ function create(ctx, userProperty) {
121
123
  const req = Object.create(ctx.request, properties);
122
- Object.defineProperty(req, userProperty, {
123
- enumerable: true,
124
- get: function () {
125
- return ctx.state[userProperty];
126
- },
127
- set: function (val) {
128
- ctx.state[userProperty] = val;
129
- },
130
- });
131
- Object.defineProperty(req, 'ctx', {
132
- enumerable: true,
133
- get: function () {
134
- return ctx;
135
- },
136
- });
137
- // add passport http.IncomingMessage extensions
138
- req.login = IncomingMessageExt.logIn;
139
- req.logIn = IncomingMessageExt.logIn;
140
- req.logout = IncomingMessageExt.logOut;
141
- req.logOut = IncomingMessageExt.logOut;
142
- req.isAuthenticated = IncomingMessageExt.isAuthenticated;
143
- req.isUnauthenticated = IncomingMessageExt.isUnauthenticated;
124
+ if (!ctx.state.hasOwnProperty(userProperty)) {
125
+ Object.defineProperty(ctx.state, userProperty, {
126
+ enumerable: true,
127
+ get: function () {
128
+ return req[userProperty];
129
+ },
130
+ set: function (val) {
131
+ req[userProperty] = val;
132
+ },
133
+ });
134
+ }
144
135
  return req;
145
- };
136
+ }
137
+ exports.create = create;
146
138
  //# sourceMappingURL=request.js.map
@@ -0,0 +1,34 @@
1
+ import { Strategy } from './strategy';
2
+ /**
3
+ * `SessionStrategy` constructor.
4
+ *
5
+ * @api public
6
+ */
7
+ export declare class SessionStrategy extends Strategy {
8
+ readonly options: {
9
+ userProperty: string;
10
+ sessionUserProperty: string;
11
+ pauseStream?: boolean;
12
+ };
13
+ _deserializeUser: any;
14
+ constructor(options: {
15
+ userProperty: string;
16
+ sessionUserProperty: string;
17
+ pauseStream?: boolean;
18
+ }, deserializeUser: any);
19
+ /**
20
+ * Authenticate request based on the current session state.
21
+ *
22
+ * The session authentication strategy uses the session to restore any login
23
+ * state across requests. If a login session has been established, `req.user`
24
+ * will be populated with the current user.
25
+ *
26
+ * This strategy is registered automatically by Passport.
27
+ *
28
+ * @param {Object} req
29
+ * @param {Object} options
30
+ * @api protected
31
+ */
32
+ authenticate(req: any, options: any): import("@midwayjs/core/dist/error/http").UnauthorizedError;
33
+ }
34
+ //# sourceMappingURL=session.stratey.d.ts.map
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SessionStrategy = void 0;
4
+ const strategy_1 = require("./strategy");
5
+ const core_1 = require("@midwayjs/core");
6
+ const pause_1 = require("./pause");
7
+ /**
8
+ * `SessionStrategy` constructor.
9
+ *
10
+ * @api public
11
+ */
12
+ class SessionStrategy extends strategy_1.Strategy {
13
+ constructor(options, deserializeUser) {
14
+ super();
15
+ this.options = options;
16
+ this.name = 'session';
17
+ this._deserializeUser = deserializeUser;
18
+ }
19
+ /**
20
+ * Authenticate request based on the current session state.
21
+ *
22
+ * The session authentication strategy uses the session to restore any login
23
+ * state across requests. If a login session has been established, `req.user`
24
+ * will be populated with the current user.
25
+ *
26
+ * This strategy is registered automatically by Passport.
27
+ *
28
+ * @param {Object} req
29
+ * @param {Object} options
30
+ * @api protected
31
+ */
32
+ authenticate(req, options) {
33
+ if (!req.session) {
34
+ return new core_1.httpError.UnauthorizedError('Login sessions require session support,please enable it.');
35
+ }
36
+ options = options || {};
37
+ let su;
38
+ if (req.session[this.options.sessionUserProperty]) {
39
+ su = req.session[this.options.sessionUserProperty].user;
40
+ }
41
+ if (su || su === 0) {
42
+ // NOTE: Stream pausing is desirable in the case where later middleware is
43
+ // listening for events emitted from request. For discussion on the
44
+ // matter, refer to: https://github.com/jaredhanson/passport/pull/106
45
+ const paused = options.pauseStream ? (0, pause_1.pause)(req) : null;
46
+ this._deserializeUser(su, req, (err, user) => {
47
+ if (err) {
48
+ return new core_1.httpError.UnauthorizedError(err.message);
49
+ }
50
+ if (!user) {
51
+ delete req.session[this.options.sessionUserProperty].user;
52
+ this.pass();
53
+ }
54
+ else {
55
+ this.success(user);
56
+ }
57
+ if (paused) {
58
+ paused.resume();
59
+ }
60
+ });
61
+ }
62
+ else {
63
+ this.pass();
64
+ }
65
+ }
66
+ }
67
+ exports.SessionStrategy = SessionStrategy;
68
+ //# sourceMappingURL=session.stratey.js.map
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ import { IncomingMessage } from 'http';
3
+ import { IPassportStrategy, StrategyCreatedStatic } from '../interface';
4
+ export declare abstract class Strategy {
5
+ name?: string | undefined;
6
+ abstract authenticate(req: IncomingMessage, options?: any): any;
7
+ }
8
+ export interface Strategy extends StrategyCreatedStatic {
9
+ }
10
+ export declare abstract class AbstractStrategyWrapper implements IPassportStrategy {
11
+ abstract validate(...args: any[]): any;
12
+ abstract getStrategyOptions(): any;
13
+ }
14
+ //# sourceMappingURL=strategy.d.ts.map
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractStrategyWrapper = exports.Strategy = void 0;
4
+ class Strategy {
5
+ }
6
+ exports.Strategy = Strategy;
7
+ class AbstractStrategyWrapper {
8
+ }
9
+ exports.AbstractStrategyWrapper = AbstractStrategyWrapper;
10
+ //# sourceMappingURL=strategy.js.map
package/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import * as passport from 'passport';
1
+ import { AuthenticateOptions } from './dist/index';
2
2
 
3
3
  export * from './dist/index';
4
4
 
5
5
  declare module '@midwayjs/core/dist/interface' {
6
6
  interface MidwayConfig {
7
- passport?: passport.AuthenticateOptions;
7
+ passport?: AuthenticateOptions;
8
8
  }
9
9
  }
10
10