diff --git a/crow_test/data/session/.expirations b/crow_test/data/session/.expirations
new file mode 100644
index 0000000..55171af
--- /dev/null
+++ b/crow_test/data/session/.expirations
@@ -0,0 +1 @@
+jlbpNSZuchBeVInZ 1692336738
diff --git a/crow_test/data/session/jlbpNSZuchBeVInZ.json b/crow_test/data/session/jlbpNSZuchBeVInZ.json
new file mode 100644
index 0000000..9650cf7
--- /dev/null
+++ b/crow_test/data/session/jlbpNSZuchBeVInZ.json
@@ -0,0 +1 @@
+{"clientID":"2e68464b-a37c-58a2-a970-97fedf56e8f9","clientToken":"00000000-0000-0000-0000-000000000000"}
\ No newline at end of file
diff --git a/crow_test/webcontent/login.html b/crow_test/webcontent/login.html
index 1154fbf..7aaedc3 100644
--- a/crow_test/webcontent/login.html
+++ b/crow_test/webcontent/login.html
@@ -17,7 +17,9 @@
-
+
+
+
diff --git a/include/crowsite/site/auth.h b/include/crowsite/site/auth.h
index e6801a0..4e45b5e 100644
--- a/include/crowsite/site/auth.h
+++ b/include/crowsite/site/auth.h
@@ -6,10 +6,16 @@
#define CROWSITE_AUTH_H
#include "crowsite/utility.h"
+#include
namespace cs {
+
+ struct cookie_data {
+ std::string clientID;
+ std::string clientToken;
+ };
- bool handleLoginPost(cs::parser::Post& postData);
+ bool handleLoginPost(cs::parser::Post& postData, cookie_data& cookieOut);
}
diff --git a/src/crowsite/site/auth.cpp b/src/crowsite/site/auth.cpp
index 838b412..d55d8b0 100644
--- a/src/crowsite/site/auth.cpp
+++ b/src/crowsite/site/auth.cpp
@@ -4,10 +4,13 @@
#include
#include
#include "blt/std/logging.h"
+#include "blt/std/uuid.h"
+
+using namespace blt;
namespace cs {
- bool handleLoginPost(parser::Post& postData)
+ bool handleLoginPost(parser::Post& postData, cookie_data& cookieOut)
{
// javascript should make sure we don't send post requests without information
// this way it can be interactive
@@ -15,6 +18,9 @@ namespace cs {
return false;
auto auth = jellyfin::authenticateUser(postData["username"], postData["password"]);
+ cookieOut.clientID = uuid::toString(uuid::genV5("ClientID?"));
+ cookieOut.clientToken = uuid::toString(uuid::genV4());
+
return auth == jellyfin::auth_response::AUTHORIZED;
}
}
\ No newline at end of file
diff --git a/src/crowsite/utility.cpp b/src/crowsite/utility.cpp
index 3a23707..6446123 100644
--- a/src/crowsite/utility.cpp
+++ b/src/crowsite/utility.cpp
@@ -17,6 +17,8 @@ namespace cs {
auto stripped_key = curl_easy_unescape(nullptr, key.c_str(), 0, nullptr);
auto stripped_value = curl_easy_unescape(nullptr, value.c_str(), 0, nullptr);
m_Values[stripped_key] = stripped_value;
+ curl_free(stripped_key);
+ curl_free(stripped_value);
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 311a5dc..293ec4a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -11,6 +11,8 @@
#include
#include
#include
+#include
+#include
class BLT_CrowLogger : public crow::ILogHandler
{
@@ -40,6 +42,11 @@ class BLT_CrowLogger : public crow::ILogHandler
}
};
+inline crow::response redirect(const std::string& loc){
+ crow::response res;
+ res.redirect(loc);
+ return res;
+}
int main(int argc, const char** argv)
{
@@ -57,16 +64,24 @@ int main(int argc, const char** argv)
cs::jellyfin::setToken(blt::arg_parse::get(args["token"]));
cs::jellyfin::processUserData();
- auto res = cs::jellyfin::authenticateUser(blt::arg_parse::get(args["user"]), blt::arg_parse::get(args["pass"]));
- BLT_INFO("Has true: %b", res == cs::jellyfin::auth_response::AUTHORIZED);
-
BLT_INFO("Starting site %s.", SITE_NAME);
crow::mustache::set_global_base(SITE_FILES_PATH);
static BLT_CrowLogger bltCrowLogger{};
crow::logger::setHandler(&bltCrowLogger);
+ using Session = crow::SessionMiddleware;
+
+ const auto session_age = 24 * 60 * 60;
+ const auto cookie_age = 180 * 24 * 60 * 60;
+
BLT_INFO("Init Crow with compression and logging enabled!");
- crow::SimpleApp app;
+ crow::App app {Session{
+ // customize cookies
+ crow::CookieParser::Cookie("session").max_age(session_age).path("/"),
+ // set session id length (small value only for demonstration purposes)
+ 16,
+ // init the store
+ crow::FileStore{std::string(SITE_FILES_PATH) + "/data/session", session_age}}};
app.use_compression(crow::compression::GZIP);
app.loglevel(crow::LogLevel::WARNING);
@@ -126,15 +141,30 @@ int main(int argc, const char** argv)
);
CROW_ROUTE(app, "/res/login").methods(crow::HTTPMethod::POST)(
- [](const crow::request& req) {
+ [&app](const crow::request& req) {
cs::parser::Post pp(req.body);
+ auto& session = app.get_context(req);
crow::response res(303);
+ cs::cookie_data data;
+
// either redirect to clear the form if failed or pass user to index
- if (cs::handleLoginPost(pp))
+ if (cs::handleLoginPost(pp, data))
+ {
+ session.set("clientID", data.clientID);
+ session.set("clientToken", data.clientToken);
+ if (pp.hasKey("remember_me")){
+ auto value = pp["remember_me"];
+ auto& cookie_context = app.get_context(req);
+ if (value[0] == 'T')
+ {
+ cookie_context.set_cookie("clientID", data.clientID).path("/").max_age(cookie_age);
+ cookie_context.set_cookie("clientToken", data.clientToken).path("/").max_age(cookie_age);
+ }
+ }
res.set_header("Location", pp.hasKey("referer") ? pp["referer"] : "/");
- else
+ } else
res.set_header("Location", "/login.html");
return res;