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

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.
@@ -176,6 +176,26 @@ class EntityStorageIdentityConnector {
176
176
  throw new core.GeneralError(this.CLASS_NAME, "createDocumentFailed", undefined, error);
177
177
  }
178
178
  }
179
+ /**
180
+ * Remove a document.
181
+ * @param controller The controller of the identity who can make changes.
182
+ * @param documentId The id of the document to remove.
183
+ * @returns Nothing.
184
+ */
185
+ async removeDocument(controller, documentId) {
186
+ core.Guards.stringValue(this.CLASS_NAME, "controller", controller);
187
+ core.Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
188
+ try {
189
+ const didDocument = await this._didDocumentEntityStorage.get(documentId);
190
+ if (core.Is.empty(didDocument)) {
191
+ throw new core.NotFoundError(this.CLASS_NAME, "documentNotFound", documentId);
192
+ }
193
+ await this._didDocumentEntityStorage.remove(documentId);
194
+ }
195
+ catch (error) {
196
+ throw new core.GeneralError(this.CLASS_NAME, "removeDocumentFailed", undefined, error);
197
+ }
198
+ }
179
199
  /**
180
200
  * Add a verification method to the document in JSON Web key Format.
181
201
  * @param controller The controller of the identity who can make changes.
@@ -190,6 +210,7 @@ class EntityStorageIdentityConnector {
190
210
  core.Guards.stringValue(this.CLASS_NAME, "controller", controller);
191
211
  core.Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
192
212
  core.Guards.arrayOneOf(this.CLASS_NAME, "verificationMethodType", verificationMethodType, Object.values(standardsW3cDid.DidVerificationMethodType));
213
+ let tempKeyId;
193
214
  try {
194
215
  const didIdentityDocument = await this._didDocumentEntityStorage.get(documentId);
195
216
  if (core.Is.undefined(didIdentityDocument)) {
@@ -197,17 +218,35 @@ class EntityStorageIdentityConnector {
197
218
  }
198
219
  await EntityStorageIdentityConnector.verifyDocument(didIdentityDocument, this._vaultConnector);
199
220
  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);
221
+ let methodKeyPublic;
222
+ if (core.Is.stringValue(verificationMethodId)) {
223
+ // If there is a verification method id, we will try to get the key from the vault.
224
+ try {
225
+ const defaultMethodId = `${controller}/${verificationMethodId}`;
226
+ // If there is an existing key, we will use it.
227
+ const existingKey = await this._vaultConnector.getKey(defaultMethodId);
228
+ methodKeyPublic = existingKey.publicKey;
229
+ }
230
+ catch { }
231
+ }
232
+ if (core.Is.empty(methodKeyPublic)) {
233
+ // If there is no existing key, we will create a new one with a temporary name.
234
+ tempKeyId = `temp-vm-${core.Converter.bytesToBase64Url(core.RandomHelper.generate(16))}`;
235
+ methodKeyPublic = await this._vaultConnector.createKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), vaultModels.VaultKeyType.Ed25519);
236
+ }
202
237
  const jwkParams = {
203
238
  alg: "EdDSA",
204
239
  kty: "OKP",
205
240
  crv: "Ed25519",
206
- x: core.Converter.bytesToBase64Url(verificationPublicKey)
241
+ x: core.Converter.bytesToBase64Url(methodKeyPublic)
207
242
  };
208
243
  const kid = await web.Jwk.generateKid(jwkParams);
209
244
  const methodId = `${documentId}#${verificationMethodId ?? kid}`;
210
- await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
245
+ if (core.Is.stringValue(tempKeyId)) {
246
+ // If we created a temporary key, we will rename it to the final method id.
247
+ await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
248
+ tempKeyId = undefined;
249
+ }
211
250
  const methods = this.getAllMethods(didDocument);
212
251
  const existingMethodIndex = methods.findIndex(m => {
213
252
  if (core.Is.string(m.method)) {
@@ -238,6 +277,15 @@ class EntityStorageIdentityConnector {
238
277
  catch (error) {
239
278
  throw new core.GeneralError(this.CLASS_NAME, "addVerificationMethodFailed", undefined, error);
240
279
  }
280
+ finally {
281
+ if (core.Is.stringValue(tempKeyId)) {
282
+ // If we created a temporary key and it is still in use, we will remove it from the vault.
283
+ try {
284
+ await this._vaultConnector.removeKey(tempKeyId);
285
+ }
286
+ catch { }
287
+ }
288
+ }
241
289
  }
242
290
  /**
243
291
  * Remove a verification method from the document.
@@ -174,6 +174,26 @@ class EntityStorageIdentityConnector {
174
174
  throw new GeneralError(this.CLASS_NAME, "createDocumentFailed", undefined, error);
175
175
  }
176
176
  }
177
+ /**
178
+ * Remove a document.
179
+ * @param controller The controller of the identity who can make changes.
180
+ * @param documentId The id of the document to remove.
181
+ * @returns Nothing.
182
+ */
183
+ async removeDocument(controller, documentId) {
184
+ Guards.stringValue(this.CLASS_NAME, "controller", controller);
185
+ Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
186
+ try {
187
+ const didDocument = await this._didDocumentEntityStorage.get(documentId);
188
+ if (Is.empty(didDocument)) {
189
+ throw new NotFoundError(this.CLASS_NAME, "documentNotFound", documentId);
190
+ }
191
+ await this._didDocumentEntityStorage.remove(documentId);
192
+ }
193
+ catch (error) {
194
+ throw new GeneralError(this.CLASS_NAME, "removeDocumentFailed", undefined, error);
195
+ }
196
+ }
177
197
  /**
178
198
  * Add a verification method to the document in JSON Web key Format.
179
199
  * @param controller The controller of the identity who can make changes.
@@ -188,6 +208,7 @@ class EntityStorageIdentityConnector {
188
208
  Guards.stringValue(this.CLASS_NAME, "controller", controller);
189
209
  Guards.stringValue(this.CLASS_NAME, "documentId", documentId);
190
210
  Guards.arrayOneOf(this.CLASS_NAME, "verificationMethodType", verificationMethodType, Object.values(DidVerificationMethodType));
211
+ let tempKeyId;
191
212
  try {
192
213
  const didIdentityDocument = await this._didDocumentEntityStorage.get(documentId);
193
214
  if (Is.undefined(didIdentityDocument)) {
@@ -195,17 +216,35 @@ class EntityStorageIdentityConnector {
195
216
  }
196
217
  await EntityStorageIdentityConnector.verifyDocument(didIdentityDocument, this._vaultConnector);
197
218
  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);
219
+ let methodKeyPublic;
220
+ if (Is.stringValue(verificationMethodId)) {
221
+ // If there is a verification method id, we will try to get the key from the vault.
222
+ try {
223
+ const defaultMethodId = `${controller}/${verificationMethodId}`;
224
+ // If there is an existing key, we will use it.
225
+ const existingKey = await this._vaultConnector.getKey(defaultMethodId);
226
+ methodKeyPublic = existingKey.publicKey;
227
+ }
228
+ catch { }
229
+ }
230
+ if (Is.empty(methodKeyPublic)) {
231
+ // If there is no existing key, we will create a new one with a temporary name.
232
+ tempKeyId = `temp-vm-${Converter.bytesToBase64Url(RandomHelper.generate(16))}`;
233
+ methodKeyPublic = await this._vaultConnector.createKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), VaultKeyType.Ed25519);
234
+ }
200
235
  const jwkParams = {
201
236
  alg: "EdDSA",
202
237
  kty: "OKP",
203
238
  crv: "Ed25519",
204
- x: Converter.bytesToBase64Url(verificationPublicKey)
239
+ x: Converter.bytesToBase64Url(methodKeyPublic)
205
240
  };
206
241
  const kid = await Jwk.generateKid(jwkParams);
207
242
  const methodId = `${documentId}#${verificationMethodId ?? kid}`;
208
- await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
243
+ if (Is.stringValue(tempKeyId)) {
244
+ // If we created a temporary key, we will rename it to the final method id.
245
+ await this._vaultConnector.renameKey(EntityStorageIdentityConnector.buildVaultKey(didDocument.id, tempKeyId), EntityStorageIdentityConnector.buildVaultKey(didDocument.id, verificationMethodId ?? kid));
246
+ tempKeyId = undefined;
247
+ }
209
248
  const methods = this.getAllMethods(didDocument);
210
249
  const existingMethodIndex = methods.findIndex(m => {
211
250
  if (Is.string(m.method)) {
@@ -236,6 +275,15 @@ class EntityStorageIdentityConnector {
236
275
  catch (error) {
237
276
  throw new GeneralError(this.CLASS_NAME, "addVerificationMethodFailed", undefined, error);
238
277
  }
278
+ finally {
279
+ if (Is.stringValue(tempKeyId)) {
280
+ // If we created a temporary key and it is still in use, we will remove it from the vault.
281
+ try {
282
+ await this._vaultConnector.removeKey(tempKeyId);
283
+ }
284
+ catch { }
285
+ }
286
+ }
239
287
  }
240
288
  /**
241
289
  * Remove a verification method from the document.
@@ -25,6 +25,13 @@ export declare class EntityStorageIdentityConnector implements IIdentityConnecto
25
25
  * @returns The created document.
26
26
  */
