node-vault-client 1.0.1 → 2.0.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.
@@ -1,140 +1,162 @@
1
- 'use strict';
2
-
3
- const lt = require('long-timeout');
4
- const prettyMs = require('pretty-ms');
5
- const AuthToken = require('./AuthToken');
6
- const errors = require('../errors');
7
-
8
- class VaultBaseAuth {
9
-
10
- /**
11
- * @param {VaultApiClient} apiClient
12
- * @param {Object} logger
13
- * @param {String} mount - Vault's mount point
14
- */
15
- constructor(apiClient, logger, mount) {
16
- this.__apiClient = apiClient;
17
- /** @protected */
18
- this._log = logger;
19
- this._mount = mount;
20
-
21
- /** @type AuthToken */
22
- this.__authToken = null;
23
- this.__refreshTimeout = null;
24
- }
25
-
26
- /**
27
- * @protected
28
- * @returns {Promise<AuthToken>}
29
- */
30
- _authenticate() {
31
- throw new Error('Method should be overridden');
32
- }
33
-
34
- getAuthToken() {
35
- if (this.__authToken === null || (this.__authToken instanceof AuthToken && this.__authToken.isExpired() && this._reauthenticationAllowed())) {
36
- if (this.__authToken !== null && this.__authToken.isExpired() && !this._reauthenticationAllowed()) {
37
- throw new errors.AuthTokenExpiredError('Auth token has expired & cannot be refreshed since auth method doesn\'t support this.');
38
- }
39
-
40
- this._log.info('getting auth token (mount=%s)', this._mount);
41
-
42
- const tokenPromise = this._authenticate().then(authToken => {
43
- this.__authToken = authToken;
44
-
45
- if (this.__authToken.isRenewable()) {
46
- this._log.debug(
47
- 'setting refresh timer for token %s',
48
- authToken.getId()
49
- );
50
- this.__setupTokenRefreshTimer(this.__authToken);
51
- }
52
-
53
- return this.__authToken;
54
- }).catch(e => {
55
- this.__authToken = null;
56
- throw e;
57
- });
58
-
59
- this.__authToken = tokenPromise;
60
- return tokenPromise;
61
- }
62
-
63
- this._log.debug('token already exist');
64
- return Promise.resolve(this.__authToken);
65
- }
66
-
67
- /**
68
- * @protected
69
- * @returns {Promise<AuthToken>}
70
- */
71
- _getTokenEntity(tokenId) {
72
- return this.__apiClient.makeRequest('GET', '/auth/token/lookup-self', null, {'X-Vault-Token': tokenId})
73
- .then(res => {
74
- return AuthToken.fromResponse(res);
75
- });
76
- }
77
-
78
- /**
79
- * @protected
80
- * @returns {boolean}
81
- */
82
- _reauthenticationAllowed() {
83
- return true;
84
- }
85
-
86
- /**
87
- * @param {AuthToken} authToken
88
- * @private
89
- */
90
- __setupTokenRefreshTimer(authToken) {
91
- if (this.__refreshTimeout !== null) {
92
- lt.clearTimeout(this.__refreshTimeout);
93
- this.__refreshTimeout = null;
94
- }
95
-
96
- if (!authToken.isRenewable() || authToken.isExpired()) {
97
- return;
98
- }
99
-
100
- const timer = Math.max((authToken.getExpiresAt() - Math.floor(Date.now() / 1000)) / 2, 1) * 1000;
101
-
102
- this.__refreshTimeout = lt.setTimeout(() => {
103
- this.__renewToken(authToken).then(authToken => {
104
- this.__authToken = authToken;
105
- this.__setupTokenRefreshTimer(authToken);
106
- }).catch(err => {
107
- this.__setupTokenRefreshTimer(authToken);
108
-
109
- this._log.error(`Cannot refresh auth token with "${authToken.getAccessor()}" accessor. Error: ${err.message}`);
110
- this._log.error(err);
111
- });
112
- }, timer);
113
-
114
- this._log.debug(
115
- 'sleeping for %s',
116
- prettyMs(timer)
117
- );
118
- }
119
-
120
- /**
121
- * @param {AuthToken} authToken
122
- * @returns {Promise.<AuthToken>}
123
- * @private
124
- */
125
- __renewToken(authToken) {
126
- this._log.debug('renewing vault token');
127
-
128
- return this.__apiClient.makeRequest('POST', '/auth/token/renew-self', null, {'X-Vault-Token': authToken.getId()})
129
- .then(() => {
130
- this._log.info('successfully renewed token');
131
- return this._getTokenEntity(authToken.getId());
132
- })
133
- .catch((reason) => {
134
- this._log.error('token renew failed: %s', reason.message);
135
- throw reason;
136
- });
137
- }
138
- }
139
-
140
- module.exports = VaultBaseAuth;
1
+ 'use strict';
2
+
3
+ const lt = require('long-timeout');
4
+ const prettyMs = require('pretty-ms');
5
+ const AuthToken = require('./AuthToken');
6
+ const errors = require('../errors');
7
+
8
+ class VaultBaseAuth {
9
+
10
+ /**
11
+ * @param {VaultApiClient} apiClient
12
+ * @param {Object} logger
13
+ * @param {String} mount - Vault's mount point
14
+ */
15
+ constructor(apiClient, logger, mount) {
16
+ this.__apiClient = apiClient;
17
+ /** @protected */
18
+ this._log = logger;
19
+ this._mount = mount;
20
+
21
+ /** @type AuthToken */
22
+ this.__authToken = null;
23
+ this.__refreshTimeout = null;
24
+ }
25
+
26
+ /**
27
+ * @protected
28
+ * @returns {Promise<AuthToken>}
29
+ */
30
+ _authenticate() {
31
+ throw new Error('Method should be overridden');
32
+ }
33
+
34
+ getAuthToken() {
35
+ const tokenExpired = this.__authToken instanceof AuthToken && this.__authToken.isExpired();
36
+
37
+ if (tokenExpired && !this._reauthenticationAllowed()) {
38
+ return Promise.reject(new errors.AuthTokenExpiredError(
39
+ 'Auth token has expired & cannot be refreshed since auth method doesn\'t support this.'
40
+ ));
41
+ }
42
+
43
+ if (this.__authToken === null || tokenExpired) {
44
+ this._log.info('getting auth token (mount=%s)', this._mount);
45
+
46
+ const tokenPromise = this._authenticate().then(authToken => {
47
+ this.__authToken = authToken;
48
+
49
+ if (this.__authToken.isRenewable()) {
50
+ this._log.debug(
51
+ 'setting refresh timer for token %s',
52
+ authToken.getId()
53
+ );
54
+ this.__setupTokenRefreshTimer(this.__authToken);
55
+ }
56
+
57
+ return this.__authToken;
58
+ }).catch(e => {
59
+ this.__authToken = null;
60
+ throw e;
61
+ });
62
+
63
+ this.__authToken = tokenPromise;
64
+ return tokenPromise;
65
+ }
66
+
67
+ this._log.debug('token already exist');
68
+ return Promise.resolve(this.__authToken);
69
+ }
70
+
71
+ /**
72
+ * Cancel any pending token-refresh timer.
73
+ *
74
+ * When a renewable token is fetched the client arms a `long-timeout` timer to renew it
75
+ * before it expires. That timer keeps the Node.js event loop alive, so a short-lived
76
+ * script never exits on its own. Call this (or {@link VaultClient#close}) once you are
77
+ * done with the client to release the event loop. Safe to call when no timer is armed
78
+ * and safe to call multiple times.
79
+ *
80
+ * @returns {void}
81
+ */
82
+ cancelTokenRefresh() {
83
+ if (this.__refreshTimeout !== null) {
84
+ lt.clearTimeout(this.__refreshTimeout);
85
+ this.__refreshTimeout = null;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @protected
91
+ * @returns {Promise<AuthToken>}
92
+ */
93
+ _getTokenEntity(tokenId) {
94
+ return this.__apiClient.makeRequest('GET', '/auth/token/lookup-self', null, {'X-Vault-Token': tokenId})
95
+ .then(res => {
96
+ return AuthToken.fromResponse(res);
97
+ });
98
+ }
99
+
100
+ /**
101
+ * @protected
102
+ * @returns {boolean}
103
+ */
104
+ _reauthenticationAllowed() {
105
+ return true;
106
+ }
107
+
108
+ /**
109
+ * @param {AuthToken} authToken
110
+ * @private
111
+ */
112
+ __setupTokenRefreshTimer(authToken) {
113
+ if (this.__refreshTimeout !== null) {
114
+ lt.clearTimeout(this.__refreshTimeout);
115
+ this.__refreshTimeout = null;
116
+ }
117
+
118
+ if (!authToken.isRenewable() || authToken.isExpired()) {
119
+ return;
120
+ }
121
+
122
+ const timer = Math.max((authToken.getExpiresAt() - Math.floor(Date.now() / 1000)) / 2, 1) * 1000;
123
+
124
+ this.__refreshTimeout = lt.setTimeout(() => {
125
+ this.__renewToken(authToken).then(authToken => {
126
+ this.__authToken = authToken;
127
+ this.__setupTokenRefreshTimer(authToken);
128
+ }).catch(err => {
129
+ this.__setupTokenRefreshTimer(authToken);
130
+
131
+ this._log.error(`Cannot refresh auth token with "${authToken.getAccessor()}" accessor. Error: ${err.message}`);
132
+ this._log.error(err);
133
+ });
134
+ }, timer);
135
+
136
+ this._log.debug(
137
+ 'sleeping for %s',
138
+ prettyMs(timer)
139
+ );
140
+ }
141
+
142
+ /**
143
+ * @param {AuthToken} authToken
144
+ * @returns {Promise.<AuthToken>}
145
+ * @private
146
+ */
147
+ __renewToken(authToken) {
148
+ this._log.debug('renewing vault token');
149
+
150
+ return this.__apiClient.makeRequest('POST', '/auth/token/renew-self', null, {'X-Vault-Token': authToken.getId()})
151
+ .then(() => {
152
+ this._log.info('successfully renewed token');
153
+ return this._getTokenEntity(authToken.getId());
154
+ })
155
+ .catch((reason) => {
156
+ this._log.error('token renew failed: %s', reason.message);
157
+ throw reason;
158
+ });
159
+ }
160
+ }
161
+
162
+ module.exports = VaultBaseAuth;