Skip to content

Commit 29796e6

Browse files
committed
Add authentication type to Wifi
Add authentication type to Wifi so that the user can choose between open, WPA2 or WPA3 types when configuring the connection to a Wifi network.
1 parent b0ae903 commit 29796e6

10 files changed

Lines changed: 163 additions & 22 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"hostname":"mynixieclock","SSID":"","password":""}
1+
{"hostname":"mynixieclock","SSID":"", "auth_type":"open","password":""}

firmware/flash_data/frontend/index.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,23 @@ <h2>Wifi configuration</h2>
139139
<label for="ssid">SSID:</label>
140140
<input type="text" name="ssid" id="ssid" value="" />
141141
</div>
142+
<div class="field-container">
143+
<label for="authType">Authentication type:</label>
144+
<div class="choice-container">
145+
<div class="choice" onclick="handleAtuhTypeChoice(event)" name="authTypeChoice" value="open">
146+
<input id="authTypeOpen" type="radio" />
147+
<label for="authTypeOpen">Open</label>
148+
</div>
149+
<div class="choice" onclick="handleAtuhTypeChoice(event)" name="authTypeChoice" value="wpa2">
150+
<input id="authTypeWpa2" type="radio" />
151+
<label for="authTypeWpa2">WPA2</label>
152+
</div>
153+
<div class="choice" onclick="handleAtuhTypeChoice(event)" name="authTypeChoice" value="wpa3">
154+
<input id="authTypeWpa3" type="radio" />
155+
<label for="authTypeWpa3">WPA3</label>
156+
</div>
157+
</div>
158+
</div>
142159
<div class="field-container">
143160
<label for="password">Password:</label>
144161
<input type="password" name="password" id="password" value="" />

firmware/flash_data/frontend/server.js

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,23 @@ class LedInfo {
8181
}
8282

