@bedrock/kms 10.3.0 → 12.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,79 +0,0 @@
1
- /*!
2
- * Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
3
- */
4
- import {keystores} from '@bedrock/kms';
5
-
6
- describe('keystores APIs', () => {
7
- const mockConfig = {
8
- id: 'https://example.com/keystores/se0ea64f2a-06db-4055-93a5-c2f305cd541d',
9
- kmsModule: 'ssm-v1',
10
- controller: '1e65ba0c-966e-440c-bd72-e4b97caeb7f3',
11
- sequence: 0,
12
- };
13
- before(async () => {
14
- let err;
15
- try {
16
- await keystores.insert({config: mockConfig});
17
- } catch(e) {
18
- err = e;
19
- }
20
- assertNoError(err);
21
- });
22
- describe('get API', () => {
23
- it('throws on missing id', async () => {
24
- let err;
25
- let result;
26
- try {
27
- result = await keystores.get();
28
- } catch(e) {
29
- err = e;
30
- }
31
- should.not.exist(result);
32
- should.exist(err);
33
- err.message.should.contain('id (string) is required');
34
- });
35
- it('throws on non-string id', async () => {
36
- let err;
37
- let result;
38
- try {
39
- result = await keystores.get({id: 0});
40
- } catch(e) {
41
- err = e;
42
- }
43
- should.not.exist(result);
44
- should.exist(err);
45
- err.message.should.contain('id (string) is required');
46
- });
47
- it('successfully gets a keystore', async () => {
48
- let err;
49
- let result;
50
- try {
51
- result = await keystores.get({id: mockConfig.id});
52
- } catch(e) {
53
- err = e;
54
- }
55
- assertNoError(err);
56
- should.exist(result);
57
- result.should.be.an('object');
58
- // ensure the projection only return meta & config
59
- Object.keys(result).should.deep.equal(['meta', 'config']);
60
- result.meta.should.have.property('created');
61
- result.meta.should.have.property('updated');
62
- result.config.should.eql(mockConfig);
63
- });
64
- it('unsuccessfully gets a keystore', async () => {
65
- const unknownId = 'bd9a90e3-2989-4d40-81c6-94ad0c98c56c';
66
- let err;
67
- let result;
68
- try {
69
- result = await keystores.get({id: unknownId});
70
- } catch(e) {
71
- err = e;
72
- }
73
- should.not.exist(result);
74
- should.exist(err);
75
- err.name.should.equal('NotFoundError');
76
- err.details.keystoreId.should.equal(unknownId);
77
- });
78
- });
79
- });
@@ -1,127 +0,0 @@
1
- /*!
2
- * Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
3
- */
4
- import {keystores} from '@bedrock/kms';
5
-
6
- describe('keystores APIs', () => {
7
- const mockConfigAlpha = {
8
- id: 'https://example.com/keystores/8b688649-d546-4e88-9027-da434bac495a',
9
- kmsModule: 'ssm-v1',
10
- controller: 'caf40b44-0e66-44ef-b331-23f6ca0bb837',
11
- sequence: 0,
12
- };
13
- // mockConfigBeta one and two have the same controller
14
- const mockConfigBeta1 = {
15
- id: 'https://example.com/keystores/6821b4ec-2630-4bf3-9464-39581d2c4499',
16
- kmsModule: 'ssm-v1',
17
- controller: '8a86d089-3a48-4096-a5a3-b874e873fb60',
18
- sequence: 0,
19
- };
20
- const mockConfigBeta2 = {
21
- id: 'https://example.com/keystores/448cf4ad-e9ff-4bd3-aa9a-b882cd01583c',
22
- kmsModule: 'ssm-v1',
23
- controller: '8a86d089-3a48-4096-a5a3-b874e873fb60',
24
- sequence: 0,
25
- };
26
- before(async () => {
27
- let err;
28
- try {
29
- await keystores.insert({config: mockConfigAlpha});
30
- } catch(e) {
31
- err = e;
32
- }
33
- assertNoError(err);
34
- });
35
- before(async () => {
36
- let err;
37
- try {
38
- await keystores.insert({config: mockConfigBeta1});
39
- await keystores.insert({config: mockConfigBeta2});
40
- } catch(e) {
41
- err = e;
42
- }
43
- assertNoError(err);
44
- });
45
- describe('find API', () => {
46
- it('throws on missing controller', async () => {
47
- let err;
48
- let result;
49
- try {
50
- result = await keystores.find();
51
- } catch(e) {
52
- err = e;
53
- }
54
- should.not.exist(result);
55
- should.exist(err);
56
- err.message.should.contain('options.controller (string) is required');
57
- });
58
- it('throws on non-string controller', async () => {
59
- let err;
60
- let result;
61
- try {
62
- result = await keystores.find({controller: 1});
63
- } catch(e) {
64
- err = e;
65
- }
66
- should.not.exist(result);
67
- should.exist(err);
68
- err.message.should.contain('options.controller (string) is required');
69
- });
70
- it('successfully finds a keystore', async () => {
71
- let err;
72
- let results;
73
- try {
74
- results = await keystores.find(
75
- {controller: mockConfigAlpha.controller});
76
- } catch(e) {
77
- err = e;
78
- }
79
- assertNoError(err);
80
- results.should.be.an('array');
81
- results.should.have.length(1);
82
- const [result] = results;
83
- result.should.be.an('object');
84
- result.should.have.property('meta');
85
- result.meta.should.have.property('created');
86
- result.meta.should.have.property('updated');
87
- result.should.have.property('config');
88
- result.config.should.eql(mockConfigAlpha);
89
- });
90
- it('successfully finds multiple keystores for a controller', async () => {
91
- let err;
92
- let results;
93
- try {
94
- results = await keystores.find(
95
- {controller: mockConfigBeta1.controller});
96
- } catch(e) {
97
- err = e;
98
- }
99
- assertNoError(err);
100
- results.should.be.an('array');
101
- results.should.have.length(2);
102
- for(const result of results) {
103
- result.should.be.an('object');
104
- result.should.have.property('meta');
105
- result.meta.should.have.property('created');
106
- result.meta.should.have.property('updated');
107
- result.should.have.property('config');
108
- }
109
- results.map(r => r.config).should.have.deep.members([
110
- mockConfigBeta1, mockConfigBeta2
111
- ]);
112
- });
113
- it('returns empty array on unknown controller', async () => {
114
- const unknownController = 'bc794e06-e985-45d4-97c3-57d65d393736';
115
- let err;
116
- let results;
117
- try {
118
- results = await keystores.find({controller: unknownController});
119
- } catch(e) {
120
- err = e;
121
- }
122
- assertNoError(err);
123
- results.should.be.an('array');
124
- results.should.have.length(0);
125
- });
126
- });
127
- });
@@ -1,202 +0,0 @@
1
- /*!
2
- * Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
3
- */
4
- import {keystores} from '@bedrock/kms';
5
- import {klona} from 'klona';
6
-
7
- describe('keystores APIs', () => {
8
- const mockConfigAlpha = {
9
- id: 'https://example.com/keystores/b122cc8a-39be-4680-b88e-2593b1295b1b',
10
- kmsModule: 'ssm-v1',
11
- controller: '8a945a10-9f6a-4096-8306-c6c6825a9fe2',
12
- sequence: 0,
13
- referenceId: '95901c02-a4ad-4d3a-be17-0be3aafbe6f3',
14
- };
15
- const mockConfigBeta = {
16
- id: 'https://example.com/keystores/f454ad49-90eb-4f15-aff9-13048adc84d0',
17
- kmsModule: 'ssm-v1',
18
- controller: '8e79ce0e-926d-457c-b520-849663e1d9de',
19
- sequence: 0,
20
- };
21
- const mockConfigGamma = {
22
- id: 'https://example.com/keystores/6be652c3-3ed6-452b-a98a-cb0ad6905f37',
23
- kmsModule: 'ssm-v1',
24
- controller: 'f2da13ee-50d2-46ab-865d-ee23d609edbd',
25
- sequence: 0,
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
- };
33
-
34
- before(async () => {
35
- let err;
36
- try {
37
- await keystores.insert({config: mockConfigAlpha});
38
- await keystores.insert({config: mockConfigBeta});
39
- await keystores.insert({config: mockConfigGamma});
40
- await keystores.insert({config: mockConfigDelta});
41
- } catch(e) {
42
- err = e;
43
- }
44
- assertNoError(err);
45
- });
46
- describe('update API', () => {
47
- it('throws error on missing config', async () => {
48
- let err;
49
- let result;
50
- try {
51
- result = await keystores.update();
52
- } catch(e) {
53
- err = e;
54
- }
55
- should.not.exist(result);
56
- should.exist(err);
57
- err.message.should.contain('config (object) is required');
58
- });
59
- it('successfully updates a keystore', async () => {
60
- let err;
61
- let result;
62
- const config = klona(mockConfigAlpha);
63
- config.sequence++;
64
- config.controller = 'someOtherController';
65
- try {
66
- result = await keystores.update({config});
67
- } catch(e) {
68
- err = e;
69
- }
70
- assertNoError(err);
71
- result.should.be.a('boolean');
72
- result.should.be.true;
73
- });
74
- it('successfully updates a keystore twice', async () => {
75
- let err;
76
- let result;
77
- const config = klona(mockConfigBeta);
78
- config.sequence++;
79
- config.controller = 'someOtherController';
80
- try {
81
- result = await keystores.update({config});
82
- } catch(e) {
83
- err = e;
84
- }
85
- assertNoError(err);
86
- result.should.be.a('boolean');
87
- result.should.be.true;
88
-
89
- // update same config again
90
- config.sequence++;
91
- config.controller = 'someOtherController2';
92
- result = undefined;
93
- err = undefined;
94
- try {
95
- result = await keystores.update({config});
96
- } catch(e) {
97
- err = e;
98
- }
99
- assertNoError(err);
100
- result.should.be.a('boolean');
101
- result.should.be.true;
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
- });
136
- it('fails to updates a keystore using wrong sequence number', async () => {
137
- let err;
138
- let result;
139
- const config = klona(mockConfigGamma);
140
- config.sequence++;
141
- config.controller = 'someOtherController';
142
- try {
143
- result = await keystores.update({config});
144
- } catch(e) {
145
- err = e;
146
- }
147
- assertNoError(err);
148
- result.should.be.a('boolean');
149
- result.should.be.true;
150
-
151
- // update same config again without updating the sequence number
152
- // config.sequence++;
153
-
154
- config.controller = 'someOtherController2';
155
- result = undefined;
156
- err = undefined;
157
- try {
158
- result = await keystores.update({config});
159
- } catch(e) {
160
- err = e;
161
- }
162
- should.not.exist(result);
163
- should.exist(err);
164
- err.name.should.equal('InvalidStateError');
165
- err.details.id.should.equal(config.id);
166
- err.details.sequence.should.equal(config.sequence);
167
- });
168
- it('successfully updates a keystore and invalidates cache', async () => {
169
- let err;
170
- let result;
171
- const config = klona(mockConfigBeta);
172
- config.sequence = 3;
173
- config.controller = 'someOtherController';
174
- try {
175
- result = await keystores.update({config});
176
- } catch(e) {
177
- err = e;
178
- }
179
- assertNoError(err);
180
- result.should.be.a('boolean');
181
- result.should.be.true;
182
- const keyRecord = await keystores.get({id: config.id});
183
- should.exist(keyRecord);
184
- keyRecord.config.sequence.should.equal(3);
185
- });
186
- it('throws error on unknown keystore id', async () => {
187
- let err;
188
- let result;
189
- const config = klona(mockConfigBeta);
190
- config.sequence++;
191
- config.id = 'someOtherId';
192
- try {
193
- result = await keystores.update({config});
194
- } catch(e) {
195
- err = e;
196
- }
197
- should.not.exist(result);
198
- should.exist(err);
199
- err.name.should.equal('InvalidStateError');
200
- });
201
- });
202
- });
@@ -1,119 +0,0 @@
1
- /*!
2
- * Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
3
- */
4
- import {keystores, defaultModuleManager as moduleManager} from '@bedrock/kms';
5
-
6
- describe('keystores APIs', () => {
7
- describe('getStorageUsage API', () => {
8
- it('gets storage usage for a keystore', async () => {
9
- let err;
10
- let result;
11
- const config = {
12
- id: 'https://example.com/keystores/usage-test1',
13
- controller: 'usage-test',
14
- kmsModule: 'ssm-v1',
15
- sequence: 0,
16
- meterId: 'usage-meter-1'
17
- };
18
- try {
19
- await keystores.insert({config});
20
- result = await keystores.getStorageUsage({
21
- meterId: 'usage-meter-1', moduleManager
22
- });
23
- } catch(e) {
24
- err = e;
25
- }
26
- assertNoError(err);
27
- should.exist(result);
28
- result.should.be.an('object');
29
- result.should.deep.equal({storage: 1});
30
- });
31
- it('gets custom storage usage for a keystore', async () => {
32
- let err;
33
- let result;
34
- const config = {
35
- id: 'https://example.com/keystores/usage-test2',
36
- controller: 'usage-test',
37
- kmsModule: 'ssm-v1',
38
- sequence: 0,
39
- meterId: 'usage-meter-2'
40
- };
41
- try {
42
- await keystores.insert({config});
43
- result = await keystores.getStorageUsage({
44
- meterId: 'usage-meter-2', moduleManager,
45
- async aggregate({usage}) {
46
- usage.storage++;
47
- }
48
- });
49
- } catch(e) {
50
- err = e;
51
- }
52
- assertNoError(err);
53
- should.exist(result);
54
- result.should.be.an('object');
55
- result.should.deep.equal({storage: 2});
56
- });
57
- it('gets custom storage usage for a keystore when max concurrency is ' +
58
- 'reached', async () => {
59
- let err;
60
- let result;
61
- // 54 is used in order to have a counters.length of 102 to ensure max
62
- // concurrency of 100 (`USAGE_COUNTER_MAX_CONCURRENCY`) is reached;
63
- // if this max concurrency changes, this test will need to change too
64
- for(let i = 3; i < 54; i++) {
65
- const config = {
66
- id: `https://example.com/keystores/usage-test${i}`,
67
- controller: 'usage-test',
68
- kmsModule: 'ssm-v1',
69
- sequence: 0,
70
- meterId: `usage-meter-3`
71
- };
72
- await keystores.insert({config});
73
- }
74
- try {
75
- result = await keystores.getStorageUsage({
76
- meterId: 'usage-meter-3', moduleManager,
77
- async aggregate({usage}) {
78
- usage.storage++;
79
- }
80
- });
81
- } catch(e) {
82
- err = e;
83
- }
84
- assertNoError(err);
85
- should.exist(result);
86
- result.should.be.an('object');
87
- result.should.deep.equal({storage: 102});
88
- });
89
- it('aborts computing metered storage', async () => {
90
- let err;
91
- let result;
92
- const config = {
93
- id: 'https://example.com/keystores/usage-test55',
94
- controller: 'usage-test',
95
- kmsModule: 'ssm-v1',
96
- sequence: 0,
97
- meterId: 'usage-meter-55'
98
- };
99
- try {
100
- await keystores.insert({config});
101
- result = await keystores.getStorageUsage({
102
- signal: {
103
- abort: true
104
- },
105
- meterId: 'usage-meter-55', moduleManager,
106
- async aggregate({usage}) {
107
- usage.storage++;
108
- }
109
- });
110
- } catch(e) {
111
- err = e;
112
- }
113
-
114
- should.exist(err);
115
- should.not.exist(result);
116
- err.name.should.equal('AbortError');
117
- });
118
- }); // end getStorageUsage API
119
- }); // end keystore APIs