Files
chookchat/server/src/main.cpp

124 lines
4.1 KiB
C++
Raw Normal View History

2026-07-20 19:02:04 +10:00
#include <cstdint>
2026-07-20 10:57:07 +10:00
#include <iostream>
#include <mutex>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
#include "httplib/httplib.h"
#include "bcrypt/bcrypt.h"
#include "db.h"
#include "post.h"
#include "generated/header.h"
#include "generated/footer.h"
2026-07-20 11:48:27 +10:00
#include "generated/style.h"
2026-07-20 19:02:04 +10:00
#include "generated/script.h"
2026-07-20 10:57:07 +10:00
int main() {
const bin2cpp::File& headerfile = bin2cpp::getHeaderHtmlFile();
const bin2cpp::File& footerfile = bin2cpp::getFooterHtmlFile();
2026-07-20 11:48:27 +10:00
const bin2cpp::File& stylefile = bin2cpp::getStyleCssFile();
2026-07-20 19:02:04 +10:00
const bin2cpp::File& scriptfile = bin2cpp::getScriptJsFile();
2026-07-20 10:57:07 +10:00
std::string header{headerfile.getBuffer(), headerfile.getSize()};
std::string footer{footerfile.getBuffer(), footerfile.getSize()};
2026-07-20 11:48:27 +10:00
std::string style{stylefile.getBuffer(), stylefile.getSize()};
2026-07-20 19:02:04 +10:00
std::string script{scriptfile.getBuffer(), scriptfile.getSize()};
2026-07-20 10:57:07 +10:00
Database database{"chookchat.db"};
std::mutex data_mutex;
httplib::Server svr;
2026-07-20 11:48:27 +10:00
svr.Get("/style.css", [&style](const httplib::Request& request, httplib::Response& response) {
response.set_content(style, "text/css");
});
2026-07-20 19:02:04 +10:00
svr.Get("/script.js", [&script](const httplib::Request& request, httplib::Response& response) {
response.set_content(script, "text/css");
});
2026-07-20 10:57:07 +10:00
svr.Get("/", [&header, &footer, &database, &data_mutex](const httplib::Request& request, httplib::Response& response) {
std::stringstream ss;
ss << header;
std::lock_guard<std::mutex> lock(data_mutex);
try {
std::vector<Post> posts = database.getTopPosts(100);
for (const auto& post : posts) {
ss << post.genHtml();
}
ss << footer;
response.set_content(ss.str(), "text/html");
} catch (const std::runtime_error& e) {
response.set_content("<p>there was an error :( it is: " + std::string(e.what()) + "</p>", "text/html");
}
});
2026-07-20 19:02:04 +10:00
svr.Post("/make_post", [&database, &data_mutex](const httplib::Request& request, httplib::Response& response) {
2026-07-20 10:57:07 +10:00
std::string username = request.get_param_value("username");
std::string password = request.get_param_value("password");
std::string post = request.get_param_value("post");
std::lock_guard<std::mutex> lock(data_mutex);
try {
uint64_t userId = 0;
std::optional<User> user = database.getUserByName(username);
if (user.has_value()) {
if (!bcrypt::validatePassword(password, user->passwordHash)) {
// noooo wrong password
response.set_content("<p>wrong password lmao</p>", "text/html");
return;
}
userId = user->id;
} else {
if (username.empty()) {
response.set_content("<p>hey you can't have an empty username!!!!1!!!1! >:(</p>", "text/html");
return;
}
// create user
User newUser{0, username, bcrypt::generateHash(password)};
database.addUser(newUser);
userId = newUser.id;
}
// and now we add their post
database.addPost(Post(post, userId));
response.set_redirect("/");
} catch (const std::runtime_error& e) {
2026-07-20 19:02:04 +10:00
response.set_content("<p>there was an error :( it is: " + std::string(e.what()) + "</p>", "text/html");
2026-07-20 10:57:07 +10:00
}
});
2026-07-20 19:02:04 +10:00
svr.Post("/like", [&database, &data_mutex](const httplib::Request& request, httplib::Response& response) {
std::string username = request.get_param_value("username");
std::string password = request.get_param_value("password");
std::string post = request.get_param_value("post");
std::lock_guard<std::mutex> lock(data_mutex);
try {
uint64_t postNum = std::stoull(post);
database.addLike(postNum, 0);
} catch (const std::runtime_error& e) {
response.set_content("<p>there was an error :( it is: " + std::string(e.what()) + "</p>", "text/html");
}
});
2026-07-20 10:57:07 +10:00
svr.listen("0.0.0.0", 8080);
}