Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Threema/libthreema/lib/src/bindings/wasm/   (Social Medium ©)  Datei vom 26.9.2026 mit Größe 15 kB image not shown  

Quelle  remote_secret.rs   Sprache: Rust

 

//! Bindings for the _Remote Secret_.
pub mod setup {
    //! Bindings for the remote secret setup.
    use js_sys::Error;
    use serde::Deserialize;
    use serde_bytes::ByteBuf;
    use tsify::Tsify;
    use wasm_bindgen::prelude::wasm_bindgen;

    use crate::{
        common::{
            ClientInfo, ThreemaId,
            config::{WorkContext, WorkServerBaseUrl},
            keys::ClientKey,
        },
        remote_secret::setup,
    };

    /// Binding version of [`setup::RemoteSecretSetupContext`].
    #[derive(Tsify, Deserialize)]
    #[serde(rename_all = "camelCase")]
    #[tsify(from_wasm_abi)]
    pub struct RemoteSecretSetupContext {
        /// Client info.
        pub client_info: ClientInfo,

        /// Work directory server base URL. Must end with a trailing slash.
        pub work_server_base_url: String,

        /// Work (or OnPrem) application configuration.
        pub work_context: WorkContext,

        /// The user's identity.
        pub user_identity: String,

        /// Client key (32 bytes).
        pub client_key: ByteBuf,
    }

    impl TryFrom<RemoteSecretSetupContext> for setup::RemoteSecretSetupContext {
        type Error = Error;

        fn try_from(context: RemoteSecretSetupContext) -> Result<Self, Self::Error> {
            let work_server_url = WorkServerBaseUrl::try_from(context.work_server_base_url)
                .map_err(|_| Error::new("'work_server_base_url' invalid"))?;

            let client_key: [u8; ClientKey::LENGTH] = context
                .client_key
                .to_vec()
                .try_into()
                .map_err(|_| Error::new("'client_key' must be 32 bytes"))?;

            let user_identity = ThreemaId::try_from(context.user_identity.as_str())
                .map_err(|_| Error::new("'user_identity' invalid"))?;

            Ok(Self {
                client_info: context.client_info,
                work_server_url,
                work_context: context.work_context,
                user_identity,
                client_key: client_key.into(),
            })
        }
    }

    pub mod create {
        //! Bindings for the remote secret creation.
        use js_sys::Error;
        use serde::Serialize;
        use serde_bytes::ByteBuf;
        use tsify::Tsify;
        use wasm_bindgen::prelude::wasm_bindgen;

        use crate::{
            bindings::wasm::https::{HttpsRequest, HttpsResult},
            remote_secret::setup::{self, create},
        };

        /// Binding version of [`create::RemoteSecretCreateResult`].
        #[derive(Tsify, Serialize)]
        #[serde(rename_all = "camelCase")]
        #[tsify(into_wasm_abi)]
        #[expect(clippy::struct_field_names, reason = "Names as defined in protocol")]
        pub struct RemoteSecretCreateResult {
            /// Established remote secret (32 bytes).
            pub remote_secret: ByteBuf,

            /// Assigned remote secret authentication token (32 bytes).
            pub remote_secret_authentication_token: ByteBuf,

            /// The hash derived from the `remote_secret` (32 bytes).
            pub remote_secret_hash: ByteBuf,
        }
        impl From<create::RemoteSecretCreateResult> for RemoteSecretCreateResult {
            fn from(result: create::RemoteSecretCreateResult) -> Self {
                Self {
                    remote_secret: ByteBuf::from(result.remote_secret.0.to_vec()),
                    remote_secret_authentication_token: ByteBuf::from(
                        result.remote_secret_authentication_token.0.to_vec(),
                    ),
                    remote_secret_hash: ByteBuf::from(result.remote_secret.derive_hash().0.to_vec()),
                }
            }
        }

