@bedrock/kms 10.0.0 → 10.1.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.
- package/CHANGELOG.md +6 -0
- package/lib/keystores.js +11 -4
- package/package.json +1 -1
- package/test/mocha/13-keystores-update-api.js +40 -0
package/CHANGELOG.md
CHANGED
package/lib/keystores.js
CHANGED
|
@@ -17,6 +17,9 @@ import './config.js';
|
|
|
17
17
|
const USAGE_COUNTER_MAX_CONCURRENCY = 100;
|
|
18
18
|
let KEYSTORE_CONFIG_CACHE;
|
|
19
19
|
|
|
20
|
+
// cache only exported for testing purposes
|
|
21
|
+
export {KEYSTORE_CONFIG_CACHE as _KEYSTORE_CONFIG_CACHE};
|
|
22
|
+
|
|
20
23
|
bedrock.events.on('bedrock.init', async () => {
|
|
21
24
|
const cfg = bedrock.config.kms;
|
|
22
25
|
KEYSTORE_CONFIG_CACHE = new LruCache({
|
|
@@ -100,8 +103,7 @@ export async function insert({config} = {}) {
|
|
|
100
103
|
config
|
|
101
104
|
};
|
|
102
105
|
try {
|
|
103
|
-
const result = await database.collections['kms-keystore'].insertOne(
|
|
104
|
-
record, database.writeOptions);
|
|
106
|
+
const result = await database.collections['kms-keystore'].insertOne(record);
|
|
105
107
|
return result.ops[0];
|
|
106
108
|
} catch(e) {
|
|
107
109
|
if(!database.isDuplicateError(e)) {
|
|
@@ -180,7 +182,7 @@ export async function update({config, explain = false} = {}) {
|
|
|
180
182
|
config,
|
|
181
183
|
'meta.updated': Date.now()
|
|
182
184
|
}
|
|
183
|
-
}
|
|
185
|
+
});
|
|
184
186
|
|
|
185
187
|
if(result.result.n === 0) {
|
|
186
188
|
// no records changed...
|
|
@@ -207,11 +209,16 @@ export async function update({config, explain = false} = {}) {
|
|
|
207
209
|
*
|
|
208
210
|
* @param {object} options - The options to use.
|
|
209
211
|
* @param {string} options.id - The ID of the keystore.
|
|
212
|
+
* @param {boolean} [options.fresh=false] - False if it is safe to use a
|
|
213
|
+
* potentially cached value, false to always get a fresh value.
|
|
210
214
|
*
|
|
211
215
|
* @returns {Promise<object>} Resolves to `{config, meta}`.
|
|
212
216
|
*/
|
|
213
|
-
export async function get({id} = {}) {
|
|
217
|
+
export async function get({id, fresh = false} = {}) {
|
|
214
218
|
assert.string(id, 'id');
|
|
219
|
+
if(fresh) {
|
|
220
|
+
KEYSTORE_CONFIG_CACHE.delete(id);
|
|
221
|
+
}
|
|
215
222
|
const fn = () => _getUncachedRecord({id});
|
|
216
223
|
return KEYSTORE_CONFIG_CACHE.memoize({key: id, fn});
|
|
217
224
|
}
|
package/package.json
CHANGED
|
@@ -24,6 +24,12 @@ describe('keystores APIs', () => {
|
|
|
24
24
|
controller: 'f2da13ee-50d2-46ab-865d-ee23d609edbd',
|
|
25
25
|
sequence: 0,
|
|
26
26
|
};
|
|
27
|
+
const mockConfigDelta = {
|
|
28
|
+
id: 'https://example.com/keystores/f9da6f23-6e13-42e9-88d3-5c03011ecbbf',
|
|
29
|
+
kmsModule: 'ssm-v1',
|
|
30
|
+
controller: '17e77da1-bb7e-4fe2-b4dd-1c4bba933d7c',
|
|
31
|
+
sequence: 0,
|
|
32
|
+
};
|
|
27
33
|
|
|
28
34
|
before(async () => {
|
|
29
35
|
let err;
|
|
@@ -31,6 +37,7 @@ describe('keystores APIs', () => {
|
|
|
31
37
|
await keystores.insert({config: mockConfigAlpha});
|
|
32
38
|
await keystores.insert({config: mockConfigBeta});
|
|
33
39
|
await keystores.insert({config: mockConfigGamma});
|
|
40
|
+
await keystores.insert({config: mockConfigDelta});
|
|
34
41
|
} catch(e) {
|
|
35
42
|
err = e;
|
|
36
43
|
}
|
|
@@ -93,6 +100,39 @@ describe('keystores APIs', () => {
|
|
|
93
100
|
result.should.be.a('boolean');
|
|
94
101
|
result.should.be.true;
|
|
95
102
|
});
|
|
103
|
+
it('successfully updates a keystore and gets a fresh value', async () => {
|
|
104
|
+
const config = klona(mockConfigDelta);
|
|
105
|
+
|
|
106
|
+
// get keystore config to prime cache
|
|
107
|
+
await keystores.get({id: config.id});
|
|
108
|
+
|
|
109
|
+
// now update config
|
|
110
|
+
let err;
|
|
111
|
+
let result;
|
|
112
|
+
config.sequence++;
|
|
113
|
+
config.controller = 'someOtherController';
|
|
114
|
+
const oldDelete = keystores._KEYSTORE_CONFIG_CACHE.delete;
|
|
115
|
+
try {
|
|
116
|
+
// remove cache delete functionality to test fresh API
|
|
117
|
+
keystores._KEYSTORE_CONFIG_CACHE.delete = () => {};
|
|
118
|
+
result = await keystores.update({config});
|
|
119
|
+
} catch(e) {
|
|
120
|
+
err = e;
|
|
121
|
+
} finally {
|
|
122
|
+
keystores._KEYSTORE_CONFIG_CACHE.delete = oldDelete;
|
|
123
|
+
}
|
|
124
|
+
assertNoError(err);
|
|
125
|
+
result.should.be.a('boolean');
|
|
126
|
+
result.should.be.true;
|
|
127
|
+
|
|
128
|
+
// get keystore config, should be stale
|
|
129
|
+
const stale = await keystores.get({id: config.id});
|
|
130
|
+
stale.config.controller.should.not.equal(config.controller);
|
|
131
|
+
|
|
132
|
+
// get fresh config
|
|
133
|
+
const fresh = await keystores.get({id: config.id, fresh: true});
|
|
134
|
+
fresh.config.controller.should.equal(config.controller);
|
|
135
|
+
});
|
|
96
136
|
it('fails to updates a keystore using wrong sequence number', async () => {
|
|
97
137
|
let err;
|
|
98
138
|
let result;
|