diff --git a/bindings/wasm/docs/api-reference.md b/bindings/wasm/docs/api-reference.md index e9e3a65a85..e83bbc81b6 100644 --- a/bindings/wasm/docs/api-reference.md +++ b/bindings/wasm/docs/api-reference.md @@ -187,10 +187,6 @@ working with storage backed DID documents.

## Members
-
StateMetadataEncoding
-
-
MethodRelationship
-
CredentialStatus
SubjectHolderRelationship
@@ -207,6 +203,9 @@ This variant is the default.

Any

The holder is not required to have any kind of relationship to any credential subject.

+
StatusPurpose
+

Purpose of a StatusList2021.

+
FailFast

Declares when validation should return if an error occurs.

@@ -216,9 +215,6 @@ This variant is the default.

FirstError

Return after the first error occurs.

-
StatusPurpose
-

Purpose of a StatusList2021.

-
StatusCheck

Controls validation behaviour when checking whether or not a credential has been revoked by its credentialStatus.

@@ -236,16 +232,17 @@ This variant is the default.

SkipAll

Skip all status checks.

+
StateMetadataEncoding
+
+
MethodRelationship
+
## Functions
-
encodeB64(data)string
-

Encode the given bytes in url-safe base64.

-
-
decodeB64(data)Uint8Array
-

Decode the given url-safe base64-encoded slice into its raw bytes.

+
start()
+

Initializes the console error panic hook for better error messages

verifyEd25519(alg, signingInput, decodedSignature, publicKey)

Verify a JWS signature secured with the EdDSA algorithm and curve Ed25519.

@@ -255,8 +252,11 @@ This variant is the default.

This function does not check whether alg = EdDSA in the protected header. Callers are expected to assert this prior to calling the function.

-
start()
-

Initializes the console error panic hook for better error messages

+
encodeB64(data)string
+

Encode the given bytes in url-safe base64.

+
+
decodeB64(data)Uint8Array
+

Decode the given url-safe base64-encoded slice into its raw bytes.

