diff --git a/README.md b/README.md index 675838b..d3feac8 100644 --- a/README.md +++ b/README.md @@ -20,5 +20,5 @@ Use file named `devices.json` in working directory or supply your own via config * From: https://github.com/yhirose/cpp-httplib * Version: 0.47.0 -# Info on API +# Info on TRMNL API * https://github.com/usetrmnl/trmnl-firmware diff --git a/main.cpp b/main.cpp index ebca4a3..ec9a0ae 100644 --- a/main.cpp +++ b/main.cpp @@ -18,6 +18,18 @@ using nlohmann::json; using namespace std; +void reload_container(TRMNLContainer& container, const string& filename) +{ + json j; + bool ok = read_file_json(j, filename, &cout); + if (!ok) + { + return; + } + container.clear(); + container = j; +} + int main(int argc, char **argv) { string config_filename = "config.json"; @@ -90,82 +102,144 @@ int main(int argc, char **argv) auto setup_handler = [&container, &devices_filename](const httplib::Request& req, httplib::Response& res) { - if (req.has_header("ID")) - { - json response; - string id = req.get_header_value("ID"); - TRMNL* trmnl = container.get_device_by_id(id); + json response; - // Refresh date from file - // Someone might have put the new device in - if (nullptr == trmnl) - { - json j; - read_file_json(j, devices_filename, &cout); - container.clear(); - container = j; - trmnl = container.get_device_by_id(id); - } - - if (nullptr == trmnl) - { - res.status = 404; - - response["status"] = 404; - response["api_key"] = nullptr; - response["friendly_id"] = nullptr; - response["image_url"] = nullptr; - response["filename"] = nullptr; - - res.body = response.dump(); - } - else - { - bool should_dump = false; - - res.status = 200; - if (trmnl->friendly_id().empty()) - { - should_dump = true; - trmnl->friendly_id(TRMNL::friendly_from_id(id)); - } - - if (trmnl->api_key().empty()) - { - should_dump = true; - trmnl->api_key("nullptr"); - } - - response["status"] = 200; - response["api_key"] = trmnl->api_key(); - response["friendly_id"] = trmnl->friendly_id(); - // TODO: Check for image in folder - response["image_url"] = "https://trmnl.com/images/setup/setup-logo.bmp"; - response["filename"] = "welcome"; - - res.body = response.dump(); - - if (should_dump) - { - write_file_json(container, devices_filename, &cout); - } - } - } - else + if (!req.has_header("ID")) { // Bad Request - No ID header res.status = 400; + + response["status"] = 400; + response["error"] = "No ID header"; + + res.set_header("Content-Type", "application/json"); + res.body = response.dump(); + + return; + } + + // Refresh data from file + // Someone might have put a new device in + reload_container(container, devices_filename); + + string id = req.get_header_value("ID"); + TRMNL* trmnl = container.get_device_by_id(id); + + if (nullptr == trmnl) + { + res.status = 404; + + response["status"] = 404; + response["api_key"] = nullptr; + response["friendly_id"] = nullptr; + response["image_url"] = nullptr; + response["filename"] = nullptr; + + res.set_header("Content-Type", "application/json"); + res.body = response.dump(); + return; + } + + bool should_dump = false; + + res.status = 200; + if (trmnl->friendly_id().empty()) + { + should_dump = true; + trmnl->friendly_id(TRMNL::friendly_from_id(id)); + } + + if (trmnl->api_key().empty()) + { + should_dump = true; + // TODO: Randomly generate key here + trmnl->api_key("nullptr"); + } + + response["status"] = 200; + response["api_key"] = trmnl->api_key(); + response["friendly_id"] = trmnl->friendly_id(); + // TODO: Check for image in folder + response["image_url"] = "https://trmnl.com/images/setup/setup-logo.bmp"; + response["filename"] = "welcome"; + + res.set_header("Content-Type", "application/json"); + res.body = response.dump(); + + if (should_dump) + { + write_file_json(container, devices_filename, &cout); } }; auto display_handler = [&container, &devices_filename](const httplib::Request& req, httplib::Response& res) { - res.status = 500; + json response; - for (auto header : res.headers) + if (!req.has_header("ID") || !req.has_header("Access-Token")) { - cout << header.first << ": " << header.second << endl; + // Bad Request + res.status = 400; + + response["status"] = 400; + response["error"] = "No ID and Access-Token headers set"; + + res.body = response.dump(); + res.set_header("Content-Type", "application/json"); + return; } + + // Refresh data from file + // Someone might have put a new device in + reload_container(container, devices_filename); + + string id = req.get_header_value("ID"); + string api_key = req.get_header_value("Access-Token"); + TRMNL* trmnl = container.get_device_by_id(id); + + if (nullptr == trmnl) + { + // Not Found + res.status = 404; + + response["status"] = 404; + response["error"] = "Device not found"; + + res.set_header("Content-Type", "application/json"); + res.body = response.dump(); + return; + } + + if (trmnl->api_key() != api_key) + { + // Forbidden + res.status = 403; + + response["status"] = 403; + response["error"] = "Wrong credentials for this device"; + + res.set_header("Content-Type", "application/json"); + res.body = response.dump(); + return; + } + + // TODO: Check for image in folder + // string image; + + // The ID and api_key match here + res.status = 200; + + // From docs: will be 202 if no user_id is attached to device + response["status"] = 0; + response["image_url"] = "https://trmnl.com/images/setup/setup-logo.bmp"; + response["filename"] = "2024-09-20T00:00:00"; + response["update_firmware"] = false; + response["firmware_url"] = nullptr; + response["refresh_rate"] = to_string(trmnl->refresh_rate()); + response["reset_firmware"] = false; + + res.set_header("Content-Type", "application/json"); + res.body = response.dump(); }; auto log_handler = [](const httplib::Request& req, httplib::Response& res)