27
27
  createDocument(controller: string): Promise<IDidDocument>;
28
+ /**
29
+ * Remove a document.
30
+ * @param controller The controller of the identity who can make changes.
31
+ * @param documentId The id of the document to remove.
32
+ * @returns Nothing.
33
+ */
34
+ removeDocument(controller: string, documentId: string): Promise<void>;
28
35
  /**
29
36
  * Add a verification method to the document in JSON Web key Format.
30
37
  * @param controller The controller of the identity who can make changes.
package/docs/changelog.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @twin.org/identity-connector-entity-storage- Changelog
2
2
 
3
+ ## [0.0.1-next.57](https://github.com/twinfoundation/identity/compare/identity-connector-entity-storage-v0.0.1-next.56...identity-connector-entity-storage-v0.0.1-next.57) (2025-07-08)
4
+
5
+
6
+ ### Features
7
+
8
+ * add identity remove ([eebc13f](https://github.com/twinfoundation/identity/commit/eebc13f4c2cd994d2d9cce4da2128fb346c80ba7))
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.56 to 0.0.1-next.57
16
+
17
+ ## [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)
18
+
19
+
20
+ ### Features
21
+
22
+ * re-use vault keys if available ([5a848d7](https://github.com/twinfoundation/identity/commit/5a848d7520829d9c891ec889fd773fbc0ee77ba5))
23
+
24
+
25
+ ### Dependencies
26
+
27
+ * The following workspace dependencies were updated
28
+ * dependencies
29
+ * @twin.org/identity-models bumped from 0.0.1-next.55 to 0.0.1-next.56
30
+
3
31
  ## [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
32
 
5
33
 
@@ -74,6 +74,38 @@ The created document.
74
74
 
75
75
  ***
76
76
 
77
+ ### removeDocument()
78
+
79
+ > **removeDocument**(`controller`, `documentId`): `Promise`\<`void`\>
80
+
81
+ Remove a document.
82
+
83
+ #### Parameters
84
+
85
+ ##### controller
86
+
87
+ `string`
88
+
89
+ The controller of the identity who can make changes.
90
+
91
+ ##### documentId
92
+
93
+ `string`
94
+
95
+ The id of the document to remove.
96
+
97
+ #### Returns
98
+
99
+ `Promise`\<`void`\>
100
+
101
+ Nothing.
102
+
103
+ #### Implementation of
104
+
105
+ `IIdentityConnector.removeDocument`
106
+
107
+ ***
108
+
77
109
  ### addVerificationMethod()
78
110
 
79
111
  > **addVerificationMethod**(`controller`, `documentId`, `verificationMethodType`, `verificationMethodId?`): `Promise`\<`IDidDocumentVerificationMethod`\>
package/locales/en.json CHANGED
@@ -6,13 +6,14 @@
6
6
  },
7
7
  "entityStorageIdentityConnector": {
8
8
  "createDocumentFailed": "Creating the document failed",
9
+ "removeDocumentFailed": "Removing the document failed",
9
10
  "signatureVerificationFailed": "The document integrity check failed",
10
11
  "missingDid": "The full id including DID is required",
11
12
  "addVerificationMethodFailed": "Adding the verification method failed",
12
13
  "removeVerificationMethodFailed": "Removing the verification method failed",
13
14
  "addServiceFailed": "Adding the service failed",
14
15
  "removeServiceFailed": "Removing the service failed",
15
- "documentNotFound": "The document could not be found",
16
+ "documentNotFound": "The document could not be found \"{notFoundId}\"",
16
17
  "documentPrivateKeyNotFound": "The private key for document could not be found in the vault",
17
18
  "verificationMethodNotFound": "The verification method could not be found",
18
19
  "verificationPrivateKeyNotFound": "The private key for the verification method could not be found in the vault",
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.57",
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.57",
23
23
  "@twin.org/nameof": "next",
24
24
  "@twin.org/standards-w3c-did": "next",
25
25
  "@twin.org/vault-models": "next",