-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
92 lines (82 loc) · 3.62 KB
/
main.cpp
File metadata and controls
92 lines (82 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <crow.h>
#include <jwt-cpp/jwt.h>
#include <picojson/picojson.h>
#include "jwt.hpp"
#include "data_store.hpp"
#include "dotenv.hpp"
#define MSC_COMPATIBLE_SPRINTF(BUFFER_PTR, FORMAT_PTR, VALUE) snprintf((BUFFER_PTR), sizeof(BUFFER_PTR), (FORMAT_PTR), (VALUE))
int main() {
std::map<std::string, std::string> env = load_dotenv();
auto& dt = env;
crow::SimpleApp app;
std::string port_str = dt["PORT"];
std::string host = dt["HOST"];
uint16_t port = static_cast<uint16_t>(std::stoi(port_str));
// Initialize database
std::string db_path = dt["FILE_STORE_PATH"];
DataStore::Database db(db_path);
CROW_ROUTE(app, "/api/sync")
.methods("GET"_method, "PUT"_method, "POST"_method)
([&dt, &db](const crow::request& req) {
std::string jwt_secret = dt["JWT_SECRET"];
std::string ids = dt["JWT_USERS"];
auto token = req.get_header_value("Authorization");
auto jwt_data = verify_jwt(token.substr(7), jwt_secret, ids); // Strip "Bearer " prefix
if (jwt_data.count("error") > 0) {
std::string error_msg = jwt_data["error"].get<std::string>();
if (error_msg == "Invalid id") {
picojson::object res;
res["status"] = picojson::value("error");
res["message"] = picojson::value("Unauthorized!");
return crow::response(401, picojson::value(res).serialize());
} else {
picojson::object res;
res["status"] = picojson::value("error");
res["message"] = picojson::value("Invalid token");
return crow::response(422, picojson::value(res).serialize());
}
}
std::string uid = jwt_data["id"].get<std::string>();
if (req.method == crow::HTTPMethod::Get) {
auto r = db.readData(uid);
if (r == "404") {
return crow::response(404, "File not found");
};
return crow::response(r);
}
if (req.method == crow::HTTPMethod::Post) {
return crow::response("test ok");
}
if (req.method == crow::HTTPMethod::Put) {
auto r = db.writeData(uid, req.body);
if (!r) {
return crow::response(500, "failed");
}
return crow::response("ok");
}
// Method is other than GET and PUT, which should not happen due to the route configuration
return crow::response(405);
});
CROW_ROUTE(app, "/test")
.methods("GET"_method)
([]() {
return "ok";
});
std::cout << "Electerm sync server starting..." << std::endl;
std::cout << "Server will be available at: http://" << host << ":" << port << std::endl;
std::cout << std::endl;
std::cout << "API Endpoints:" << std::endl;
std::cout << " GET /api/sync - Retrieve user data (requires JWT auth)" << std::endl;
std::cout << " POST /api/sync - Test endpoint (requires JWT auth)" << std::endl;
std::cout << " PUT /api/sync - Store user data (requires JWT auth)" << std::endl;
std::cout << " GET /test - Health check endpoint" << std::endl;
std::cout << std::endl;
std::cout << "To use with Electerm:" << std::endl;
std::cout << " 1. In Electerm sync settings, select 'Custom sync server'" << std::endl;
std::cout << " 2. Set Server URL: http://" << host << ":" << port << std::endl;
std::cout << " 3. Set JWT_SECRET: " << dt["JWT_SECRET"] << std::endl;
std::cout << " 4. Set JWT_USER_NAME: one of [" << dt["JWT_USERS"] << "]" << std::endl;
std::cout << std::endl;
app.port(port).bindaddr(host).run();
return 0;
}