@twin.org/identity-connector-entity-storage 0.0.1-next.55 → 0.0.1-next.56

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.
@@ -190,6 +190,7 @@ class EntityStorageIdentityConnector {
190
190
  core.Guards.stringValue(this.CLASS_NAME, "controller", controller);
191
191
  core.Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
192
192
  core.Guards.arrayOneOf(this.CLASS_NAME, "verificationMethodType", verificationMethodType, Object.values(standardsW3cDid.DidVerificationMethodType));
193
+ let tempKeyId;
193
194
  try {
194
195
  const didIdentityDocument = await this._didDocumentEntityStorage.get(documentId);
195
196
  if (core.Is.undefined(didIdentityDocument)) {
@@ -197,17 +198,35 @@ class EntityStorageIdentityConnector {
197
198
  }
198
199
  await EntityStorageIdentityConnector.verifyDocument(didIdentityDocument, this._vaultConnector);
199
200
  const didDocument = didIdentityDocument.document;
200
- const tempKeyId = `temp-vm-${core.Converter.bytesToBase64Url(core.RandomHelper.generate(16))}`;
201
- const verificationPublicKey = await this._vaultConnector.createKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), vaultModels.VaultKeyType.Ed25519);
201
+ let methodKeyPublic;
202
+ if (core.Is.stringValue(verificationMethodId)) {
203
+ // If there is a verification method id, we will try to get the key from the vault.
204
+ try {
205
+ const defaultMethodId = `${controller}/${verificationMethodId}`;
206
+ // If there is an existing key, we will use it.
207
+ const existingKey = await this._vaultConnector.getKey(defaultMethodId);
208
+ methodKeyPublic = existingKey.publicKey;
209
+ }
210
+ catch { }
211
+ }
212
+ if (core.Is.empty(methodKeyPublic)) {
213
+ // If there is no existing key, we will create a new one with a temporary name.
214
+ tempKeyId = `temp-vm-${core.Converter.bytesToBase64Url(core.RandomHelper.generate(16))}`;
215
+ methodKeyPublic = await this._vaultConnector.createKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), vaultModels.VaultKeyType.Ed25519);
216
+ }
202
217
  const jwkParams = {
203
218
  alg: "EdDSA",
204
219
  kty: "OKP",
205
220
  crv: "Ed25519",
206
- x: core.Converter.bytesToBase64Url(verificationPublicKey)
221
+ x: core.Converter.bytesToBase64Url(methodKeyPublic)
207
222
  };
208
223
  const kid = await web.Jwk.generateKid(jwkParams);
209
224
  const methodId = `${documentId}#${verificationMethodId ?? kid}`;
210
- await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
225
+ if (core.Is.stringValue(tempKeyId)) {
226
+ // If we created a temporary key, we will rename it to the final method id.
227
+ await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
228
+ tempKeyId = undefined;
229
+ }
211
230
  const methods = this.getAllMethods(didDocument);
