1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | 'use strict';
|
15 |
|
16 | const debug = require('debug')('cloudant:plugins:cookieauth');
|
17 | const request = require('request');
|
18 | const u = require('url');
|
19 |
|
20 | const BasePlugin = require('./base');
|
21 | const CookieTokenManager = require('../lib/tokens/CookieTokenManager');
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | class CookiePlugin extends BasePlugin {
|
27 | constructor(client, cfg) {
|
28 | cfg = Object.assign({
|
29 | autoRenew: true,
|
30 | errorOnNoCreds: true
|
31 | }, cfg);
|
32 |
|
33 | super(client, cfg);
|
34 |
|
35 | let sessionUrl = new u.URL(cfg.serverUrl);
|
36 | sessionUrl.pathname = '/_session';
|
37 | if (!sessionUrl.username || !sessionUrl.password) {
|
38 | if (cfg.errorOnNoCreds) {
|
39 | throw new Error('Credentials are required for cookie authentication.');
|
40 | }
|
41 | debug('Missing credentials for cookie authentication. Permanently disabling plugin.');
|
42 | this.disabled = true;
|
43 | return;
|
44 | }
|
45 |
|
46 | this._jar = request.jar();
|
47 |
|
48 | this._tokenManager = new CookieTokenManager(
|
49 | client,
|
50 | this._jar,
|
51 | u.format(sessionUrl, {auth: false}),
|
52 |
|
53 | decodeURIComponent(sessionUrl.username),
|
54 | decodeURIComponent(sessionUrl.password)
|
55 | );
|
56 |
|
57 | if (cfg.autoRenew) {
|
58 | this._tokenManager.startAutoRenew(cfg.autoRenewDefaultMaxAgeSecs);
|
59 | }
|
60 | }
|
61 |
|
62 | onRequest(state, req, callback) {
|
63 | var self = this;
|
64 |
|
65 | req.jar = self._jar;
|
66 |
|
67 | req.uri = req.uri || req.url;
|
68 | delete req.url;
|
69 | req.uri = u.format(new u.URL(req.uri), {auth: false});
|
70 |
|
71 | self._tokenManager.renewIfRequired().then(() => {
|
72 | callback(state);
|
73 | }).catch((error) => {
|
74 | if (state.attempt < state.maxAttempt) {
|
75 | state.retry = true;
|
76 | } else {
|
77 | state.abortWithResponse = [ error ];
|
78 | }
|
79 | callback(state);
|
80 | });
|
81 | }
|
82 |
|
83 | onResponse(state, response, callback) {
|
84 | if (response.statusCode === 401) {
|
85 | debug('Received 401 response. Asking for request retry.');
|
86 | state.retry = true;
|
87 | this._tokenManager.attemptTokenRenewal = true;
|
88 | }
|
89 | callback(state);
|
90 | }
|
91 | }
|
92 |
|
93 | CookiePlugin.id = 'cookieauth';
|
94 |
|
95 | module.exports = CookiePlugin;
|