aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/routes/ui')
-rw-r--r--server/src/routes/ui/account/mod.rs11
-rw-r--r--server/src/routes/ui/account/session.rs32
-rw-r--r--server/src/routes/ui/error.rs5
-rw-r--r--server/src/routes/ui/home.rs2
-rw-r--r--server/src/routes/ui/player.rs6
5 files changed, 47 insertions, 9 deletions
diff --git a/server/src/routes/ui/account/mod.rs b/server/src/routes/ui/account/mod.rs
index e7031ff..63c01c5 100644
--- a/server/src/routes/ui/account/mod.rs
+++ b/server/src/routes/ui/account/mod.rs
@@ -6,6 +6,8 @@
pub mod admin;
pub mod session;
+use self::session::SessionCookie;
+
use super::{error::MyError, layout::LayoutPage};
use crate::{
database::{Database, User},
@@ -157,7 +159,14 @@ pub fn r_account_login_post(
Err(anyhow!("invalid password"))?
}
- jar.add_private(Cookie::build("user", user.name).permanent().finish());
+ jar.add_private(
+ Cookie::build(
+ "user",
+ serde_json::to_string(&SessionCookie::new(user.name)).unwrap(),
+ )
+ .permanent()
+ .finish(),
+ );
Ok(Redirect::found(uri!(r_home())))
}
diff --git a/server/src/routes/ui/account/session.rs b/server/src/routes/ui/account/session.rs
index 6059311..6795c06 100644
--- a/server/src/routes/ui/account/session.rs
+++ b/server/src/routes/ui/account/session.rs
@@ -5,19 +5,36 @@
*/
use crate::{
database::{Database, User},
- routes::ui::error::MyError,
+ routes::ui::error::MyError, CONF,
};
use anyhow::anyhow;
+use chrono::{DateTime, Duration, Utc};
use rocket::{
outcome::Outcome,
request::{self, FromRequest},
Request, State,
};
+use serde::{Deserialize, Serialize};
pub struct Session {
pub user: User,
}
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct SessionCookie {
+ name: String,
+ expire: DateTime<Utc>,
+}
+
+impl SessionCookie {
+ pub fn new(name: String) -> Self {
+ Self {
+ name,
+ expire: Utc::now() + Duration::days(CONF.login_expire),
+ }
+ }
+}
+
impl Session {
pub async fn from_request_ut(req: &Request<'_>) -> Result<Self, MyError> {
#[cfg(not(feature = "bypass-auth"))]
@@ -26,14 +43,21 @@ impl Session {
.get_private("user")
.ok_or(anyhow!("login required"))?;
#[cfg(not(feature = "bypass-auth"))]
- let username = cookie.value();
+ let cookie = serde_json::from_str::<SessionCookie>(cookie.value())?;
#[cfg(feature = "bypass-auth")]
- let username = crate::CONF.admin_username.to_string();
+ let cookie = SessionCookie {
+ name: crate::CONF.admin_username.to_string(),
+ expire: Utc::now() + Duration::days(CONF.login_expire),
+ };
+
+ if cookie.expire < Utc::now() {
+ Err(anyhow!("cookie expired"))?;
+ }
let db = req.guard::<&State<Database>>().await.unwrap();
let user = db
.users
- .get(&username.to_string())?
+ .get(&cookie.name.to_string())?
.ok_or(anyhow!("user not found"))?;
Ok(Session { user })
diff --git a/server/src/routes/ui/error.rs b/server/src/routes/ui/error.rs
index 59e322a..7913e1a 100644
--- a/server/src/routes/ui/error.rs
+++ b/server/src/routes/ui/error.rs
@@ -70,3 +70,8 @@ impl From<sled::Error> for MyError {
MyError(anyhow::anyhow!("{err}"))
}
}
+impl From<serde_json::Error> for MyError {
+ fn from(err: serde_json::Error) -> Self {
+ MyError(anyhow::anyhow!("{err}"))
+ }
+}
diff --git a/server/src/routes/ui/home.rs b/server/src/routes/ui/home.rs
index a8d9c65..f81e04f 100644
--- a/server/src/routes/ui/home.rs
+++ b/server/src/routes/ui/home.rs
@@ -25,7 +25,7 @@ pub fn r_home(_sess: Session, library: &State<Library>) -> DynLayoutPage {
#[get("/", rank = 2)]
pub async fn r_home_unpriv() -> MyResult<DynLayoutPage<'static>> {
- let front = read_to_string(CONF.asset_dir.join("front.htm")).await?;
+ let front = read_to_string(CONF.asset_path.join("front.htm")).await?;
Ok(LayoutPage {
title: "Home".to_string(),
content: markup::new! {
diff --git a/server/src/routes/ui/player.rs b/server/src/routes/ui/player.rs
index 866787a..20b451f 100644
--- a/server/src/routes/ui/player.rs
+++ b/server/src/routes/ui/player.rs
@@ -95,11 +95,11 @@ pub fn player_conf<'a>(item: Arc<Item>) -> MyResult<DynLayoutPage<'a>> {
fieldset.subtitles {
legend { "Subtitles" }
- @for (i, (tid, track)) in sub_tracks.iter().enumerate() {
- input[type="radio", id=tid, name="s", value=tid, checked=i==0];
+ @for (_i, (tid, track)) in sub_tracks.iter().enumerate() {
+ input[type="radio", id=tid, name="s", value=tid];
label[for=tid] { @format!("{track}") } br;
}
- input[type="radio", id="s-none", name="s", value=""];
+ input[type="radio", id="s-none", name="s", value="", checked=true];
label[for="s-none"] { "No subtitles" }
}