@@ -1967,6 +1967,7 @@ if the object is being concurrently modified. * _instance_ * [.id()](#IotaDocument+id) ⇒ [IotaDID](#IotaDID) * [.controller()](#IotaDocument+controller) ⇒ [Array.<IotaDID>](#IotaDID) + * [.setController(controllers)](#IotaDocument+setController) * [.alsoKnownAs()](#IotaDocument+alsoKnownAs) ⇒ Array.<string> * [.setAlsoKnownAs(urls)](#IotaDocument+setAlsoKnownAs) * [.properties()](#IotaDocument+properties) ⇒ Map.<string, any> @@ -2039,6 +2040,20 @@ NOTE: controllers are determined by the `state_controller` unlock condition of t during resolution and are omitted when publishing. **Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setController(controllers) +Sets the controllers of the document. + +Note: Duplicates will be ignored. +Use `null` to remove all controllers. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| controllers | [CoreDID](#CoreDID) \| [Array.<CoreDID>](#CoreDID) \| null | + ### iotaDocument.alsoKnownAs() ⇒ Array.<string> @@ -6104,14 +6119,6 @@ Deserializes an instance from a JSON object. | --- | --- | | json | any | - - -## StateMetadataEncoding -**Kind**: global variable - - -## MethodRelationship -**Kind**: global variable ## CredentialStatus @@ -6142,6 +6149,12 @@ The holder must match the subject only for credentials where the [`nonTransferab ## Any The holder is not required to have any kind of relationship to any credential subject. +**Kind**: global variable + + +## StatusPurpose +Purpose of a [StatusList2021](#StatusList2021). + **Kind**: global variable @@ -6160,12 +6173,6 @@ Return all errors that occur during validation. ## FirstError Return after the first error occurs. -**Kind**: global variable - - -## StatusPurpose -Purpose of a [StatusList2021](#StatusList2021). - **Kind**: global variable @@ -6198,28 +6205,20 @@ Validate the status if supported, skip any unsupported Skip all status checks. **Kind**: global variable - - -## encodeB64(data) ⇒ string -Encode the given bytes in url-safe base64. - -**Kind**: global function + -| Param | Type | -| --- | --- | -| data | Uint8Array | +## StateMetadataEncoding +**Kind**: global variable + - +## MethodRelationship +**Kind**: global variable + -## decodeB64(data) ⇒ Uint8Array -Decode the given url-safe base64-encoded slice into its raw bytes. +## start() +Initializes the console error panic hook for better error messages **Kind**: global function - -| Param | Type | -| --- | --- | -| data | Uint8Array | - ## verifyEd25519(alg, signingInput, decodedSignature, publicKey) @@ -6242,9 +6241,25 @@ prior to calling the function. | decodedSignature | Uint8Array | | publicKey | [Jwk](#Jwk) | - + -## start() -Initializes the console error panic hook for better error messages +## encodeB64(data) ⇒ string +Encode the given bytes in url-safe base64. + +**Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +## decodeB64(data) ⇒ Uint8Array +Decode the given url-safe base64-encoded slice into its raw bytes. **Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + diff --git a/bindings/wasm/src/iota/iota_document.rs b/bindings/wasm/src/iota/iota_document.rs index 8f8cbe6823..8d004422ad 100644 --- a/bindings/wasm/src/iota/iota_document.rs +++ b/bindings/wasm/src/iota/iota_document.rs @@ -5,12 +5,14 @@ use std::rc::Rc; use identity_iota::core::Object; use identity_iota::core::OneOrMany; + use identity_iota::core::OrderedSet; use identity_iota::core::Timestamp; use identity_iota::core::Url; use identity_iota::credential::Credential; use identity_iota::credential::JwtPresentationOptions; use identity_iota::credential::Presentation; + use identity_iota::did::DIDUrl; use identity_iota::iota::block::output::dto::AliasOutputDto; use identity_iota::iota::block::output::AliasOutput; @@ -48,6 +50,7 @@ use crate::credential::WasmJws; use crate::credential::WasmJwt; use crate::credential::WasmPresentation; use crate::did::CoreDocumentLock; + use crate::did::PromiseJws; use crate::did::PromiseJwt; use crate::did::WasmCoreDocument; @@ -156,6 +159,20 @@ impl WasmIotaDocument { ) } + /// Sets the controllers of the document. + /// + /// Note: Duplicates will be ignored. + /// Use `null` to remove all controllers. + #[wasm_bindgen(js_name = setController)] + pub fn set_controller(&mut self, controller: &OptionArrayIotaDID) -> Result<()> { + let controller: Option> = controller.into_serde().wasm_result()?; + match controller { + Some(controller) => self.0.try_write()?.set_controller(controller), + None => self.0.try_write()?.set_controller([]), + }; + Ok(()) + } + /// Returns a copy of the document's `alsoKnownAs` set. #[wasm_bindgen(js_name = alsoKnownAs)] pub fn also_known_as(&self) -> Result { @@ -845,6 +862,9 @@ impl From for WasmIotaDocument { #[wasm_bindgen] extern "C" { + #[wasm_bindgen(typescript_type = "IotaDID[] | null")] + pub type OptionArrayIotaDID; + #[wasm_bindgen(typescript_type = "IotaDID[]")] pub type ArrayIotaDID; diff --git a/identity_iota_core/src/document/iota_document.rs b/identity_iota_core/src/document/iota_document.rs index c3c8551183..04d43e3b68 100644 --- a/identity_iota_core/src/document/iota_document.rs +++ b/identity_iota_core/src/document/iota_document.rs @@ -123,9 +123,6 @@ impl IotaDocument { } /// Returns an iterator yielding the DID controllers. - /// - /// NOTE: controllers are determined by the `state_controller` unlock condition of the output - /// during resolution and are omitted when publishing. pub fn controller(&self) -> impl Iterator + '_ { let core_did_controller_iter = self .document @@ -134,14 +131,29 @@ impl IotaDocument { .into_iter() .flatten(); - // CORRECTNESS: These casts are OK because the public API does not expose methods - // enabling unchecked mutation of the controllers. + // CORRECTNESS: These casts are OK because the public API only allows setting IotaDIDs. core_did_controller_iter.map(IotaDID::from_inner_ref_unchecked) } - /// Returns a mutable reference to the document controller. - pub fn controller_mut(&mut self) -> &mut Option> { - self.document.controller_mut() + /// Sets the value of the document controller. + /// + /// Note: + /// * Duplicates in `controller` will be ignored. + /// * Use an empty collection to clear all controllers. + pub fn set_controller(&mut self, controller: T) + where + T: IntoIterator, + { + let controller_core_dids: Option> = { + let controller_set: OrderedSet = controller.into_iter().map(|value| CoreDID::from(value)).collect(); + if controller_set.is_empty() { + None + } else { + Some(OneOrSet::new_set(controller_set).expect("controller is checked to be not empty")) + } + }; + + *self.document.controller_mut() = controller_core_dids; } /// Returns a reference to the `alsoKnownAs` set. @@ -753,7 +765,7 @@ mod tests { .unwrap(); let mut original_doc: IotaDocument = IotaDocument::new_with_id(document_did.clone()); - *original_doc.controller_mut() = None; + original_doc.set_controller([]); let alias_output: AliasOutput = AliasOutputBuilder::new_with_amount(1, AliasId::from(&document_did)) .with_state_metadata(original_doc.pack().unwrap()) @@ -782,7 +794,7 @@ mod tests { .unwrap(); let mut original_doc: IotaDocument = IotaDocument::new_with_id(document_did.clone()); - *original_doc.controller_mut() = Some(OneOrSet::new_one(CoreDID::from(alias_controller.clone()))); + original_doc.set_controller([alias_controller.clone()]); let alias_output: AliasOutput = AliasOutputBuilder::new_with_amount(1, AliasId::from(&document_did)) .with_state_metadata(original_doc.pack().unwrap()) @@ -815,7 +827,7 @@ mod tests { .unwrap(); let mut original_doc: IotaDocument = IotaDocument::new_with_id(document_did.clone()); - *original_doc.controller_mut() = Some(OneOrSet::new_one(CoreDID::from(external_controller_did.clone()))); + original_doc.set_controller([external_controller_did.clone()]); let alias_output: AliasOutput = AliasOutputBuilder::new_with_amount(1, AliasId::from(&document_did)) .with_state_metadata(original_doc.pack().unwrap())