Added loging page
This commit is contained in:
parent
38ff44f2e9
commit
79b5737bcb
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"httpPort" : 3010,
|
|
||||||
"services": [
|
|
||||||
["Calibre", " calibre-server.service"],
|
|
||||||
["File Server", "file-server.service"],
|
|
||||||
["Jellyfin", "jellyfin.service"],
|
|
||||||
["DuckDNS", "duckdns.service"],
|
|
||||||
["Wiki.js", "wiki.service"],
|
|
||||||
["qBitTorrent", "qbittorrent-nox@lukas.service"]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,7 +1,3 @@
|
|||||||
{
|
{
|
||||||
"httpPort" : 3010,
|
"httpPort" : 3010
|
||||||
"services": [
|
|
||||||
["Cups", "cups.service"],
|
|
||||||
["Waydriod", "waydroid-container.service"]
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@ -1,10 +1,38 @@
|
|||||||
|
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
let user = '';
|
import { API_BASE } from '$lib/config';
|
||||||
let password = '';
|
|
||||||
let loading = false;
|
let user : any = '';
|
||||||
let error = '';
|
let password : any = '';
|
||||||
|
let loading : any = false;
|
||||||
|
let error : any = '';
|
||||||
|
|
||||||
|
async function handleLogin() {
|
||||||
|
let error : any = '';
|
||||||
|
let loading : Boolean = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE}/api/shadowrun/characters`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
username: user,
|
||||||
|
password: password,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
characters = await res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
alert('Logged in!');
|
||||||
|
} catch (e) {
|
||||||
|
error = e.message;
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="login" on:submit|preventDefault={handleLogin}>
|
<form class="login" on:submit|preventDefault={handleLogin}>
|
||||||
@ -29,25 +57,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
|
||||||
async function handleLogin() {
|
|
||||||
error = '';
|
|
||||||
loading = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// placeholder – we’ll add real auth next
|
|
||||||
if user !== 'test@test.com' || password !== '1234') {
|
|
||||||
throw new Error('Invalid credentials');
|
|
||||||
}
|
|
||||||
|
|
||||||
alert('Logged in!');
|
|
||||||
} catch (e) {
|
|
||||||
error = e.message;
|
|
||||||
} finally {
|
|
||||||
loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.login {
|
.login {
|
||||||
|
|||||||
@ -1,14 +1,7 @@
|
|||||||
#ifndef __DATABASE_H__
|
#ifndef __DATABASE_H__
|
||||||
#define __DATABASE_H__
|
#define __DATABASE_H__
|
||||||
|
|
||||||
#include "sqlite3.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
#include <variant>
|
|
||||||
#include <optional>
|
|
||||||
#include <set>
|
|
||||||
#include <map>
|
|
||||||
#include "crow.h"
|
|
||||||
#include "sqlite_orm.h"
|
#include "sqlite_orm.h"
|
||||||
#include "ShadowrunDb.hpp"
|
#include "ShadowrunDb.hpp"
|
||||||
#include "loginDb.hpp"
|
#include "loginDb.hpp"
|
||||||
|
|||||||
@ -1,60 +1,41 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <format>
|
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "json_settings.h"
|
#include "json_settings.h"
|
||||||
|
#include "crow/logging.h"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
using namespace::AppSettings;
|
||||||
|
|
||||||
expected<AppSettings, string> AppSettings::loadAppSettings() {
|
Settings AppSettings::deafult(){
|
||||||
constexpr char settings_file[] = "static/settings.json";
|
return Settings {
|
||||||
ifstream file(settings_file);
|
.httpPort = 3010
|
||||||
if (!file.is_open()) {
|
|
||||||
return unexpected(format("Failed to open {}",settings_file));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the JSON
|
|
||||||
json j;
|
|
||||||
try {
|
|
||||||
file >> j;
|
|
||||||
} catch (const json::parse_error& e) {
|
|
||||||
return unexpected(format("Failed to parse JSON {}",e.what()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!j.contains("services") || !j["services"].is_array()) {
|
|
||||||
return unexpected("JSON does not contain an array called 'services'");
|
|
||||||
}
|
|
||||||
|
|
||||||
AppSettings settings;
|
|
||||||
|
|
||||||
for (const auto& item : j["services"]) {
|
|
||||||
if (item.is_array() && item.size() == 2) {
|
|
||||||
Service service = {
|
|
||||||
item[0].get<std::string>(),
|
|
||||||
item[1].get<std::string>()
|
|
||||||
};
|
};
|
||||||
settings.services.push_back(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.services.empty()){
|
|
||||||
return unexpected("'services' array in JSON file is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j.contains("httpPort")) {
|
|
||||||
settings.httpPort = j["httpPort"].get<int>();
|
|
||||||
} else {
|
|
||||||
settings.httpPort = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<std::string> AppSettings::getId(string_view name){
|
Settings AppSettings::load() {
|
||||||
for (auto& service : services) {
|
ifstream file(settingsFile);
|
||||||
if(service.name == name) {
|
if (!file.is_open()) {
|
||||||
return service.service;
|
CROW_LOG_ERROR << "Failed to load settings file" << settingsFile << " Loading default settings";
|
||||||
|
return AppSettings::deafult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << file.rdbuf(); // Read the whole file into the stringstream
|
||||||
|
std::string fileContents = buffer.str(); // Convert to std::string
|
||||||
|
auto result = utils::parseJson(fileContents);
|
||||||
|
|
||||||
|
if(!result){
|
||||||
|
CROW_LOG_ERROR << "failed to parse settings file, Loading default settings";
|
||||||
|
return AppSettings::deafult();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return result.value().get<Settings>();
|
||||||
|
} catch (...) {
|
||||||
|
CROW_LOG_ERROR << "failed to parse settings file, Loading default settings";
|
||||||
|
return AppSettings::deafult();
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +1,18 @@
|
|||||||
#ifndef JSON_SETTINGS_H
|
#ifndef JSON_SETTINGS_H
|
||||||
#define JSON_SETTINGS_H
|
#define JSON_SETTINGS_H
|
||||||
|
|
||||||
#include <vector>
|
#include "json.hpp"
|
||||||
#include <string>
|
|
||||||
#include <expected>
|
|
||||||
#include <optional>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
struct Service {
|
namespace AppSettings {
|
||||||
std::string name;
|
|
||||||
std::string service;
|
static constexpr char settingsFile[] = "assets/settings.json";
|
||||||
|
struct Settings {
|
||||||
|
int httpPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AppSettings {
|
Settings load();
|
||||||
static std::expected<AppSettings, std::string> loadAppSettings();
|
Settings deafult();
|
||||||
|
|
||||||
std::optional<std::string> getId(std::string_view name);
|
|
||||||
|
|
||||||
std::vector<Service> services;
|
|
||||||
std::optional<uint16_t> httpPort;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Settings, httpPort);
|
||||||
|
}
|
||||||
#endif // JSON_SETTINGS_H
|
#endif // JSON_SETTINGS_H
|
||||||
@ -41,7 +41,7 @@ void initLogin(crow::SimpleApp& app)
|
|||||||
|
|
||||||
CROW_ROUTE(app, "/login").methods("POST"_method)
|
CROW_ROUTE(app, "/login").methods("POST"_method)
|
||||||
([](const crow::request& req) {
|
([](const crow::request& req) {
|
||||||
auto body = utils::parseBody(req.body);
|
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");
|
return crow::response(400, "Invalid JSON");
|
||||||
|
|
||||||
@ -50,8 +50,8 @@ void initLogin(crow::SimpleApp& app)
|
|||||||
if(usenameIt == body.end() || passwordIt == body.end())
|
if(usenameIt == body.end() || passwordIt == body.end())
|
||||||
return crow::response(400, "No username or password in body");
|
return crow::response(400, "No username or password in body");
|
||||||
|
|
||||||
const std::string& username = usenameIt->second;
|
const std::string& username = *usenameIt;
|
||||||
const std::string& password = passwordIt->second;
|
const std::string& password = *passwordIt;
|
||||||
|
|
||||||
// Validate credentials
|
// Validate credentials
|
||||||
auto sessionId = loginUser(username, password);
|
auto sessionId = loginUser(username, password);
|
||||||
@ -67,6 +67,8 @@ void initLogin(crow::SimpleApp& app)
|
|||||||
"; HttpOnly; Path=/; SameSite=Strict"
|
"; HttpOnly; Path=/; SameSite=Strict"
|
||||||
// add "; Secure" when using HTTPS
|
// add "; Secure" when using HTTPS
|
||||||
);
|
);
|
||||||
|
res.set_header("Access-Control-Allow-Credentials", "true");
|
||||||
|
res.set_header("Access-Control-Allow-Origin", "http://localhost:5173");
|
||||||
|
|
||||||
res.body = "Logged in";
|
res.body = "Logged in";
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
22
src/main.cpp
22
src/main.cpp
@ -1,6 +1,5 @@
|
|||||||
#include <crow.h>
|
#include <crow.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
|
||||||
#include "json_settings.h"
|
#include "json_settings.h"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "login.hpp"
|
#include "login.hpp"
|
||||||
@ -43,26 +42,17 @@ int main() {
|
|||||||
return crow::response(200, "text/html", data);
|
return crow::response(200, "text/html", data);
|
||||||
});
|
});
|
||||||
|
|
||||||
const uint16_t defaultPort = 3010;
|
auto settings = AppSettings::load();
|
||||||
uint16_t httpPort = defaultPort;
|
auto opt_isPortOpen = utils::isLocalPortOpen(settings.httpPort);
|
||||||
{
|
|
||||||
auto opt_settings = AppSettings::loadAppSettings();
|
|
||||||
if (opt_settings.has_value()){
|
|
||||||
auto& settings = opt_settings.value();
|
|
||||||
httpPort = settings.httpPort.value_or(defaultPort);
|
|
||||||
} else {
|
|
||||||
CROW_LOG_ERROR << "failed to load settings : " << opt_settings.error();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto opt_isPortOpen = utils::isLocalPortOpen(httpPort);
|
|
||||||
if (opt_isPortOpen.has_value()){
|
if (opt_isPortOpen.has_value()){
|
||||||
if (opt_isPortOpen.value()){
|
if (opt_isPortOpen.value()){
|
||||||
CROW_LOG_ERROR << "Local port : " << httpPort << " is already open";
|
CROW_LOG_ERROR << "Local port : " << settings.httpPort << " is already open";
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CROW_LOG_ERROR << "failed to check if local port is open : " << opt_isPortOpen.error();
|
CROW_LOG_ERROR << "failed to check if local port is open : " << opt_isPortOpen.error();
|
||||||
}
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowrun::initApi(app);
|
shadowrun::initApi(app);
|
||||||
@ -110,5 +100,5 @@ int main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.loglevel(crow::LogLevel::INFO);
|
app.loglevel(crow::LogLevel::INFO);
|
||||||
app.bindaddr("0.0.0.0").port(httpPort).multithreaded().run();
|
app.bindaddr("0.0.0.0").port(settings.httpPort).multithreaded().run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include "databasepool.h"
|
#include "databasepool.h"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
#include "crow/logging.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace sqlite_orm;
|
using namespace sqlite_orm;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user