This commit is contained in:
2026-02-27 22:17:33 +01:00
commit 8e95149d8e
27 changed files with 4480 additions and 0 deletions

159
main/zk_handlers.h Normal file
View File

@@ -0,0 +1,159 @@
#ifndef ZK_HANDLERS_H
#define ZK_HANDLERS_H
#include "provision.h"
#include "zk_auth.h"
#include "zk_web_page.h"
#include <esp_http_server.h>
#include <esp_log.h>
#include <esp_timer.h>
#include <string.h>
static const char *TAG_ZK = "zk_handlers";
// Global ZK Auth instance (to be initialized in main)
extern ZKAuth zk_auth;
extern httpd_handle_t server_http;
// Serve the main web interface
static esp_err_t handle_zk_root(httpd_req_t *req) {
// Check if provisioning is needed - if so, redirect
if (needs_provisioning()) {
ESP_LOGI(TAG_ZK, "Provisioning needed - redirecting to /provision");
httpd_resp_set_status(req, "302 Found");
httpd_resp_set_hdr(req, "Location", "/provision");
httpd_resp_sendstr(req, "Redirecting to provisioning page...");
return ESP_OK;
}
// Normal landing page
httpd_resp_set_type(req, "text/html");
httpd_resp_sendstr(req, ZK_WEB_PAGE);
return ESP_OK;
}
// API endpoint: Get device identity
static esp_err_t handle_zk_identity(httpd_req_t *req) {
char *json_response = zk_auth.get_identity_json();
if (json_response == NULL) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
"Failed to get identity");
return ESP_FAIL;
}
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_sendstr(req, json_response);
free(json_response);
return ESP_OK;
}
// API endpoint: Process unlock request
static esp_err_t handle_zk_unlock(httpd_req_t *req) {
// Read POST body
char content[1024];
int ret = httpd_req_recv(req, content, sizeof(content) - 1);
if (ret <= 0) {
if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
httpd_resp_send_408(req);
}
return ESP_FAIL;
}
content[ret] = '\0';
bool success = false;
char *response = zk_auth.process_unlock(content, &success);
if (response == NULL) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Internal error");
return ESP_FAIL;
}
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_set_status(req, success ? "200 OK" : "400 Bad Request");
httpd_resp_sendstr(req, response);
free(response);
return ESP_OK;
}
static esp_err_t handle_zk_status(httpd_req_t *req) {
unsigned long uptime_ms = esp_timer_get_time() / 1000;
char response[128];
snprintf(response, sizeof(response), "{\"unlocked\":%s,\"uptime\":%lu}",
zk_auth.is_unlocked() ? "true" : "false", uptime_ms);
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_sendstr(req, response);
return ESP_OK;
}
// API endpoint: Lock the device
static esp_err_t handle_zk_lock(httpd_req_t *req) {
zk_auth.lock();
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_sendstr(req, "{\"unlocked\":false}");
return ESP_OK;
}
// Handle CORS preflight
static esp_err_t handle_zk_options(httpd_req_t *req) {
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "POST, GET, OPTIONS");
httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
httpd_resp_set_status(req, "204 No Content");
httpd_resp_send(req, NULL, 0);
return ESP_OK;
}
// Register all ZK auth routes to the HTTP server
void register_zk_handlers(httpd_handle_t server) {
// Root handler for ZK web interface
httpd_uri_t root_uri = {.uri = "/",
.method = HTTP_GET,
.handler = handle_zk_root,
.user_ctx = NULL};
httpd_register_uri_handler(server, &root_uri);
// API endpoints
httpd_uri_t identity_uri = {.uri = "/api/identity",
.method = HTTP_GET,
.handler = handle_zk_identity,
.user_ctx = NULL};
httpd_register_uri_handler(server, &identity_uri);
httpd_uri_t status_uri = {.uri = "/api/status",
.method = HTTP_GET,
.handler = handle_zk_status,
.user_ctx = NULL};
httpd_register_uri_handler(server, &status_uri);
httpd_uri_t unlock_uri = {.uri = "/api/unlock",
.method = HTTP_POST,
.handler = handle_zk_unlock,
.user_ctx = NULL};
httpd_register_uri_handler(server, &unlock_uri);
httpd_uri_t unlock_options_uri = {.uri = "/api/unlock",
.method = HTTP_OPTIONS,
.handler = handle_zk_options,
.user_ctx = NULL};
httpd_register_uri_handler(server, &unlock_options_uri);
httpd_uri_t lock_uri = {.uri = "/api/lock",
.method = HTTP_POST,
.handler = handle_zk_lock,
.user_ctx = NULL};
httpd_register_uri_handler(server, &lock_uri);
ESP_LOGI(TAG_ZK, "ZK Auth routes registered:");
ESP_LOGI(TAG_ZK, " GET / - Web interface");
ESP_LOGI(TAG_ZK, " GET /api/identity - Device identity");
ESP_LOGI(TAG_ZK, " GET /api/status - Session status");
ESP_LOGI(TAG_ZK, " POST /api/unlock - Unlock request");
ESP_LOGI(TAG_ZK, " POST /api/lock - Lock device");
}
#endif // ZK_HANDLERS_H