Remove path repetition
This commit is contained in:
parent
2536f09cd7
commit
2a7a19fdf0
10 changed files with 65 additions and 149 deletions
|
|
@ -11,3 +11,19 @@ pub mod put_file_manifest;
|
||||||
mod utils;
|
mod utils;
|
||||||
pub mod vault_snapshot;
|
pub mod vault_snapshot;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
|
use crate::{app_state::database::models::VaultId, utils::normalize_vault_id::normalize_vault_id};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct VaultPath(pub VaultId);
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for VaultPath {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
normalize_vault_id(deserializer).map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,12 @@ use axum::{
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use super::VaultPath;
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{AppState, database::models::EventBatch},
|
||||||
AppState,
|
|
||||||
database::models::{EventBatch, VaultId},
|
|
||||||
},
|
|
||||||
errors::{SyncServerError, client_error, server_error},
|
errors::{SyncServerError, client_error, server_error},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct EventsPath {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EventsQuery {
|
pub struct EventsQuery {
|
||||||
pub after: i64,
|
pub after: i64,
|
||||||
|
|
@ -27,13 +18,13 @@ pub struct EventsQuery {
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn events(
|
pub async fn events(
|
||||||
Path(path): Path<EventsPath>,
|
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||||
Query(query): Query<EventsQuery>,
|
Query(query): Query<EventsQuery>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Json<EventBatch>, SyncServerError> {
|
) -> Result<Json<EventBatch>, SyncServerError> {
|
||||||
debug!(
|
debug!(
|
||||||
"Fetching events after `{}` for vault `{}`",
|
"Fetching events after `{}` for vault `{}`",
|
||||||
query.after, path.vault_id
|
query.after, vault_id
|
||||||
);
|
);
|
||||||
|
|
||||||
if query.after < 0 {
|
if query.after < 0 {
|
||||||
|
|
@ -42,7 +33,7 @@ pub async fn events(
|
||||||
|
|
||||||
state
|
state
|
||||||
.database
|
.database
|
||||||
.events_after(&path.vault_id, query.after)
|
.events_after(&vault_id, query.after)
|
||||||
.await
|
.await
|
||||||
.map(Json)
|
.map(Json)
|
||||||
.map_err(server_error)
|
.map_err(server_error)
|
||||||
|
|
|
||||||
|
|
@ -4,33 +4,23 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
|
use super::VaultPath;
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{
|
||||||
AppState,
|
AppState,
|
||||||
database::models::{DocumentId, VaultId, VaultUpdateId},
|
database::models::{DocumentId, VaultUpdateId},
|
||||||
},
|
},
|
||||||
errors::{SyncServerError, not_found_error, server_error},
|
errors::{SyncServerError, not_found_error, server_error},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct FetchDocumentVersionContentPathParams {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
|
|
||||||
document_id: DocumentId,
|
|
||||||
vault_update_id: VaultUpdateId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn fetch_document_version_content(
|
pub async fn fetch_document_version_content(
|
||||||
Path(FetchDocumentVersionContentPathParams {
|
Path((VaultPath(vault_id), document_id, vault_update_id)): Path<(
|
||||||
vault_id,
|
VaultPath,
|
||||||
document_id,
|
DocumentId,
|
||||||
vault_update_id,
|
VaultUpdateId,
|
||||||
}): Path<FetchDocumentVersionContentPathParams>,
|
)>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Bytes, SyncServerError> {
|
) -> Result<Bytes, SyncServerError> {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
||||||
|
|
@ -4,31 +4,19 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
|
use super::VaultPath;
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{
|
||||||
AppState,
|
AppState,
|
||||||
database::models::{DocumentId, DocumentVersion, VaultId},
|
database::models::{DocumentId, DocumentVersion},
|
||||||
},
|
},
|
||||||
errors::{SyncServerError, not_found_error, server_error},
|
errors::{SyncServerError, not_found_error, server_error},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct FetchLatestDocumentVersionPathParams {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
|
|
||||||
document_id: DocumentId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn fetch_latest_document_version(
|
pub async fn fetch_latest_document_version(
|
||||||
Path(FetchLatestDocumentVersionPathParams {
|
Path((VaultPath(vault_id), document_id)): Path<(VaultPath, DocumentId)>,
|
||||||
vault_id,
|
|
||||||
document_id,
|
|
||||||
}): Path<FetchLatestDocumentVersionPathParams>,
|
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Json<DocumentVersion>, SyncServerError> {
|
) -> Result<Json<DocumentVersion>, SyncServerError> {
|
||||||
debug!("Fetching latest document version for document `{document_id}` in vault `{vault_id}`");
|
debug!("Fetching latest document version for document `{document_id}` in vault `{vault_id}`");
|
||||||
|
|
|
||||||
|
|
@ -3,36 +3,26 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
|
use super::VaultPath;
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{
|
||||||
AppState,
|
AppState,
|
||||||
database::{
|
database::{Database, models::FileManifest},
|
||||||
Database,
|
|
||||||
models::{FileManifest, VaultId},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
errors::{SyncServerError, server_error},
|
errors::{SyncServerError, server_error},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct GetFileManifestPath {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn get_file_manifest(
|
pub async fn get_file_manifest(
|
||||||
Path(path): Path<GetFileManifestPath>,
|
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Json<FileManifest>, SyncServerError> {
|
) -> Result<Json<FileManifest>, SyncServerError> {
|
||||||
debug!("Fetching file manifest for vault `{}`", path.vault_id);
|
debug!("Fetching file manifest for vault `{vault_id}`");
|
||||||
|
|
||||||
let mut transaction = state
|
let mut transaction = state
|
||||||
.database
|
.database
|
||||||
.create_readonly_transaction(&path.vault_id)
|
.create_readonly_transaction(&vault_id)
|
||||||
.await
|
.await
|
||||||
.map_err(server_error)?;
|
.map_err(server_error)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,15 @@ use axum_extra::{
|
||||||
headers::{Authorization, authorization::Bearer},
|
headers::{Authorization, authorization::Bearer},
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
|
use super::VaultPath;
|
||||||
use crate::server::{auth::auth, responses::PingResponse};
|
use crate::server::{auth::auth, responses::PingResponse};
|
||||||
use crate::{
|
use crate::{app_state::AppState, consts::SUPPORTED_API_VERSION, errors::SyncServerError};
|
||||||
app_state::{AppState, database::models::VaultId},
|
|
||||||
consts::SUPPORTED_API_VERSION,
|
|
||||||
errors::SyncServerError,
|
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct PingPathParams {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn ping(
|
pub async fn ping(
|
||||||
maybe_auth_header: Option<TypedHeader<Authorization<Bearer>>>,
|
maybe_auth_header: Option<TypedHeader<Authorization<Bearer>>>,
|
||||||
Path(PingPathParams { vault_id }): Path<PingPathParams>,
|
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Json<PingResponse>, SyncServerError> {
|
) -> Result<Json<PingResponse>, SyncServerError> {
|
||||||
debug!("Pinging vault `{vault_id}`");
|
debug!("Pinging vault `{vault_id}`");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::utils::find_already_processed_event;
|
use super::{VaultPath, utils::find_already_processed_event};
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{
|
||||||
AppState,
|
AppState,
|
||||||
|
|
@ -14,7 +14,6 @@ use crate::{
|
||||||
requests::{PushContent, PutFileContent},
|
requests::{PushContent, PutFileContent},
|
||||||
responses::DocumentUpdateResponse,
|
responses::DocumentUpdateResponse,
|
||||||
},
|
},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use axum::{
|
use axum::{
|
||||||
|
|
@ -25,37 +24,26 @@ use axum_extra::TypedHeader;
|
||||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use reconcile_text::{BuiltinTokenizer, EditedText, NumberOrText};
|
use reconcile_text::{BuiltinTokenizer, EditedText, NumberOrText};
|
||||||
use serde::Deserialize;
|
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct PutFileContentPath {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
document_id: DocumentId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn put_file_content(
|
pub async fn put_file_content(
|
||||||
Path(path): Path<PutFileContentPath>,
|
Path((VaultPath(vault_id), document_id)): Path<(VaultPath, DocumentId)>,
|
||||||
Extension(user): Extension<User>,
|
Extension(user): Extension<User>,
|
||||||
TypedHeader(device): TypedHeader<DeviceIdHeader>,
|
TypedHeader(device): TypedHeader<DeviceIdHeader>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Json(push): Json<PutFileContent>,
|
Json(push): Json<PutFileContent>,
|
||||||
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
|
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
|
||||||
debug!(
|
debug!("Pushing document `{}` in vault `{}`", document_id, vault_id);
|
||||||
"Pushing document `{}` in vault `{}`",
|
|
||||||
path.document_id, path.vault_id
|
|
||||||
);
|
|
||||||
|
|
||||||
let fingerprint = Sha256::digest(
|
let fingerprint = Sha256::digest(
|
||||||
serde_json::to_vec(&("content", path.document_id, &push))
|
serde_json::to_vec(&("content", document_id, &push))
|
||||||
.map_err(|error| server_error(error.into()))?,
|
.map_err(|error| server_error(error.into()))?,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tx = state
|
let mut tx = state
|
||||||
.database
|
.database
|
||||||
.create_write_transaction(&path.vault_id)
|
.create_write_transaction(&vault_id)
|
||||||
.await
|
.await
|
||||||
.map_err(server_error)?;
|
.map_err(server_error)?;
|
||||||
|
|
||||||
|
|
@ -74,7 +62,7 @@ pub async fn put_file_content(
|
||||||
|
|
||||||
let parent = state
|
let parent = state
|
||||||
.database
|
.database
|
||||||
.get_latest_document_version(&path.vault_id, &path.document_id, Some(&mut tx))
|
.get_latest_document_version(&vault_id, &document_id, Some(&mut tx))
|
||||||
.await
|
.await
|
||||||
.map_err(server_error)?;
|
.map_err(server_error)?;
|
||||||
|
|
||||||
|
|
@ -87,7 +75,7 @@ pub async fn put_file_content(
|
||||||
} else if push.parent_version_id.is_some() {
|
} else if push.parent_version_id.is_some() {
|
||||||
return Err(not_found_error(anyhow!(
|
return Err(not_found_error(anyhow!(
|
||||||
"Document {} does not exist",
|
"Document {} does not exist",
|
||||||
path.document_id
|
document_id
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,7 +111,7 @@ pub async fn put_file_content(
|
||||||
vault_update_id: Database::allocate_event(&mut tx, push.request_id, &fingerprint)
|
vault_update_id: Database::allocate_event(&mut tx, push.request_id, &fingerprint)
|
||||||
.await
|
.await
|
||||||
.map_err(server_error)?,
|
.map_err(server_error)?,
|
||||||
document_id: path.document_id,
|
document_id,
|
||||||
content,
|
content,
|
||||||
updated_date: chrono::Utc::now(),
|
updated_date: chrono::Utc::now(),
|
||||||
user_id: user.name,
|
user_id: user.name,
|
||||||
|
|
@ -152,10 +140,7 @@ pub async fn put_file_content(
|
||||||
.await
|
.await
|
||||||
.map_err(|error| server_error(error.into()))?;
|
.map_err(|error| server_error(error.into()))?;
|
||||||
|
|
||||||
state
|
state.broadcasts.notify_about_vault_update(vault_id).await;
|
||||||
.broadcasts
|
|
||||||
.notify_about_vault_update(path.vault_id)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(Json(response))
|
Ok(Json(response))
|
||||||
}
|
}
|
||||||
|
|
@ -185,10 +170,7 @@ mod tests {
|
||||||
push: PutFileContent,
|
push: PutFileContent,
|
||||||
) -> Result<DocumentUpdateResponse, SyncServerError> {
|
) -> Result<DocumentUpdateResponse, SyncServerError> {
|
||||||
put_file_content(
|
put_file_content(
|
||||||
Path(PutFileContentPath {
|
Path((VaultPath(vault.clone()), document_id)),
|
||||||
vault_id: vault.clone(),
|
|
||||||
document_id,
|
|
||||||
}),
|
|
||||||
Extension(User {
|
Extension(User {
|
||||||
name: user_id,
|
name: user_id,
|
||||||
token: String::new(),
|
token: String::new(),
|
||||||
|
|
|
||||||
|
|
@ -4,36 +4,28 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use super::utils::find_already_processed_event;
|
use super::{VaultPath, utils::find_already_processed_event};
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{
|
||||||
AppState,
|
AppState,
|
||||||
database::{
|
database::{
|
||||||
Database,
|
Database,
|
||||||
models::{EventRecord, FileManifest, VaultEvent, VaultId},
|
models::{EventRecord, FileManifest, VaultEvent},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors::{SyncServerError, client_error, server_error},
|
errors::{SyncServerError, client_error, server_error},
|
||||||
server::{requests::PushFileManifest, responses::FileManifestUpdateResponse},
|
server::{requests::PushFileManifest, responses::FileManifestUpdateResponse},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct PutFileManifestPath {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn put_file_manifest(
|
pub async fn put_file_manifest(
|
||||||
Path(path): Path<PutFileManifestPath>,
|
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Json(push): Json<PushFileManifest>,
|
Json(push): Json<PushFileManifest>,
|
||||||
) -> Result<Json<FileManifestUpdateResponse>, SyncServerError> {
|
) -> Result<Json<FileManifestUpdateResponse>, SyncServerError> {
|
||||||
debug!("Pushing file manifest for vault `{}`", path.vault_id);
|
debug!("Pushing file manifest for vault `{vault_id}`");
|
||||||
|
|
||||||
// BTreeMap canonicalizes file manifest entries for request fingerprinting.
|
// BTreeMap canonicalizes file manifest entries for request fingerprinting.
|
||||||
let fingerprint = Sha256::digest(
|
let fingerprint = Sha256::digest(
|
||||||
|
|
@ -43,7 +35,7 @@ pub async fn put_file_manifest(
|
||||||
|
|
||||||
let mut tx = state
|
let mut tx = state
|
||||||
.database
|
.database
|
||||||
.create_write_transaction(&path.vault_id)
|
.create_write_transaction(&vault_id)
|
||||||
.await
|
.await
|
||||||
.map_err(server_error)?;
|
.map_err(server_error)?;
|
||||||
|
|
||||||
|
|
@ -73,7 +65,7 @@ pub async fn put_file_manifest(
|
||||||
for id in push.entries.keys() {
|
for id in push.entries.keys() {
|
||||||
if state
|
if state
|
||||||
.database
|
.database
|
||||||
.get_latest_document_version(&path.vault_id, id, Some(&mut tx))
|
.get_latest_document_version(&vault_id, id, Some(&mut tx))
|
||||||
.await
|
.await
|
||||||
.map_err(server_error)?
|
.map_err(server_error)?
|
||||||
.is_none()
|
.is_none()
|
||||||
|
|
@ -113,10 +105,7 @@ pub async fn put_file_manifest(
|
||||||
.await
|
.await
|
||||||
.map_err(|error| server_error(error.into()))?;
|
.map_err(|error| server_error(error.into()))?;
|
||||||
|
|
||||||
state
|
state.broadcasts.notify_about_vault_update(vault_id).await;
|
||||||
.broadcasts
|
|
||||||
.notify_about_vault_update(path.vault_id)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(Json(response))
|
Ok(Json(response))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,33 +3,23 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
|
use super::VaultPath;
|
||||||
use crate::{
|
use crate::{
|
||||||
app_state::{
|
app_state::{AppState, database::models::VaultSnapshot},
|
||||||
AppState,
|
|
||||||
database::models::{VaultId, VaultSnapshot},
|
|
||||||
},
|
|
||||||
errors::{SyncServerError, server_error},
|
errors::{SyncServerError, server_error},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct VaultSnapshotPath {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn vault_snapshot(
|
pub async fn vault_snapshot(
|
||||||
Path(path): Path<VaultSnapshotPath>,
|
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Json<VaultSnapshot>, SyncServerError> {
|
) -> Result<Json<VaultSnapshot>, SyncServerError> {
|
||||||
debug!("Fetching vault snapshot for vault `{}`", path.vault_id);
|
debug!("Fetching vault snapshot for vault `{vault_id}`");
|
||||||
|
|
||||||
state
|
state
|
||||||
.database
|
.database
|
||||||
.vault_snapshot(&path.vault_id)
|
.vault_snapshot(&vault_id)
|
||||||
.await
|
.await
|
||||||
.map(Json)
|
.map(Json)
|
||||||
.map_err(server_error)
|
.map_err(server_error)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ use crate::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors::{SyncServerError, client_error, server_error},
|
errors::{SyncServerError, client_error, server_error},
|
||||||
utils::normalize_vault_id::normalize_vault_id,
|
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{
|
extract::{
|
||||||
|
|
@ -20,29 +19,21 @@ use axum::{
|
||||||
};
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use serde::Deserialize;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::sync::broadcast::error::RecvError;
|
use tokio::sync::broadcast::error::RecvError;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
use super::VaultPath;
|
||||||
pub struct WebSocketPathParams {
|
|
||||||
#[serde(deserialize_with = "normalize_vault_id")]
|
|
||||||
vault_id: VaultId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum::debug_handler]
|
#[axum::debug_handler]
|
||||||
pub async fn websocket_handler(
|
pub async fn websocket_handler(
|
||||||
ws: WebSocketUpgrade,
|
ws: WebSocketUpgrade,
|
||||||
Path(path): Path<WebSocketPathParams>,
|
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<Response, SyncServerError> {
|
) -> Result<Response, SyncServerError> {
|
||||||
debug!(
|
debug!("Upgrading WebSocket connection for vault `{vault_id}`");
|
||||||
"Upgrading WebSocket connection for vault `{}`",
|
|
||||||
path.vault_id
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(ws.on_upgrade(move |socket| async move {
|
Ok(ws.on_upgrade(move |socket| async move {
|
||||||
if let Err(error) = websocket(state, socket, path.vault_id).await {
|
if let Err(error) = websocket(state, socket, vault_id).await {
|
||||||
debug!("WebSocket disconnected: {error}");
|
debug!("WebSocket disconnected: {error}");
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue