Skip to content

Commit

Permalink
Provide the frontend translations via the /po.js path
Browse files Browse the repository at this point in the history
  • Loading branch information
lslezak committed Apr 3, 2024
1 parent 4be45d2 commit e9482ab
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
12 changes: 12 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/agama-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ utoipa = { version = "4.2.0", features = ["axum_extras"] }
config = "0.14.0"
rand = "0.8.5"
jsonwebtoken = "9.2.0"
axum-extra = { version = "0.9.2", features = ["typed-header"] }
axum-extra = { version = "0.9.2", features = ["cookie", "typed-header"] }
chrono = { version = "0.4.34", default-features = false, features = [
"now",
"std",
Expand Down
59 changes: 59 additions & 0 deletions rust/agama-server/src/web/service.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use super::http::{login, logout, session};
use super::{auth::TokenClaims, config::ServiceConfig, state::ServiceState, EventsSender};
use axum::{
body::Body,
extract::Request,
http::{header, HeaderMap, HeaderValue, StatusCode},
middleware,
response::IntoResponse,
routing::{get, post},
Router,
};
use axum_extra::extract::cookie::CookieJar;
use std::{
convert::Infallible,
path::{Path, PathBuf},
Expand Down Expand Up @@ -85,8 +88,64 @@ impl MainServiceBuilder {
.route("/auth", post(login).get(session).delete(logout));

let serve = ServeDir::new(self.public_dir);

// handle the /po.js request
// the requested language (locale) is sent in the "agamaLanguage" HTTP cookie
// this reimplements the Cockpit translation support
async fn po(jar: CookieJar) -> impl IntoResponse {
let mut response_headers = HeaderMap::new();

if let Some(cookie) = jar.get("agamaLanguage") {
let mut target_file = String::new();
let mut found = false;
// FIXME: this does not work, the public_dir setting is not accessible :-/
// when using something like PathBuf::from("/usr/share/cockpit/agama") here
// it works just fine....
let prefix = self.public_dir;

// try parsing the cookie
if let Some((lang, region)) = cookie.value().split_once('-') {
// first try the full locale
target_file = format!("po.{}_{}.js", lang, region.to_uppercase());
found = prefix.join(&target_file).exists();

if !found {
// then try the language only
target_file = format!("po.{}.js", lang);
found = prefix.join(&target_file).exists();
}
}

if !found {
// use the full cookie without parsing
target_file = format!("po.{}.js", cookie.value());
found = prefix.join(&target_file).exists();
}

if found {
// translation found, redirect to the real file
response_headers.insert(
header::LOCATION,
// if the file exists then the name is a valid header value and unwrapping is safe
HeaderValue::from_str(&target_file).unwrap()
);

return (StatusCode::TEMPORARY_REDIRECT, response_headers, Body::empty())
}
}

// fallback, return empty javascript translations if the language is not supported
response_headers.insert(
header::CONTENT_TYPE,
HeaderValue::from_static("text/javascript"),
);

(StatusCode::OK, response_headers, Body::empty())
}

Router::new()
.nest_service("/", serve)
.route("/po.js", get(po))
.nest("/api", api_router)
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new().br(true))
Expand Down

0 comments on commit e9482ab

Please sign in to comment.