        /// Binding version of [`create::RemoteSecretCreateLoop`].
        #[derive(Tsify, Serialize)]
        #[serde(
            tag = "type",
            content = "value",
            rename_all = "kebab-case",
            rename_all_fields = "camelCase"
        )]
        #[tsify(into_wasm_abi)]
        pub enum RemoteSecretCreateLoop {
            #[expect(missing_docs, reason = "Binding version")]
            Instruction(HttpsRequest),

            #[expect(missing_docs, reason = "Binding version")]
            Done(RemoteSecretCreateResult),
        }

        impl From<create::RemoteSecretCreateLoop> for RemoteSecretCreateLoop {
            fn from(create_loop: create::RemoteSecretCreateLoop) -> Self {
                match create_loop {
                    create::RemoteSecretCreateLoop::Instruction(setup::RemoteSecretSetupInstruction {
                        request,
                    }) => Self::Instruction(request.into()),

                    create::RemoteSecretCreateLoop::Done(result) => Self::Done(result.into()),
                }
            }
        }

        /// Binding version of a [`RemoteSecretCreateTask::poll`] result.
        #[derive(Tsify, Serialize)]
        #[serde(
            tag = "type",
            content = "value",
            rename_all = "kebab-case",
            rename_all_fields = "camelCase"
        )]
        #[tsify(into_wasm_abi)]
        pub enum RemoteSecretCreatePollResult {
            #[expect(missing_docs, reason = "Binding version")]
            CreateLoop(RemoteSecretCreateLoop),

            #[expect(missing_docs, reason = "Binding version")]
            Error(setup::RemoteSecretSetupError),
        }

        impl From<Result<create::RemoteSecretCreateLoop, setup::RemoteSecretSetupError>>
            for RemoteSecretCreatePollResult
        {
            fn from(result: Result<create::RemoteSecretCreateLoop, setup::RemoteSecretSetupError>) -> Self {
                match result {
                    Ok(create_loop) => Self::CreateLoop(create_loop.into()),
                    Err(error) => Self::Error(error),
                }
            }
        }

        /// Binding version of [`create::RemoteSecretCreateTask`].
        #[wasm_bindgen]
        pub struct RemoteSecretCreateTask(create::RemoteSecretCreateTask);

        #[wasm_bindgen]
        impl RemoteSecretCreateTask {
            /// Binding version of [`create::RemoteSecretCreateTask::new`].
            ///
            /// # Errors
            ///
            /// Returns an error if `context` contains invalid parameters.
            pub fn new(context: super::RemoteSecretSetupContext) -> Result<Self, Error> {
                Ok(Self(create::RemoteSecretCreateTask::new(context.try_into()?)))
            }

            /// Binding version of [`create::RemoteSecretCreateTask::poll`].
            pub fn poll(&mut self) -> RemoteSecretCreatePollResult {
                self.0.poll().into()
            }

            /// Binding version of [`create::RemoteSecretCreateTask::response`].
            pub fn response(&mut self, response: HttpsResult) -> Option<setup::RemoteSecretSetupError> {
                self.0.response(response.into()).err()
            }
        }
    }

    pub mod delete {
        //! Bindings for the remote secret deletion.
        use js_sys::Error;
        use serde::Serialize;
        use tsify::Tsify;
        use wasm_bindgen::prelude::wasm_bindgen;

        use crate::{
            bindings::wasm::https::{HttpsRequest, HttpsResult},
            remote_secret::setup::{self, delete},
        };

        /// Binding version of [`delete::RemoteSecretDeleteLoop`].
        #[derive(Tsify, Serialize)]
        #[serde(
            tag = "type",
            content = "value",
            rename_all = "kebab-case",
            rename_all_fields = "camelCase"
        )]
        #[tsify(into_wasm_abi)]
        pub enum RemoteSecretDeleteLoop {
            #[expect(missing_docs, reason = "Binding version")]
            Instruction(HttpsRequest),

            #[expect(missing_docs, reason = "Binding version")]
            Done,
        }
        impl From<delete::RemoteSecretDeleteLoop> for RemoteSecretDeleteLoop {
            fn from(delete_loop: delete::RemoteSecretDeleteLoop) -> Self {
                match delete_loop {
                    delete::RemoteSecretDeleteLoop::Instruction(setup::RemoteSecretSetupInstruction {
                        request,
                    }) => Self::Instruction(request.into()),

                    delete::RemoteSecretDeleteLoop::Done(()) => Self::Done,
                }
            }
        }

        /// Binding version of a [`RemoteSecretDeleteTask::poll`] result.
        #[derive(Tsify, Serialize)]
        #[serde(
            tag = "type",
            content = "value",
            rename_all = "kebab-case",
            rename_all_fields = "camelCase"
        )]
        #[tsify(into_wasm_abi)]
        pub enum RemoteSecretDeletePollResult {
            #[expect(missing_docs, reason = "Binding version")]
            DeleteLoop(RemoteSecretDeleteLoop),

            #[expect(missing_docs, reason = "Binding version")]
            Error(setup::RemoteSecretSetupError),
        }

        impl From<Result<delete::RemoteSecretDeleteLoop, setup::RemoteSecretSetupError>>
            for RemoteSecretDeletePollResult
        {
            fn from(result: Result<delete::RemoteSecretDeleteLoop, setup::RemoteSecretSetupError>) -> Self {
                match result {
                    Ok(delete_loop) => Self::DeleteLoop(delete_loop.into()),
                    Err(error) => Self::Error(error),
                }
            }
        }

        /// Binding version of [`delete::RemoteSecretDeleteTask`].
        #[wasm_bindgen]
        pub struct RemoteSecretDeleteTask(delete::RemoteSecretDeleteTask);

        #[wasm_bindgen]
        impl RemoteSecretDeleteTask {
            /// Binding version of [`delete::RemoteSecretDeleteTask::new`].
            ///
            /// # Errors
            ///
            /// Returns an error if `context` contains invalid parameters or if the
            /// `remote_secret_authentication_token` is not exactly 32 bytes.
            pub fn new(
                context: super::RemoteSecretSetupContext,
                remote_secret_authentication_token: &[u8],
            ) -> Result<Self, Error> {
                Ok(Self(delete::RemoteSecretDeleteTask::new(
                    context.try_into()?,
                    remote_secret_authentication_token
                        .try_into()
                        .map_err(|_| Error::new("'remote_secret_authentication_token' must be 32 bytes"))?,
                )))
            }

            /// Binding version of [`delete::RemoteSecretDeleteTask::poll`].
            pub fn poll(&mut self) -> RemoteSecretDeletePollResult {
                self.0.poll().into()
            }

            /// Binding version of [`delete::RemoteSecretDeleteTask::response`].
            pub fn response(&mut self, response: HttpsResult) -> Option<setup::RemoteSecretSetupError> {
                self.0.response(response.into()).err()
            }
        }
    }
}

