diff --git a/src/internal/utils.gleam b/src/internal/utils.gleam index 3911153..0be6429 100644 --- a/src/internal/utils.gleam +++ b/src/internal/utils.gleam @@ -5,6 +5,7 @@ import gleam/bool import gleam/crypto import gleam/http/request import gleam/list +import gleam/order import gleam/result import gleam/string import wisp @@ -76,6 +77,14 @@ fn seconds_from_now(time: #(#(Int, Int, Int), #(Int, Int, Int))) { /// Get session Id from cookie pub fn get_session_id(cookie_name: String, req: wisp.Request) { wisp.get_cookie(req, cookie_name, wisp.Signed) - |> result.replace_error(session.NoSessionCookieError) + |> result.replace_error(session.NoSessionError) |> result.map(session.id_from_string) } + +pub fn is_session_expired(session: session.Session) { + let expiry = birl.from_erlang_universal_datetime(session.expires_at) + case birl.compare(birl.now(), expiry) { + order.Gt -> True + _ -> False + } +} diff --git a/src/wisp_kv_sessions.gleam b/src/wisp_kv_sessions.gleam index e0ed2e3..750071a 100644 --- a/src/wisp_kv_sessions.gleam +++ b/src/wisp_kv_sessions.gleam @@ -17,7 +17,12 @@ pub fn get_session(config: session_config.Config, req: wisp.Request) { use session_id <- result.try(utils.get_session_id(config.cookie_name, req)) use maybe_session <- result.try(config.store.get_session(session_id)) case maybe_session { - option.Some(session) -> Ok(session) + option.Some(session) -> { + case utils.is_session_expired(session) { + True -> Error(session.SessionExpiredError) + False -> Ok(session) + } + } option.None -> session.builder() |> session.with_id(session_id) diff --git a/src/wisp_kv_sessions/session.gleam b/src/wisp_kv_sessions/session.gleam index 0cbc225..6c1e3d1 100644 --- a/src/wisp_kv_sessions/session.gleam +++ b/src/wisp_kv_sessions/session.gleam @@ -14,7 +14,8 @@ pub type SessionError { DbErrorGetError(String) DbErrorDeleteError(String) DeserializeError(String) - NoSessionCookieError + SessionExpiredError + NoSessionError } // Session id diff --git a/test/wisp_kv_sessions_test.gleam b/test/wisp_kv_sessions_test.gleam index e35d937..fe4929e 100644 --- a/test/wisp_kv_sessions_test.gleam +++ b/test/wisp_kv_sessions_test.gleam @@ -34,7 +34,7 @@ pub fn return_an_error_if_no_session_cookie_exist_test() { test_obj_to_json, ) |> should.be_error - |> should.equal(session.NoSessionCookieError) + |> should.equal(session.NoSessionError) } pub fn set_a_value_in_the_session_test() { @@ -148,6 +148,7 @@ pub fn creating_a_session_test() { cookie_name: "SESSION_COOKIE", store: memory_store, ) + let req = testing.get("/", []) |> testing.set_cookie("SESSION_COOKIE", "TEST_SESSION_ID", wisp.Signed) @@ -193,6 +194,30 @@ pub fn replace_session_test() { |> should.be_none } +pub fn dont_get_expired_session_test() { + use #(session_config, memory_store, _) <- result.map(test_session_config()) + + let assert Ok(past_date) = birl.parse("1905-12-22 16:38:23-3") + + let expired_session = + session.builder() + |> session.with_expires_at(past_date) + |> session.build + + let assert Ok(_) = memory_store.save_session(expired_session) + + let req = + testing.get("/", []) + |> testing.set_cookie( + "SESSION_COOKIE", + session.id_to_string(expired_session.id), + wisp.Signed, + ) + + sessions.get_session(session_config, req) + |> should.be_error +} + pub fn inject_a_cookie_in_a_request_test() { use #(session_config, _, _) <- result.map(test_session_config())