212
231
  const existingMethodIndex = methods.findIndex(m => {
213
232
  if (core.Is.string(m.method)) {
@@ -238,6 +257,15 @@ class EntityStorageIdentityConnector {
238
257
  catch (error) {
239
258
  throw new core.GeneralError(this.CLASS_NAME, "addVerificationMethodFailed", undefined, error);
240
259
  }
260
+ finally {
261
+ if (core.Is.stringValue(tempKeyId)) {
262
+ // If we created a temporary key and it is still in use, we will remove it from the vault.
263
+ try {
264
+ await this._vaultConnector.removeKey(tempKeyId);
265
+ }
266
+ catch { }
267
+ }
268
+ }
241
269
  }
242
270
  /**
243
271
  * Remove a verification method from the document.
@@ -188,6 +188,7 @@ class EntityStorageIdentityConnector {
188
188
  Guards.stringValue(this.CLASS_NAME, "controller", controller);
189
189
  Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
190
190
  Guards.arrayOneOf(this.CLASS_NAME, "verificationMethodType", verificationMethodType, Object.values(DidVerificationMethodType));
191
+ let tempKeyId;
191
192
  try {
192
193
  const didIdentityDocument = await this._didDocumentEntityStorage.get(documentId);
193
194
  if (Is.undefined(didIdentityDocument)) {
@@ -195,17 +196,35 @@ class EntityStorageIdentityConnector {
195
196
  }
196
197
  await EntityStorageIdentityConnector.verifyDocument(didIdentityDocument, this._vaultConnector);
197
198
  const didDocument = didIdentityDocument.document;
198
- const tempKeyId = `temp-vm-${Converter.bytesToBase64Url(RandomHelper.generate(16))}`;
199
- const verificationPublicKey = await this._vaultConnector.createKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), VaultKeyType.Ed25519);
199
+ let methodKeyPublic;
200
+ if (Is.stringValue(verificationMethodId)) {
201
+ // If there is a verification method id, we will try to get the key from the vault.
202
+ try {
203
+ const defaultMethodId = `${controller}/${verificationMethodId}`;
204
+ // If there is an existing key, we will use it.
205
+ const existingKey = await this._vaultConnector.getKey(defaultMethodId);
206
+ methodKeyPublic = existingKey.publicKey;
207
+ }
208
+ catch { }
209
+ }
210
+ if (Is.empty(methodKeyPublic)) {
211
+ // If there is no existing key, we will create a new one with a temporary name.
212
+ tempKeyId = `temp-vm-${Converter.bytesToBase64Url(RandomHelper.generate(16))}`;
213
+ methodKeyPublic = await this._vaultConnector.createKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), VaultKeyType.Ed25519);
214
+ }
200
215
  const jwkParams = {
201
216
  alg: "EdDSA",
202
217
  kty: "OKP",
203
218
  crv: "Ed25519",
204
- x: Converter.bytesToBase64Url(verificationPublicKey)
219
+ x: Converter.bytesToBase64Url(methodKeyPublic)
205
220
  };
206
221
  const kid = await Jwk.generateKid(jwkParams);
207
222
  const methodId = `${documentId}#${verificationMethodId ?? kid}`;
208
- await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
223
+ if (Is.stringValue(tempKeyId)) {
224
+ // If we created a temporary key, we will rename it to the final method id.
225
+ await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
226
+ tempKeyId = undefined;
227
+ }
209
228
  const methods = this.getAllMethods(didDocument);
210
229
  const existingMethodIndex = methods.findIndex(m => {
211
230
  if (Is.string(m.method)) {
@@ -236,6 +255,15 @@ class EntityStorageIdentityConnector {
236
255
  catch (error) {
237
256
  throw new GeneralError(this.CLASS_NAME, "addVerificationMethodFailed", undefined, error);
238
257
  }
258
+ finally {
259
+ if (Is.stringValue(tempKeyId)) {
260
+ // If we created a temporary key and it is still in use, we will remove it from the vault.
261
+ try {
262
+ await this._vaultConnector.removeKey(tempKeyId);
263
+ }
264
+ catch { }
265
+ }
266
+ }
239
267
  }
240
268
  /**
241
269
  * Remove a verification method from the document.
package/docs/changelog.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @twin.org/identity-connector-entity-storage- Changelog
2
2
 
3
+ ## [0.0.1-next.56](https://github.com/twinfoundation/identity/compare/identity-connector-entity-storage-v0.0.1-next.55...identity-connector-entity-storage-v0.0.1-next.56) (2025-06-30)
4
+
5
+
6
+ ### Features
7
+
8
+ * re-use vault keys if available ([5a848d7](https://github.com/twinfoundation/identity/commit/5a848d7520829d9c891ec889fd773fbc0ee77ba5))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/identity-models bumped from 0.0.1-next.55 to 0.0.1-next.56
16
+
3
17
  ## [0.0.1-next.55](https://github.com/twinfoundation/identity/compare/identity-connector-entity-storage-v0.0.1-next.54...identity-connector-entity-storage-v0.0.1-next.55) (2025-06-26)
4
18
 
5
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/identity-connector-entity-storage",
3
- "version": "0.0.1-next.55",
3
+ "version": "0.0.1-next.56",
4
4
  "description": "Identity connector implementation using entity storage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "@twin.org/data-core": "next",
20
20
  "@twin.org/data-json-ld": "next",
21
21
  "@twin.org/entity": "next",
22
- "@twin.org/identity-models": "0.0.1-next.55",
22
+ "@twin.org/identity-models": "0.0.1-next.56",
23
23
  "@twin.org/nameof": "next",
24
24
  "@twin.org/standards-w3c-did": "next",
25
25
  "@twin.org/vault-models": "next",