UNPKG

2.73 kBJavaScriptView Raw
1// Copyright © 2015, 2019 IBM Corp. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14'use strict';
15
16const debug = require('debug')('cloudant:plugins:cookieauth');
17const request = require('request');
18const u = require('url');
19
20const BasePlugin = require('./base');
21const CookieTokenManager = require('../lib/tokens/CookieTokenManager');
22
23/**
24 * Cookie Authentication plugin.
25 */
26class 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 // Extract creds from URL and decode
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 ]; // return error to client
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
93CookiePlugin.id = 'cookieauth';
94
95module.exports = CookiePlugin;