diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index f93ff4853..a48158840 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -38,3 +38,4 @@ export function updateLogSettings(logSettings: LogSettings): AxiosPromise { return AXIOS_BIN.get('/fetchLog'); } + diff --git a/interface/src/project/HelpInformation.tsx b/interface/src/project/HelpInformation.tsx index 16a27dbe4..1d28946ac 100644 --- a/interface/src/project/HelpInformation.tsx +++ b/interface/src/project/HelpInformation.tsx @@ -24,7 +24,22 @@ const HelpInformation: FC = () => { const { me } = useContext(AuthenticatedContext); - const onDownload = async (endpoint: string) => { + const saveFile = (json: any, endpoint: string) => { + const a = document.createElement('a'); + const filename = 'emsesp_' + endpoint + '.json'; + a.href = URL.createObjectURL( + new Blob([JSON.stringify(json, null, 2)], { + type: 'text/plain' + }) + ); + a.setAttribute('download', filename); + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + enqueueSnackbar('File downloaded', { variant: 'info' }); + }; + + const callAPI = async (endpoint: string) => { try { const response = await EMSESP.API({ device: 'system', @@ -34,19 +49,33 @@ const HelpInformation: FC = () => { if (response.status !== 200) { enqueueSnackbar('API call failed', { variant: 'error' }); } else { - const json = response.data; - const a = document.createElement('a'); - const filename = 'emsesp_' + endpoint + '.json'; - a.href = URL.createObjectURL( - new Blob([JSON.stringify(json, null, 2)], { - type: 'text/plain' - }) - ); - a.setAttribute('download', filename); - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - enqueueSnackbar('File downloaded', { variant: 'info' }); + saveFile(response.data, endpoint); + } + } catch (error: unknown) { + enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' }); + } + }; + + const downloadSettings = async () => { + try { + const response = await EMSESP.getSettings(); + if (response.status !== 200) { + enqueueSnackbar('Unable to get settings', { variant: 'error' }); + } else { + saveFile(response.data, 'settings'); + } + } catch (error: unknown) { + enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' }); + } + }; + + const downloadCustomizations = async () => { + try { + const response = await EMSESP.getCustomizations(); + if (response.status !== 200) { + enqueueSnackbar('Unable to get customizations', { variant: 'error' }); + } else { + saveFile(response.data, 'customizations'); } } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' }); @@ -103,7 +132,7 @@ const HelpInformation: FC = () => { To report an issue or request a feature, please  - onDownload('info')}> + callAPI('info')}> download  the debug information and include in a new  @@ -131,7 +160,7 @@ const HelpInformation: FC = () => { startIcon={} variant="outlined" color="primary" - onClick={() => onDownload('settings')} + onClick={() => downloadSettings()} > settings @@ -139,7 +168,7 @@ const HelpInformation: FC = () => { startIcon={} variant="outlined" color="primary" - onClick={() => onDownload('customizations')} + onClick={() => downloadCustomizations()} > customizations diff --git a/interface/src/project/api.ts b/interface/src/project/api.ts index c625630c5..d6804cda4 100644 --- a/interface/src/project/api.ts +++ b/interface/src/project/api.ts @@ -86,3 +86,11 @@ export function resetCustomizations(): AxiosPromise { export function API(apiCall: APIcall): AxiosPromise { return AXIOS_API.post('/', apiCall); } + +export function getSettings(): AxiosPromise { + return AXIOS.get('/getSettings'); +} + +export function getCustomizations(): AxiosPromise { + return AXIOS.get('/getCustomizations'); +} diff --git a/mock-api/server.js b/mock-api/server.js index 33764ab66..d6bc9fefc 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -1193,16 +1193,19 @@ rest_server.get(SYSTEM_INFO_ENDPOINT, (req, res) => { res.json(emsesp_info) }) -const SYSTEM_SETTINGS_ENDPOINT = API_ENDPOINT_ROOT + 'system/settings' -rest_server.post(SYSTEM_SETTINGS_ENDPOINT, (req, res) => { - console.log('System Settings POST: ' + JSON.stringify(req.body)) - res.sendStatus(200) -}) -rest_server.get(SYSTEM_SETTINGS_ENDPOINT, (req, res) => { - console.log('System Settings GET') +const GET_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'getSettings' +rest_server.get(GET_SETTINGS_ENDPOINT, (req, res) => { + console.log('System Settings:') res.json(settings) }) +const GET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'getCustomizations' +rest_server.get(GET_CUSTOMIZATIONS_ENDPOINT, (req, res) => { + console.log('Customizations:') + // not implemented yet + res.sendStatus(200) +}) + // start server const expressServer = rest_server.listen(port, () => console.log(`Mock server for EMS-ESP is up and running at http://localhost:${port}`), diff --git a/src/system.cpp b/src/system.cpp index 44eb94b31..cb3be0332 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -689,8 +689,6 @@ void System::commands_init() { // these commands will return data in JSON format Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, F("show system status")); - Command::add(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings, F("fetch system settings"), CommandFlag::ADMIN_ONLY); - Command::add(EMSdevice::DeviceType::SYSTEM, F_(customizations), System::command_customizations, F("fetch system customizations")); Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, F("fetch system commands")); #if defined(EMSESP_DEBUG) @@ -973,34 +971,6 @@ bool System::saveSettings(const char * filename, const char * section, JsonObjec return false; // not found } -// export all settings to JSON text -// we need to keep the original format so the import/upload works as we just replace files -// http://ems-esp/api/system/settings -bool System::command_settings(const char * value, const int8_t id, JsonObject & output) { - output["type"] = "settings"; - - JsonObject node = output.createNestedObject("System"); - node["version"] = EMSESP_APP_VERSION; - - extractSettings(NETWORK_SETTINGS_FILE, "Network", output); - extractSettings(AP_SETTINGS_FILE, "AP", output); - extractSettings(MQTT_SETTINGS_FILE, "MQTT", output); - extractSettings(NTP_SETTINGS_FILE, "NTP", output); - extractSettings(OTA_SETTINGS_FILE, "OTA", output); - extractSettings(SECURITY_SETTINGS_FILE, "Security", output); - extractSettings(EMSESP_SETTINGS_FILE, "Settings", output); - - return true; -} - -// http://ems-esp/api/system/customizations -// we need to keep the original format so the import/upload works as we just replace file -bool System::command_customizations(const char * value, const int8_t id, JsonObject & output) { - output["type"] = "customizations"; - extractSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", output); - return true; -} - // export status information including the device information // http://ems-esp/api/system/info bool System::command_info(const char * value, const int8_t id, JsonObject & output) { diff --git a/src/system.h b/src/system.h index 63010652b..2d1796f83 100644 --- a/src/system.h +++ b/src/system.h @@ -61,8 +61,6 @@ class System { static bool command_watch(const char * value, const int8_t id); static bool command_info(const char * value, const int8_t id, JsonObject & output); - static bool command_settings(const char * value, const int8_t id, JsonObject & output); - static bool command_customizations(const char * value, const int8_t id, JsonObject & output); static bool command_commands(const char * value, const int8_t id, JsonObject & output); std::string reset_reason(uint8_t cpu) const; diff --git a/src/version.h b/src/version.h index c77300d6d..93db4995f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.4.0b17" +#define EMSESP_APP_VERSION "3.4.0b18" diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index c79e04ca5..5ab041987 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -32,6 +32,12 @@ WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * security , _apiHandler("/api", std::bind(&WebAPIService::webAPIService_post, this, _1, _2), 256) { // for POSTS, must use 'Content-Type: application/json' in header server->on("/api", HTTP_GET, std::bind(&WebAPIService::webAPIService_get, this, _1)); // for GETS server->addHandler(&_apiHandler); + + // for settings + server->on(GET_SETTINGS_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebAPIService::getSettings, this, _1), AuthenticationPredicates::IS_ADMIN)); + server->on(GET_CUSTOMIZATIONS_PATH, + HTTP_GET, + securityManager->wrapRequest(std::bind(&WebAPIService::getCustomizations, this, _1), AuthenticationPredicates::IS_ADMIN)); } // HTTP GET @@ -150,4 +156,37 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) { #endif } +void WebAPIService::getSettings(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_XLARGE_DYN); + JsonObject root = response->getRoot(); + + root["type"] = "settings"; + + JsonObject node = root.createNestedObject("System"); + node["version"] = EMSESP_APP_VERSION; + + System::extractSettings(NETWORK_SETTINGS_FILE, "Network", root); + System::extractSettings(AP_SETTINGS_FILE, "AP", root); + System::extractSettings(MQTT_SETTINGS_FILE, "MQTT", root); + System::extractSettings(NTP_SETTINGS_FILE, "NTP", root); + System::extractSettings(OTA_SETTINGS_FILE, "OTA", root); + System::extractSettings(SECURITY_SETTINGS_FILE, "Security", root); + System::extractSettings(EMSESP_SETTINGS_FILE, "Settings", root); + + response->setLength(); + request->send(response); +} + +void WebAPIService::getCustomizations(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_XLARGE_DYN); + JsonObject root = response->getRoot(); + + root["type"] = "customizations"; + + System::extractSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", root); + + response->setLength(); + request->send(response); +} + } // namespace emsesp diff --git a/src/web/WebAPIService.h b/src/web/WebAPIService.h index 799cc82fd..5e5d2321a 100644 --- a/src/web/WebAPIService.h +++ b/src/web/WebAPIService.h @@ -20,6 +20,8 @@ #define WebAPIService_h #define EMSESP_API_SERVICE_PATH "/api" +#define GET_SETTINGS_PATH "/rest/getSettings" +#define GET_CUSTOMIZATIONS_PATH "/rest/getCustomizations" namespace emsesp { @@ -46,6 +48,9 @@ class WebAPIService { static uint16_t api_fails_; void parse(AsyncWebServerRequest * request, JsonObject & input); + + void getSettings(AsyncWebServerRequest * request); + void getCustomizations(AsyncWebServerRequest * request); }; } // namespace emsesp