//! 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()
}
}
}
¤ Dauer der Verarbeitung: 0.6 Sekunden
¤
*© Formatika GbR, Deutschland
|
|