pub mod monitor {
    //! Bindings for the remote secret monitoring.
    use js_sys::Error;
    use serde::Serialize;
    use serde_bytes::ByteBuf;
    use tsify::Tsify;
    use wasm_bindgen::prelude::wasm_bindgen;

    use crate::{
        bindings::wasm::https::{HttpsRequest, HttpsResult},
        common::ClientInfo,
        remote_secret::monitor,
    };

    /// Binding version of [`monitor::RemoteSecretMonitorInstruction`].
    #[derive(Tsify, Serialize)]
    #[serde(
        tag = "type",
        content = "value",
        rename_all = "kebab-case",
        rename_all_fields = "camelCase"
    )]
    #[tsify(into_wasm_abi)]
    pub enum RemoteSecretMonitorInstruction {
        #[expect(missing_docs, reason = "Binding version")]
        Request(HttpsRequest),

        #[expect(missing_docs, reason = "Binding version")]
        Schedule {
            timeout_ms: u32,
            remote_secret: Option<ByteBuf>,
        },
    }
    impl From<monitor::RemoteSecretMonitorInstruction> for RemoteSecretMonitorInstruction {
        fn from(instruction: monitor::RemoteSecretMonitorInstruction) -> Self {
            match instruction {
                monitor::RemoteSecretMonitorInstruction::Request(https_request) => {
                    Self::Request(https_request.into())
                },

                monitor::RemoteSecretMonitorInstruction::Schedule {
                    timeout,
                    remote_secret,
                } => Self::Schedule {
                    timeout_ms: timeout
                        .as_millis()
                        .try_into()
                        .expect("timeout should not exceed a u32"),
                    remote_secret: remote_secret.map(|remote_secret| ByteBuf::from(remote_secret.0)),
                },
            }
        }
    }

    /// Binding version of a [`RemoteSecretMonitorProtocol::poll`] result.
    #[derive(tsify::Tsify, Serialize)]
    #[serde(
        tag = "type",
        content = "result",
        rename_all = "kebab-case",
        rename_all_fields = "camelCase"
    )]
    #[tsify(into_wasm_abi)]
    pub enum RemoteSecretMonitorResult {
        #[expect(missing_docs, reason = "Binding version")]
        Instruction(RemoteSecretMonitorInstruction),

        #[expect(missing_docs, reason = "Binding version")]
        Error(monitor::RemoteSecretMonitorError),
    }
    impl From<Result<monitor::RemoteSecretMonitorInstruction, monitor::RemoteSecretMonitorError>>
        for RemoteSecretMonitorResult
    {
        fn from(
            result: Result<monitor::RemoteSecretMonitorInstruction, monitor::RemoteSecretMonitorError>,
        ) -> Self {
            match result {
                Ok(instruction) => Self::Instruction(instruction.into()),
                Err(error) => Self::Error(error),
            }
        }
    }

    /// Binding version of [`monitor::RemoteSecretMonitorProtocol`].
    #[wasm_bindgen]
    pub struct RemoteSecretMonitorProtocol(monitor::RemoteSecretMonitorProtocol);

    #[wasm_bindgen]
    impl RemoteSecretMonitorProtocol {
        /// Binding version of [`monitor::RemoteSecretMonitorProtocol::new`].
        ///
        /// # Errors
        ///
        /// Returns an error if
        ///
        /// - `work_server_base_url` is not a valid base URL (must end with a trailing slash)
        /// - `remote_secret_authentication_token` is not exactly 32 bytes
        /// - `remote_secret_hash` is not exactly 32 bytes
        pub fn new(
            client_info: ClientInfo,
            work_server_base_url: String,
            remote_secret_authentication_token: &[u8],
            remote_secret_hash: &[u8],
        ) -> Result<Self, Error> {
            let context = monitor::RemoteSecretMonitorContext {
                client_info,
                work_server_url: work_server_base_url
                    .try_into()
                    .map_err(|_| Error::new("'work_server_base_url' invalid"))?,
                remote_secret_authentication_token: remote_secret_authentication_token
                    .try_into()
                    .map_err(|_| Error::new("'remote_secret_authentication_token' must be 32 bytes"))?,
                remote_secret_verifier: monitor::RemoteSecretVerifier::RemoteSecretHash(
                    remote_secret_hash
                        .try_into()
                        .map_err(|_| Error::new("'remote_secret_hash' must be 32 bytes"))?,
                ),
            };

            Ok(Self(monitor::RemoteSecretMonitorProtocol::new(context)))
        }

        /// Binding version of [`monitor::RemoteSecretMonitorProtocol::poll`].
        pub fn poll(&mut self) -> RemoteSecretMonitorResult {
            self.0.poll().into()
        }

        /// Binding version of [`monitor::RemoteSecretMonitorProtocol::response`].
        pub fn response(&mut self, response: HttpsResult) -> Option<monitor::RemoteSecretMonitorError> {
            self.0.response(response.into()).err()
        }
    }
}

Messung
CHZG
8910010096

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.