diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte
index fd03663..721f701 100644
--- a/frontend/src/routes/+page.svelte
+++ b/frontend/src/routes/+page.svelte
@@ -2,59 +2,57 @@
-
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 5d1cc70..852bf08 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -29,20 +29,21 @@ bool isLoggedIn(const crow::request& req) {
std::optional loginUser(const std::string& username, const std::string& password)
{
auto user = getVerifiedUser(username, password);
- if (user.has_value()) {
- return sessionHandler.createSession(user.value().id);
+ if (user) {
+ return sessionHandler.createSession(user->id);
}
return {};
}
void initLogin(crow::SimpleApp& app)
{
- // createUser("lukas", "Trollar4928");
+
+ //createUser("lukas", "Trollar4928");
CROW_ROUTE(app, "/login").methods("POST"_method)
([](const crow::request& req) {
nlohmann::json body = nlohmann::json::parse(req.body); // parse JSON from HTTP body
- if (!body.empty())
+ if (body.empty())
return crow::response(400, "Invalid JSON");
auto usenameIt = body.find("username");
diff --git a/src/login/login.hpp b/src/login/login.hpp
index ad245b4..8127a4b 100644
--- a/src/login/login.hpp
+++ b/src/login/login.hpp
@@ -11,15 +11,27 @@ void initLogin(crow::SimpleApp& app);
bool isLoggedIn(const crow::request& req);
-// lambda to be used by endpoint that requiere login
+// login_required lambda that works for any handler with arbitrary args
inline auto login_required = [](auto handler){
- return [handler](const crow::request& req){
+ return [handler](auto&&... args) -> crow::response {
+ // the first argument is always crow::request
+ const crow::request& req = std::get<0>(std::forward_as_tuple(args...));
if (!isLoggedIn(req)) {
- return crow::response(401, "Login required");
+ return crow::response(401, "Login required");
+ }
+
+ // call original handler with all arguments
+ auto result = handler(std::forward(args)...);
+
+ // ensure crow::response return type
+ if constexpr (std::is_same_v) {
+ return result;
+ } else {
+ return crow::response(result);
}
- return handler(req);
};
};
+
}
#endif // __LOGIN_H__
\ No newline at end of file
diff --git a/src/login/loginDb.cpp b/src/login/loginDb.cpp
index fc939f4..48bbf29 100644
--- a/src/login/loginDb.cpp
+++ b/src/login/loginDb.cpp
@@ -1,8 +1,11 @@
#include "loginDb.hpp"
#include "databasepool.h"
+#include
#include
#include
#include
+#include
+
extern "C" {
#include "monocypher.h"
}
@@ -59,8 +62,14 @@ int createUser(const std::string& username, const std::string& password){
int64_t id;
auto db = dbpool.acquire();
- auto user = db->get_optional(
- where(c(&User::username) == username)
+ for (auto &u : db->get_all()) {
+ if (u.username == username){
+ std::cout << "WTF" << std::endl;
+ };
+ }
+
+ auto user = db->get_optional(
+ where(c(&login::User::username) == username)
);
if (user.has_value()) {
@@ -76,11 +85,16 @@ int createUser(const std::string& username, const std::string& password){
std::optional getUser(const std::string& username){
auto db = dbpool.acquire();
- auto user = db->get_optional(
- where(c(&User::username) == username)
+ auto user = db->get_all(
+ where(c(&login::User::username) == username)
);
dbpool.release(db);
- return user;
+
+ if(user.size() > 0){
+ return user[0];
+ }
+
+ return {};
}
std::optional getVerifiedUser(const std::string& username, const std::string& password){
@@ -88,7 +102,7 @@ std::optional getVerifiedUser(const std::string& username, const std::stri
if (!user.has_value())
return {};
- if (verifyUser(user.value(), password)){
+ if (verifyUser(*user, password)){
return user;
}
return {};
diff --git a/src/login/loginDb.hpp b/src/login/loginDb.hpp
index 4719bd4..9b71980 100644
--- a/src/login/loginDb.hpp
+++ b/src/login/loginDb.hpp
@@ -3,7 +3,6 @@
#include
#include
-#include
#include "json.hpp"
#include "utils.hpp"
namespace login
diff --git a/src/main.cpp b/src/main.cpp
index ea013b4..56b7cee 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -7,38 +7,12 @@
using namespace std;
-std::string read_file(const std::string& path) {
- std::ifstream file(path, std::ios::binary);
- if (!file) {
- throw std::runtime_error("Cannot open file: " + path);
- }
- std::ostringstream ss;
- ss << file.rdbuf();
- return ss.str();
-}
-
-// Simple MIME type detection
-std::string get_mime_type(const std::string& path) {
- if (path.ends_with(".html")) return "text/html";
- if (path.ends_with(".js")) return "text/javascript";
- if (path.ends_with(".css")) return "text/css";
- if (path.ends_with(".json")) return "application/json";
- if (path.ends_with(".svg")) return "image/svg+xml";
- if (path.ends_with(".png")) return "image/png";
- if (path.ends_with(".jpg") || path.ends_with(".jpeg")) return "image/jpeg";
- if (path.ends_with(".woff")) return "font/woff";
- if (path.ends_with(".woff2")) return "font/woff2";
- if (path.ends_with(".pdf")) return "application/pdf";
- return "application/octet-stream";
-}
-
int main() {
crow::SimpleApp app;
- const filesystem::path build_dir = "frontend/build/"; // <-- set your build folder
// Root route
CROW_ROUTE(app, "/")([&]() {
- auto data = read_file(build_dir / "index.html");
+ auto data = utils::read_file(utils::build_dir / "index.html");
return crow::response(200, "text/html", data);
});
@@ -63,40 +37,19 @@ int main() {
([&](const std::string& p) {
const filesystem::path assets_dir = "assets/"; // <-- set your build folder
filesystem::path file_path = assets_dir / p;
-
- // If file exists, serve it
- if (filesystem::exists(file_path)) {
- auto data = read_file(file_path);
- auto mime = get_mime_type(file_path.string());
- return crow::response(200, mime.c_str(), data);
- }
-
- // SPA fallback: serve root index.html for unknown routes
- filesystem::path fallback = build_dir / "index.html";
- auto data = read_file(fallback);
- return crow::response(404, "text/html", data);
+ return utils::getFile(file_path);
});
// Catch-all route for static files and SPA fallback
CROW_ROUTE(app, "/")
([&](const std::string& p) {
- filesystem::path file_path = build_dir / p;
+ filesystem::path file_path = utils::build_dir / p;
// If path is a directory, serve index.html inside it
if (filesystem::is_directory(file_path))
file_path /= "index.html";
- // If file exists, serve it
- if (filesystem::exists(file_path)) {
- auto data = read_file(file_path);
- auto mime = get_mime_type(file_path.string());
- return crow::response(200, mime.c_str(), data);
- }
-
- // SPA fallback: serve root index.html for unknown routes
- filesystem::path fallback = build_dir / "index.html";
- auto data = read_file(fallback);
- return crow::response(404, "text/html", data);
+ return utils::getFile(file_path);
});
app.loglevel(crow::LogLevel::INFO);
diff --git a/src/shadowrun/ShadowrunApi.cpp b/src/shadowrun/ShadowrunApi.cpp
index 7f8fce6..598bdd8 100644
--- a/src/shadowrun/ShadowrunApi.cpp
+++ b/src/shadowrun/ShadowrunApi.cpp
@@ -26,16 +26,26 @@ static std::unordered_map parse_query_string(const std
return params;
}
-static crow::response rsp(const std::string& msg){
- auto str = format(""
- "{}
", msg);
- return crow::response{str};
-}
+void initApi(crow::SimpleApp& app){
+
+ CROW_ROUTE(app, "/assets/shadowrun/")
+ ([&](const crow::request& req, const std::string& p) {
+ if (!login::isLoggedIn(req)) {
+ return crow::response(401, "Login required");
+ }
+
+ const filesystem::path assets_dir = "assets/shadowrun/";
+ filesystem::path file_path = assets_dir / p;
+ return utils::getFile(file_path);
+ });
-void initApi(crow::SimpleApp& app)
-{
CROW_ROUTE(app, "/api/shadowrun/characters")
- ([&]() {
+ ([&](const crow::request& req) {
+
+ if (!login::isLoggedIn(req)) {
+ return crow::response(401, "Login required");
+ }
+
auto characters = getCharacters();
auto res =
crow::response(200, utils::toJsonArray(characters));
@@ -45,6 +55,10 @@ void initApi(crow::SimpleApp& app)
CROW_ROUTE(app, "/api/shadowrun/characters").methods("POST"_method)
([](const crow::request& req) {
+ if (!login::isLoggedIn(req)) {
+ return crow::response(401, "Login required");
+ }
+
nlohmann::json data = nlohmann::json::parse(req.body); // parse JSON from HTTP body
auto name = data["name"];
int id = createCharacter(name);
@@ -60,7 +74,10 @@ void initApi(crow::SimpleApp& app)
});
CROW_ROUTE(app, "/api/shadowrun/characters/")
- ([&](int id) {
+ ([&](const crow::request& req, int id) {
+ if (!login::isLoggedIn(req)) {
+ return crow::response(401, "Login required");
+ }
auto optCharacter = getChracter(id);
if (!optCharacter.has_value())
return crow::response(404, "Character not found");
@@ -71,7 +88,10 @@ void initApi(crow::SimpleApp& app)
});
CROW_ROUTE(app, "/api/shadowrun/characters_data/")
- ([&](int id) {
+ ([&](const crow::request& req, int id) {
+ if (!login::isLoggedIn(req)) {
+ return crow::response(401, "Login required");
+ }
nlohmann::json j;
const auto characterData = getChracterData(id);
@@ -99,6 +119,9 @@ void initApi(crow::SimpleApp& app)
CROW_ROUTE(app, "/api/shadowrun/characters_data/").methods("POST"_method)
([&](const crow::request& req, int id) {
+ if (!login::isLoggedIn(req)) {
+ return crow::response(401, "Login required");
+ }
nlohmann::json j = nlohmann::json::parse(req.body);
for (auto type : magic_enum::enum_values()) {
@@ -110,7 +133,6 @@ void initApi(crow::SimpleApp& app)
auto res = crow::response(200, "Saved Character data");
return res;
- //return crow::response(405, ret.error());
});
}
diff --git a/src/utils.cpp b/src/utils.cpp
index 4b11be9..554c46c 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -6,6 +6,7 @@
#include
#include
#include "utils.hpp"
+#include "crow/http_response.h"
#include
#include
#include
@@ -141,6 +142,45 @@ string currentTime(){
return ss.str();
}
+std::string read_file(const std::string& path) {
+ std::ifstream file(path, std::ios::binary);
+ if (!file) {
+ throw std::runtime_error("Cannot open file: " + path);
+ }
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ return ss.str();
+}
+
+// Simple MIME type detection
+std::string get_mime_type(const std::string& path) {
+ if (path.ends_with(".html")) return "text/html";
+ if (path.ends_with(".js")) return "text/javascript";
+ if (path.ends_with(".css")) return "text/css";
+ if (path.ends_with(".json")) return "application/json";
+ if (path.ends_with(".svg")) return "image/svg+xml";
+ if (path.ends_with(".png")) return "image/png";
+ if (path.ends_with(".jpg") || path.ends_with(".jpeg")) return "image/jpeg";
+ if (path.ends_with(".woff")) return "font/woff";
+ if (path.ends_with(".woff2")) return "font/woff2";
+ if (path.ends_with(".pdf")) return "application/pdf";
+ return "application/octet-stream";
+}
+
+crow::response getFile(const filesystem::path& file_path){
+ // If file exists, serve it
+ if (filesystem::exists(file_path)) {
+ auto data = read_file(file_path);
+ auto mime = get_mime_type(file_path.string());
+ return crow::response(200, mime.c_str(), data);
+ }
+
+ // SPA fallback: serve root index.html for unknown routes
+ filesystem::path fallback = build_dir / "index.html";
+ auto data = read_file(fallback);
+ return crow::response(404, "text/html", data);
+}
+
std::expected parseJson(const std::string& input) {
try {
return nlohmann::json::parse(input);
diff --git a/src/utils.hpp b/src/utils.hpp
index 3fc9a4b..0b558e8 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -5,10 +5,13 @@
#include
#include
#include
-#include