8383
class WifiInfo {
84-
constructor(hostname, ssid, password) {
84+
constructor(hostname, ssid, authType, password) {
8585
this.hostname = hostname
8686
this.ssid = ssid;
87+
this.authType = authType;
8788
this.password = password;
8889
}
8990
toJson() {
9091
return {
9192
"hostname": this.hostname,
9293
"SSID": this.ssid,
94+
"auth_type": this.authType,
9395
"password": this.password,
9496
};
9597
}
9698
static Builder = class {
9799
fromJson(message) {
98-
return new WifiInfo(message.hostname, message.SSID, atob(message.password));
100+
return new WifiInfo(message.hostname, message.SSID, message.auth_type, atob(message.password));
99101
}
100102
}
101103
}
@@ -348,6 +350,15 @@ function getWifiInfo() {
348350
let wifiInfo = new WifiInfo.Builder().fromJson(data);
349351
document.getElementById("hostname").value = wifiInfo.hostname;
350352
document.getElementById("ssid").value = wifiInfo.ssid;
353+
selectRadioChoiceByName("authTypeChoice", wifiInfo.authType);
354+
if (wifiInfo.authType == "open") {
355+
wifiInfo.password = "";
356+
document.getElementById("password").disabled = true;
357+
document.getElementById("passwordVerify").disabled = true;
358+
} else {
359+
document.getElementById("password").disabled = false;
360+
document.getElementById("passwordVerify").disabled = false;
361+
}
351362
document.getElementById("password").value = wifiInfo.password;
352363
document.getElementById("passwordVerify").value = wifiInfo.password;
353364
})
@@ -371,22 +382,31 @@ function setWifiInfo() {
371382
logLabel.style.color = errorColor;
372383
return;
373384
}
374-
if (document.getElementById("password").value == "") {
375-
console.log("Wifi password cannot be empty");
376-
logLabel.innerHTML = "Error: Wifi password cannot be empty";
377-
logLabel.style.color = errorColor;
378-
return;
379-
}
380-
if (document.getElementById("password").value != document.getElementById("passwordVerify").value) {
381-
console.log("Wifi passwords are not matching");
382-
logLabel.innerHTML = "Error: Passwords are not matching";
383-
logLabel.style.color = errorColor;
384-
return;
385+
if (getSelectedRadioChoice("authTypeChoice") != "open") {
386+
if (document.getElementById("password").value == "") {
387+
console.log("Wifi password cannot be empty");
388+
logLabel.innerHTML = "Error: Wifi password cannot be empty";
389+
logLabel.style.color = errorColor;
390+
return;
391+
}
392+
if (document.getElementById("password").value.length < 8) {
393+
console.log("Use at least 8 characters for password");
394+
logLabel.innerHTML = "Error: Use at least 8 characters for password";
395+
logLabel.style.color = errorColor;
396+
return;
397+
}
398+
if (document.getElementById("password").value != document.getElementById("passwordVerify").value) {
399+
console.log("Wifi passwords are not matching");
400+
logLabel.innerHTML = "Error: Passwords are not matching";
401+
logLabel.style.color = errorColor;
402+
return;
403+
}
385404
}
386405
logLabel.innerHTML = "";
387406
let wifiInfo = new WifiInfo(
388407
document.getElementById("hostname").value,
389408
document.getElementById("ssid").value,
409+
getSelectedRadioChoice("authTypeChoice"),
390410
btoa(document.getElementById("password").value));
391411
const requestOptions = {
392412
method: 'POST',
@@ -411,7 +431,9 @@ function selectRadioChoiceByName(name, value) {
411431
for (i = 0; i < choices.length; i++) {
412432
if (choices[i].getAttribute("value") == value) {
413433
choices[i].className += " active";
414-
break;
434+
} else {
435+
// clear if any choice was active previously
436+
choices[i].className = choices[i].className.replace(" active", "");
415437
}
416438
}
417439
}
@@ -458,4 +480,16 @@ function updateColorBox() {
458480
hsv.v = document.getElementById("sliderValue").value;
459481
let color = "hsla(" + hsv.h + "," + hsv.s + "%," + "50%," + hsv.v + "%)";
460482
document.getElementById("colorBox").style.backgroundColor = color;
483+
}
484+
485+
function handleAtuhTypeChoice(evt) {
486+
if (selectRadioChoiceByEvent(evt) == "open") {
487+
document.getElementById("password").disabled = true;
488+
document.getElementById("password").value = "";
489+
document.getElementById("passwordVerify").disabled = true;
490+
document.getElementById("passwordVerify").value = "";
491+
} else {
492+
document.getElementById("password").disabled = false;
493+
document.getElementById("passwordVerify").disabled = false;
494+
}
461495
}

firmware/flash_data/frontend/style.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ input[type="password"] {
142142
border-radius: .5em;
143143
}
144144

145-
input[type="text"]:disabled {
145+
input[type="text"]:disabled,
146+
input[type="password"]:disabled {
146147
background-color: #f6f6f6;
147148
font-weight: bold;
148149
width: 69%;

firmware/main/config_store.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ std::optional<WifiInfo> ConfigStore::loadWifiInfo() {
222222
cJSON_Delete(json);
223223
return std::nullopt;
224224
}
225+
if (!cJSON_GetObjectItemCaseSensitive(json, "auth_type")) {
226+
ESP_LOGW(kTag, "'auth_type' is not found in config");
227+
cJSON_Delete(json);
228+
return std::nullopt;
229+
}
225230
if (!cJSON_GetObjectItemCaseSensitive(json, "password")) {
226231
ESP_LOGW(kTag, "'password' is not found in config");
227232
cJSON_Delete(json);
@@ -233,6 +238,19 @@ std::optional<WifiInfo> ConfigStore::loadWifiInfo() {
233238
cJSON_GetObjectItemCaseSensitive(json, "hostname")->valuestring);
234239
wifiInfo.setSSID(
235240
cJSON_GetObjectItemCaseSensitive(json, "SSID")->valuestring);
241+
std::string authType =
242+
cJSON_GetObjectItemCaseSensitive(json, "auth_type")->valuestring;
243+
if (authType == "open") {
244+
wifiInfo.setAuthType(WifiAuthType::Open);
245+
} else if (authType == "wpa2") {
246+
wifiInfo.setAuthType(WifiAuthType::WPA2);
247+
} else if (authType == "wpa3") {
248+
wifiInfo.setAuthType(WifiAuthType::WPA3);
249+
} else {
250+
ESP_LOGW(kTag, "Invalid 'auth_format'");
251+
cJSON_Delete(json);
252+
return std::nullopt;
253+
}
236254
wifiInfo.setPassword(
237255
cJSON_GetObjectItemCaseSensitive(json, "password")->valuestring);
238256
cJSON_Delete(json);
@@ -251,6 +269,9 @@ bool ConfigStore::saveWifiInfo(const WifiInfo& wifiInfo) {
251269
cJSON_CreateString(wifiInfo.getHostname().c_str()));
252270
cJSON_AddItemToObject(json, "SSID",
253271
cJSON_CreateString(wifiInfo.getSSID().c_str()));
272+
cJSON_AddItemToObject(
273+
json, "auth_type",
274+
cJSON_CreateString(wifiAuthTypeToString(wifiInfo.getAuthType())));
254275
cJSON_AddItemToObject(json, "password",
255276
cJSON_CreateString(wifiInfo.getPassword().c_str()));
256277
char* jsonString = cJSON_Print(json);

firmware/main/include/wifi_info.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,28 @@
1111
#include <inttypes.h>
1212
#include <string>
1313

14+
/**
15+
* @brief An enumeration representing wifi authentication types
16+
*/
17+
enum class WifiAuthType { Open, WPA2, WPA3 };
18+
19+
/**
20+
* @brief Convert wifi authentication type to c-style string
21+
* @param[in] waf wifi authentication type
22+
*/
23+
constexpr const char* wifiAuthTypeToString(WifiAuthType waf) {
24+
switch (waf) {
25+
case WifiAuthType::Open:
26+
return "open";
27+
case WifiAuthType::WPA2:
28+
return "wpa2";
29+
case WifiAuthType::WPA3:
30+
return "wpa3";
31+
default:
32+
return "unknown";
33+
}
34+
}
35+
1436
/**
1537
* @brief Represents a Wifi info class
1638
*
@@ -30,7 +52,7 @@ class WifiInfo {
3052
* @param password password
3153
*/
3254
WifiInfo(const std::string& hostname, const std::string& ssid,
33-
const std::string& password);
55+
const WifiAuthType& authType, const std::string& password);
3456

3557
/**
3658
* @brief Default destructor
@@ -77,6 +99,20 @@ class WifiInfo {
7799
*/
78100
void setSSID(const std::string& value);
79101

102+
/**
103+
* @brief Getter for Wifi authentication type
104+
*
105+
* @return Wifi authentication type
106+
*/
107+
WifiAuthType getAuthType() const;
108+
109+
/**
110+
* @brief Setter for Wifi authentication type
111+
*
112+
* @param value Wifi authentication type
113+
*/
114+
void setAuthType(const WifiAuthType& value);
115+
80116
/**
81117
* @brief Getter for password
82118
*
@@ -94,6 +130,7 @@ class WifiInfo {
94130
private:
95131
std::string mHostname;
96132
std::string mSsid;
133+
WifiAuthType mAuthType;
97134
std::string mPassword;
98135
};
99136

firmware/main/nixie_clock.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void NixieClock::initialize() {
6969
ESP_LOGI(kTag, "Initialize Wifi... done");
7070

7171
if (wifiInfo.getSSID() == "" || !mWifiManager.connectSta(wifiInfo)) {
72-
WifiInfo apWifiInfo(kApHostname, kApSsid, "");
72+
WifiInfo apWifiInfo(kApHostname, kApSsid, WifiAuthType::Open, "");
7373
mWifiManager.startAp(apWifiInfo);
7474
ESP_LOGI(kTag, "Setup captive portal...");
7575
setupCaptivePortal();

firmware/main/web_server.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,10 @@ esp_err_t WebServer::handleGetWifiInfo(httpd_req_t* req) {
334334
cJSON* root = cJSON_CreateObject();
335335
cJSON_AddStringToObject(root, "hostname", wifiInfo.getHostname().c_str());
336336
cJSON_AddStringToObject(root, "SSID", wifiInfo.getSSID().c_str());
337-
cJSON_AddStringToObject(root, "password", wifiInfo.getPassword().c_str());
337+
cJSON_AddStringToObject(root, "auth_type",
338+
wifiAuthTypeToString(wifiInfo.getAuthType()));
339+
// do not share the actual password
340+
cJSON_AddStringToObject(root, "password", "");
338341
char* jsonStr = cJSON_Print(root);
339342
httpd_resp_sendstr(req, jsonStr);
340343
free(static_cast<void*>(jsonStr));
@@ -367,6 +370,19 @@ esp_err_t WebServer::handleSetWifiInfo(httpd_req_t* req) {
367370
WifiInfo wifiInfo;
368371
wifiInfo.setHostname(cJSON_GetObjectItem(root, "hostname")->valuestring);
369372
wifiInfo.setSSID(cJSON_GetObjectItem(root, "SSID")->valuestring);
373+
std::string authType =
374+
cJSON_GetObjectItemCaseSensitive(root, "auth_type")->valuestring;
375+
if (authType == "open") {
376+
wifiInfo.setAuthType(WifiAuthType::Open);
377+
} else if (authType == "wpa2") {
378+
wifiInfo.setAuthType(WifiAuthType::WPA2);
379+
} else if (authType == "wpa3") {
380+
wifiInfo.setAuthType(WifiAuthType::WPA3);
381+
} else {
382+
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
383+
"Unknown wifi authentication type");
384+
return ESP_FAIL;
385+
}
370386
wifiInfo.setPassword(cJSON_GetObjectItem(root, "password")->valuestring);
371387
callback->onSetWifiInfo(wifiInfo);
372388
cJSON_Delete(root);

firmware/main/wifi_info.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
#include "wifi_info.h"
99

1010
WifiInfo::WifiInfo(const std::string& hostname, const std::string& ssid,
11-
const std::string& password)
12-
: mHostname(hostname), mSsid(ssid), mPassword(password) {}
11+
const WifiAuthType& authType, const std::string& password)
12+
: mHostname(hostname), mSsid(ssid), mAuthType(authType),
13+
mPassword(password) {}
1314

1415
std::string WifiInfo::getHostname() const { return mHostname; }
1516

@@ -19,6 +20,10 @@ std::string WifiInfo::getSSID() const { return mSsid; }
1920

2021
void WifiInfo::setSSID(const std::string& value) { mSsid = value; }
2122

23+
WifiAuthType WifiInfo::getAuthType() const { return mAuthType; }
24+
25+
void WifiInfo::setAuthType(const WifiAuthType& value) { mAuthType = value; }
26+
2227
std::string WifiInfo::getPassword() const { return mPassword; }
2328

2429
void WifiInfo::setPassword(const std::string& value) { mPassword = value; }

firmware/main/wifi_manager.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,17 @@ bool WifiManager::connectSta(const WifiInfo& wifiInfo) {
9292
std::strncpy(reinterpret_cast<char*>(wifiConfig.sta.password),
9393
reinterpret_cast<char*>(password),
9494
sizeof(wifiConfig.sta.password));
95-
wifiConfig.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
95+
switch (wifiInfo.getAuthType()) {
96+
case WifiAuthType::Open:
97+
wifiConfig.sta.threshold.authmode = WIFI_AUTH_OPEN;
98+
break;
99+
case WifiAuthType::WPA2:
100+
wifiConfig.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
101+
break;
102+
case WifiAuthType::WPA3:
103+
wifiConfig.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK;
104+
break;
105+
}
96106
wifiConfig.sta.pmf_cfg.capable = true;
97107
wifiConfig.sta.pmf_cfg.required = false;
98108

0 commit comments

Comments
 (0)