diff options
| author | Ellie Huxtable <ellie@elliehuxtable.com> | 2023-12-20 09:03:04 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-20 09:03:04 +0000 |
| commit | 86f50e0356e4b661be43c2aeba97a67d83910095 (patch) | |
| tree | 3c836616132ab23e60231af21b668d639dbabe97 /atuin-server | |
| parent | chore(deps): bump lukemathwalker/cargo-chef (#1425) (diff) | |
| download | atuin-86f50e0356e4b661be43c2aeba97a67d83910095.zip | |
feat: add semver checking to client requests (#1456)
* feat: add semver checking to client requests
This enforces that the client and the server run the same major version
in order to sync successfully.
We're using the `Atuin-Version` http header to transfer this information
If the user is not on the same MAJOR, then they will see an error like
this
> Atuin version mismatch! In order to successfully sync, the client and the server must run the same *major* version
> Client: 17.1.0
> Server: 18.1.0
> Error: could not sync records due to version mismatch
This change means two things
1. We will now only increment major versions if there is a breaking
change for sync
2. We can now add breaking changes to sync, for any version >17.1.0.
Clients will fail in a meaningful way.
* lint, fmt, etc
* only check for client newer than server
* Add version header to client too
Diffstat (limited to 'atuin-server')
| -rw-r--r-- | atuin-server/src/router.rs | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/atuin-server/src/router.rs b/atuin-server/src/router.rs index 90e726d3..581886de 100644 --- a/atuin-server/src/router.rs +++ b/atuin-server/src/router.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use atuin_common::api::ErrorResponse; +use atuin_common::api::{ErrorResponse, ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION}; use axum::{ extract::FromRequestParts, http::Request, @@ -91,6 +91,16 @@ async fn clacks_overhead<B>(request: Request<B>, next: Next<B>) -> Response { response } +/// Ensure that we only try and sync with clients on the same major version +async fn semver<B>(request: Request<B>, next: Next<B>) -> Response { + let mut response = next.run(request).await; + response + .headers_mut() + .insert(ATUIN_HEADER_VERSION, ATUIN_CARGO_VERSION.parse().unwrap()); + + response +} + #[derive(Clone)] pub struct AppState<DB: Database> { pub database: DB, @@ -126,6 +136,7 @@ pub fn router<DB: Database>(database: DB, settings: Settings<DB::Settings>) -> R ServiceBuilder::new() .layer(axum::middleware::from_fn(clacks_overhead)) .layer(TraceLayer::new_for_http()) - .layer(axum::middleware::from_fn(metrics::track_metrics)), + .layer(axum::middleware::from_fn(metrics::track_metrics)) + .layer(axum::middleware::from_fn(semver)), ) } |
