aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/access/token.rs10
-rw-r--r--src/api/login.rs6
2 files changed, 14 insertions, 2 deletions
diff --git a/src/access/token.rs b/src/access/token.rs
index ae1546c..a9fc270 100644
--- a/src/access/token.rs
+++ b/src/access/token.rs
@@ -46,8 +46,15 @@ pub(crate) struct Claims {
pub(crate) exp: u64,
/// The login it comes from, kept by refreshed tokens (16 hex digits).
pub(crate) session: String,
- /// Until when it may be refreshed (Unix ms): the login's end.
+ /// Until when it may be refreshed (Unix ms): the login's end, or sooner for one that
+ /// was given a lifetime of its own (it ends its session with it).
pub(crate) session_exp: u64,
+ /// The login's end (Unix ms), as it logged in: what no refresh changes, a token cut
+ /// short included. An ended session is recorded until then (`registry::session_path`),
+ /// so it covers every token of the session, wherever it ends. 0 in a token from
+ /// before it was kept: `session_exp` then.
+ #[serde(default)]
+ pub(crate) login_exp: u64,
/// Less than the user may do: only what these allow too.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub(crate) limit: Option<Vec<Capability>>,
@@ -206,6 +213,7 @@ mod tests {
exp: 2_000,
session: new_session(),
session_exp: 10_000,
+ login_exp: 10_000,
limit: None,
}
}
diff --git a/src/api/login.rs b/src/api/login.rs
index 57c1859..dc9d895 100644
--- a/src/api/login.rs
+++ b/src/api/login.rs
@@ -272,6 +272,7 @@ fn new_login(
exp,
session: token::new_session(),
session_exp: ended_with(session_exp, exp, lifetime),
+ login_exp: session_exp,
limit,
}
}
@@ -532,7 +533,10 @@ pub(crate) async fn end_session(
/// registry, else on this node only.
async fn end(state: &AppState, claims: &Claims, by: &str) -> Result<(), ApiError> {
let path = registry::session_path(&claims.user, &claims.session);
- let until = claims.session_exp;
+ // The login's end, not this token's refresh deadline (a token handed to another
+ // member's dashboard ends its session in minutes): every token of the session is
+ // refused until it.
+ let until = claims.login_exp.max(claims.session_exp);
let recorded = if state.is_ready().await {
state
.mutate_doc_for(Some(by.to_owned()), Sign::Protocol, move |doc| {