Skip to content

Commit 5cbf658

Browse files
committed
JSON config bug fix for pwd
1 parent 85422ea commit 5cbf658

File tree

10 files changed

+159
-51
lines changed

10 files changed

+159
-51
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ the first steam will freeze.
5757
### Wiring for AI-THINKER Boards (and similar clone-alikes)
5858

5959
Is pretty simple, You just need jumper wires, no soldering really required, see the diagram below.
60-
![Hoockup](https://github.com/abratchik/esp32-cam-webserver/blob/master/assets/hookup.png)
60+
![Hoockup](assets/hookup.png)
6161

6262
* Connect the **RX** line from the serisal adapter to the **TX** pin on ESP32
6363
* The adapters **TX** line goes to the ESP32 **RX** pin
@@ -83,7 +83,7 @@ can be either a micro SD flash memory card or the built-in flash memory with Lit
8383
#### Using micro SD flash memory card
8484
You will need a blank SD card, which must be formatted as FAT32. Insert it into the micro SD slot of your computer and copy all the files from the **data** folder. The structure of files on the SD card should be
8585
like this:
86-
![Data Folder](https://github.com/abratchik/esp32-cam-webserver/blob/master/assets/data-folder.png)
86+
![Data Folder](assets/data-folder.png)
8787

8888
After that, insert the card in the slot of your ESP32CAM board and restart it. The Server should start normally.
8989

@@ -127,12 +127,12 @@ Connected
127127

128128
Connected to the access point and open the url http://192.168.4.1/. You should see the following page:
129129
<div align="center">
130-
<img src="https://github.com/abratchik/esp32-cam-webserver/blob/master/assets/wifi-setup-ap.png" width="250">
130+
<img src="assets/wifi-setup-ap.png" width="350">
131131
</div>
132132

133133
Switch the Access Point Mode off. The screen will change as follows:
134134
<div align="center">
135-
<img src="https://github.com/abratchik/esp32-cam-webserver/blob/master/assets/wifi-setup.png" width="250">
135+
<img src="assets/wifi-setup.png" width="350">
136136
</div>
137137

138138
Specify SSID and Password for your WiFi setup. This board supports only 2.4 GHz band so you will need to ensure you wifi router has this band enabled.
@@ -147,7 +147,7 @@ and connect to your wifi automatically. The assigned IP address can be seen in t
147147
Open the browser and navigate to http://<YOUR_IP_ADDRESS:YOUR_PORT>/ (for example, http://192.168.0.2:8080)
148148

149149
You should see the following screen:
150-
![Index](https://github.com/abratchik/esp32-cam-webserver/blob/master/assets/index.png).
150+
![Index](assets/index.png).
151151

152152
Here you can take still images or start the video streaming from the camera installed on ESP32CAM.
153153

@@ -246,9 +246,9 @@ The parameter `mapping` allows to configure folders with static content for the
246246

247247
Assuming you are using the latest Espressif Arduino core the `ESP32 Dev Module` board
248248
will appear in the ESP32 Arduino section of the boards list. Select this (do not use
249-
the `AI-THINKER` entry listed in the boiards menu, it is not OTA compatible, and will
249+
the `AI-THINKER` entry listed in the boards menu, it is not OTA compatible, and will
250250
cause the module to crash and reboot rather than updating if you use it.
251-
![IDE board config](https://github.com/abratchik/esp32-cam-webserver/blob/master/assets/ota-board-selection.png)
251+
![IDE board config](assets/ota-board-selection.png)
252252

253253
Make sure you select the `Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)` partition
254254
scheme and turn `PSRAM` on.

data/default_httpd.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
"autolamp":true,
44
"flashlamp":100,
55
"pwm": [{"pin":4, "frequency":50000, "resolution":9}],
6-
"mapping":[ {"uri":"/dump", "path": "/www/dump.html"},
7-
{"uri":"/img", "path": "/www/img"},
6+
"mapping":[ {"uri":"/img", "path": "/www/img"},
87
{"uri":"/css", "path": "/www/css"},
98
{"uri":"/js", "path": "/www/js"}],
109
"debug_mode": false

data/www/js/utils.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ const addTextInput = (parent, field) => {
211211
input.setAttribute("placeholder", "xxx.xxx.xxx.xxx");
212212
input.classList.add("ipv4");
213213
}
214+
else if(field.type == "password") {
215+
input.setAttribute("type", field.type);
216+
input.setAttribute("autocomplete", "off");
217+
}
214218
else {
215219
input.setAttribute("type", field.type);
216220
}
@@ -371,17 +375,21 @@ function submitChanges (el) {
371375
}
372376

373377
if(el.id == "reboot") {
374-
setTimeout(function() {
375-
location.replace(document.URL);
376-
}, 30000);
378+
var rebootToUrl = el.getAttribute("data-reboot_to");
379+
if(!rebootToUrl) {
380+
rebootToUrl = document.URL;
381+
}
382+
setTimeout(function(url) {
383+
location.replace(url);
384+
}, 30000, rebootToUrl);
377385
}
378386
}
379387
else if(el.type == "range") {
380388
el.setAttribute("data-updating", "");
381389
}
382390

383391
let host = document.location.origin;
384-
let value = refreshControl(el);
392+
let value = encodeURIComponent(refreshControl(el));
385393

386394
const query = `${host}/control?var=${el.id}&val=${value}`;
387395

data/www/setup.html

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,25 @@
8585
if(submitChanges(el)) {
8686
if(el.id == "reboot") {
8787
hide(settings);
88-
header.innerHTML = '<h1>Rebooting!</h1>';
88+
header.innerHTML = '<h1>Rebooting!</h1><hr>Page will reload after 30 seconds.';
89+
}
90+
else if(el.id == "save_prefs") {
91+
rebootBtn = document.getElementById("reboot");
92+
portField = document.getElementById("port");
93+
if(rebootBtn && portField) {
94+
rebootUrl = location.protocol + '//' + location.hostname + ':' + portField.value + '/';
95+
rebootBtn.setAttribute("data-reboot_to", rebootUrl);
96+
}
8997
}
9098
}
9199
}
92-
else
100+
else {
93101
el.onchange = () => submitChanges(el);
94-
102+
}
95103
});
96104

97105
cameraButton.onclick = () => {
98-
window.location.href = '/';
106+
window.location.href = '/index';
99107
}
100108

101109
monitorButton.onclick = () => {

src/app_component.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,66 @@ int CLAppComponent::parsePrefs(jparse_ctx_t *jctx) {
7070
}
7171

7272
return ret;
73+
}
74+
75+
int CLAppComponent::urlDecode(char * decoded, char * source, size_t len) {
76+
char temp[] = "0x00";
77+
int i=0;
78+
char * ptr = decoded;
79+
while (i < len){
80+
char decodedChar;
81+
char encodedChar = *(source+i);
82+
i++;
83+
if ((encodedChar == '%') && (i + 1 < len)){
84+
temp[2] = *(source+i); i++;
85+
temp[3] = *(source+i); i++;
86+
decodedChar = strtol(temp, NULL, 16);
87+
} else if (encodedChar == '+') {
88+
decodedChar = ' ';
89+
} else {
90+
decodedChar = encodedChar; // normal ascii char
91+
}
92+
*ptr = decodedChar;
93+
ptr++;
94+
if(decodedChar == '\0') break;
95+
}
96+
return OS_SUCCESS;
97+
}
98+
99+
int CLAppComponent::urlEncode(char * encoded, char * source, size_t len) {
100+
char c, code0, code1, code2;
101+
102+
char * ptr = encoded;
103+
104+
for(int i=0; i < len; i++) {
105+
c = *(source+i);
106+
if(c == '\0') {
107+
break;
108+
}
109+
else if(c == ' ') {
110+
*ptr = '+'; ptr++;
111+
}
112+
else if(isalnum(c)) {
113+
*ptr = c; ptr++;
114+
}
115+
else {
116+
117+
code1 = (c & 0xf)+'0';
118+
if ((c & 0xf) > 9) {
119+
code1 = (c & 0xf) - 10 + 'A';
120+
}
121+
c = (c >> 4) & 0xf;
122+
code0 = c + '0';
123+
if (c > 9) {
124+
code0 = c - 10 + 'A';
125+
}
126+
127+
*ptr = '%'; ptr++;
128+
*ptr = code0; ptr++;
129+
*ptr = code1; ptr++;
130+
131+
}
132+
}
133+
*ptr = '\0';
134+
return OS_SUCCESS;
73135
}

src/app_component.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "storage.h"
99

1010
/**
11-
* @brief Abstract root class for the appication components.
11+
* @brief Abstract root class for the application components.
1212
*
1313
*/
1414
class CLAppComponent {
@@ -44,6 +44,9 @@ class CLAppComponent {
4444

4545
int parsePrefs(jparse_ctx_t *jctx);
4646

47+
int urlDecode(char * decoded, char * source, size_t len);
48+
int urlEncode(char * encoded, char * source, size_t len);
49+
4750

4851
private:
4952
// prefix for forming preference file name of this class

src/app_conn.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ int CLAppConn::loadPrefs() {
201201
json_obj_get_bool(&jctx, (char*)"dhcp", &dhcp);
202202
}
203203

204+
char dbuf[192];
205+
204206
if (ret == OS_SUCCESS && json_obj_get_array(&jctx, (char*)"stations", &stationCount) == OS_SUCCESS) {
205207
Serial.print("Known external SSIDs: ");
206208
if(stationCount>0)
@@ -209,8 +211,9 @@ int CLAppConn::loadPrefs() {
209211
if(json_arr_get_object(&jctx, i) == OS_SUCCESS) {
210212
Station *s = (Station*) malloc(sizeof(Station));
211213
if(json_obj_get_string(&jctx, (char*)"ssid", s->ssid, sizeof(s->ssid)) == OS_SUCCESS &&
212-
json_obj_get_string(&jctx, (char*)"pass", s->password, sizeof(s->password)) == OS_SUCCESS) {
214+
json_obj_get_string(&jctx, (char*)"pass", dbuf, sizeof(dbuf)) == OS_SUCCESS) {
213215
Serial.printf("%s\r\n", s->ssid);
216+
urlDecode(s->password, dbuf, sizeof(dbuf));
214217
stationList[i] = s;
215218
}
216219
else {
@@ -236,7 +239,8 @@ int CLAppConn::loadPrefs() {
236239
}
237240

238241
json_obj_get_string(&jctx, (char*)"ap_ssid", apName, sizeof(apName));
239-
json_obj_get_string(&jctx, (char*)"ap_pass", apPass, sizeof(apPass));
242+
json_obj_get_string(&jctx, (char*)"ap_pass", dbuf, sizeof(dbuf));
243+
urlDecode(apPass, dbuf, sizeof(dbuf));
240244
if(json_obj_get_int(&jctx, (char*)"ap_channel", &ap_channel) != OS_SUCCESS)
241245
ap_channel = 1;
242246
if(json_obj_get_bool(&jctx, (char*)"ap_dhcp", &ap_dhcp) != OS_SUCCESS)
@@ -251,7 +255,8 @@ int CLAppConn::loadPrefs() {
251255

252256
// OTA
253257
json_obj_get_bool(&jctx, (char*)"ota_enabled", &otaEnabled);
254-
json_obj_get_string(&jctx, (char*)"ota_password", otaPassword, sizeof(otaPassword));
258+
json_obj_get_string(&jctx, (char*)"ota_password", dbuf, sizeof(dbuf));
259+
urlDecode(otaPassword, dbuf, sizeof(dbuf));
255260

256261
// NTP
257262
json_obj_get_string(&jctx, (char*)"ntp_server", ntpServer, sizeof(ntpServer));
@@ -305,23 +310,29 @@ int CLAppConn::savePrefs() {
305310
if(index < 0 && count == MAX_KNOWN_STATIONS) {
306311
count--;
307312
}
308-
313+
char ebuf[192];
314+
309315
if(index < 0 || count > 0) {
310316
json_gen_push_array(&jstr, "stations");
311317
if(index < 0) {
312318
json_gen_start_object(&jstr);
313319
json_gen_obj_set_string(&jstr, "ssid", ssid);
314-
json_gen_obj_set_string(&jstr, "pass", password);
320+
urlEncode(ebuf, password, sizeof(password));
321+
json_gen_obj_set_string(&jstr, "pass", ebuf);
315322
json_gen_end_object(&jstr);
316323
}
317324

318325
for(int i=0; i < count; i++) {
319326
json_gen_start_object(&jstr);
320327
json_gen_obj_set_string(&jstr, "ssid", stationList[i]->ssid);
321-
if(index >= 0 && i == index)
322-
json_gen_obj_set_string(&jstr, "pass", password);
323-
else
324-
json_gen_obj_set_string(&jstr, "pass", stationList[i]->password);
328+
if(index >= 0 && i == index) {
329+
urlEncode(ebuf, password, sizeof(password));
330+
json_gen_obj_set_string(&jstr, "pass", ebuf);
331+
}
332+
else {
333+
urlEncode(ebuf, stationList[i]->password, sizeof(stationList[i]->password));
334+
json_gen_obj_set_string(&jstr, "pass", ebuf);
335+
}
325336
json_gen_end_object(&jstr);
326337
}
327338
json_gen_pop_array(&jstr);
@@ -337,10 +348,13 @@ int CLAppConn::savePrefs() {
337348
json_gen_pop_object(&jstr);
338349
json_gen_obj_set_int(&jstr, "http_port", httpPort);
339350
json_gen_obj_set_bool(&jstr, "ota_enabled", otaEnabled);
340-
json_gen_obj_set_string(&jstr, "ota_password", otaPassword);
351+
urlEncode(ebuf, otaPassword, sizeof(otaPassword));
352+
Serial.println(ebuf);
353+
json_gen_obj_set_string(&jstr, "ota_password", ebuf);
341354

342355
json_gen_obj_set_string(&jstr, "ap_ssid", apName);
343-
json_gen_obj_set_string(&jstr, "ap_pass", apPass);
356+
urlEncode(ebuf, apPass, sizeof(apPass));
357+
json_gen_obj_set_string(&jstr, "ap_pass", ebuf);
344358
json_gen_obj_set_bool(&jstr, "ap_dhcp", ap_dhcp);
345359
json_gen_push_object(&jstr, "ap_ip");
346360
if(apIP.ip) json_gen_obj_set_string(&jstr, "ip", apIP.ip->toString().c_str());
@@ -483,5 +497,4 @@ int CLAppConn::getSSIDIndex() {
483497
return -1;
484498
}
485499

486-
487500
CLAppConn AppConn;

src/app_conn.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ class CLAppConn : public CLAppComponent {
9696
void updateTimeStr();
9797

9898
void printLocalTime(bool extraData=false);
99-
100-
99+
101100
private:
102101
int getSSIDIndex();
103102
void calcURLs();

0 commit comments

Comments
 (0)