Remove json routes, utils and javascript #65
|
@ -4,11 +4,11 @@
|
||||||
|
|
||||||
## Web Interface for PeachCloud
|
## Web Interface for PeachCloud
|
||||||
|
|
||||||
**peach-web** provides a web interface for the PeachCloud device. It serves static assets and exposes a JSON API for programmatic interactions.
|
**peach-web** provides a web interface for the PeachCloud device.
|
||||||
|
|
||||||
Initial development is focused on administration of the device itself, beginning with networking functionality, with SSB-related administration to be integrated at a later stage.
|
Initial development is focused on administration of the device itself, beginning with networking functionality, with SSB-related administration to be integrated at a later stage.
|
||||||
|
|
||||||
The peach-web stack currently consists of [Rocket](https://rocket.rs/) (Rust web framework), [Tera](http://tera.netlify.com/) (Rust template engine), HTML, CSS and JavaScript.
|
The peach-web stack currently consists of [Rocket](https://rocket.rs/) (Rust web framework), [Tera](http://tera.netlify.com/) (Rust template engine), HTML and CSS.
|
||||||
|
|
||||||
_Note: This is a work-in-progress._
|
_Note: This is a work-in-progress._
|
||||||
|
|
||||||
|
@ -95,13 +95,13 @@ Remove configuration files (not removed with `apt-get remove`):
|
||||||
|
|
||||||
### Design
|
### Design
|
||||||
|
|
||||||
`peach-web` is built on the Rocket webserver and Tera templating engine. It presents a web interface for interacting with the device. HTML is rendered server-side. Request handlers call JSON-RPC microservices and serve HTML and assets. A JSON API is exposed for remote calls and dynamic client-side content updates (via plain JavaScript following unobstructive design principles). Each Tera template is passed a context object. In the case of Rust, this object is a `struct` and must implement `Serialize`. The fields of the context object are available in the context of the template to be rendered.
|
`peach-web` is built on the Rocket webserver and Tera templating engine. It presents a web interface for interacting with the device. HTML is rendered server-side. Request handlers call `peach-` libraries and serve HTML and assets. Each Tera template is passed a context object. In the case of Rust, this object is a `struct` and must implement `Serialize`. The fields of the context object are available in the context of the template to be rendered.
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
Configuration variables are stored in /var/lib/peachcloud/config.yml.
|
Configuration variables are stored in /var/lib/peachcloud/config.yml.
|
||||||
Peach-web also updates this file when changes are made to configurations via
|
Peach-web also updates this file when changes are made to configurations via
|
||||||
the web interface. peach-web has no database, so all configurations are stored in this file.
|
the web interface. peach-web has no database, so all configurations are stored in this file.
|
||||||
|
|
||||||
#### Dynamic DNS Configuration
|
#### Dynamic DNS Configuration
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ use crate::routes::index::*;
|
||||||
use crate::routes::scuttlebutt::*;
|
use crate::routes::scuttlebutt::*;
|
||||||
use crate::routes::status::device::*;
|
use crate::routes::status::device::*;
|
||||||
use crate::routes::status::network::*;
|
use crate::routes::status::network::*;
|
||||||
use crate::routes::status::ping::*;
|
|
||||||
|
|
||||||
use crate::routes::settings::admin::*;
|
use crate::routes::settings::admin::*;
|
||||||
use crate::routes::settings::dns::*;
|
use crate::routes::settings::dns::*;
|
||||||
|
@ -123,43 +122,6 @@ fn init_rocket() -> Rocket<Build> {
|
||||||
block, publish,
|
block, publish,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
// GENERAL JSON API ROUTES
|
|
||||||
.mount(
|
|
||||||
"/api/v1",
|
|
||||||
routes![ping_pong, ping_network, ping_oled, ping_stats,],
|
|
||||||
)
|
|
||||||
// ADMIN JSON API ROUTES
|
|
||||||
.mount(
|
|
||||||
"/api/v1/admin",
|
|
||||||
routes![
|
|
||||||
save_password_form_endpoint,
|
|
||||||
reset_password_form_endpoint,
|
|
||||||
reboot_device,
|
|
||||||
shutdown_device,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
// NETWORK JSON API ROUTES
|
|
||||||
.mount(
|
|
||||||
"/api/v1/network",
|
|
||||||
routes![
|
|
||||||
activate_ap,
|
|
||||||
activate_client,
|
|
||||||
add_wifi_credentials,
|
|
||||||
connect_ap,
|
|
||||||
disconnect_ap,
|
|
||||||
forget_ap,
|
|
||||||
modify_password,
|
|
||||||
reset_data_total,
|
|
||||||
return_ip,
|
|
||||||
return_rssi,
|
|
||||||
return_ssid,
|
|
||||||
return_state,
|
|
||||||
return_status,
|
|
||||||
scan_networks,
|
|
||||||
update_wifi_alerts,
|
|
||||||
save_dns_configuration_endpoint,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.mount("/", FileServer::from("static"))
|
.mount("/", FileServer::from("static"))
|
||||||
.register("/", catchers![not_found, internal_error, forbidden])
|
.register("/", catchers![not_found, internal_error, forbidden])
|
||||||
.attach(Template::fairing())
|
.attach(Template::fairing())
|
||||||
|
|
|
@ -3,10 +3,7 @@ use rocket::form::{Form, FromForm};
|
||||||
use rocket::http::{Cookie, CookieJar, Status};
|
use rocket::http::{Cookie, CookieJar, Status};
|
||||||
use rocket::request::{self, FlashMessage, FromRequest, Request};
|
use rocket::request::{self, FlashMessage, FromRequest, Request};
|
||||||
use rocket::response::{Flash, Redirect};
|
use rocket::response::{Flash, Redirect};
|
||||||
use rocket::serde::{
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
json::{Json, Value},
|
|
||||||
Deserialize, Serialize,
|
|
||||||
};
|
|
||||||
use rocket::{get, post, Config};
|
use rocket::{get, post, Config};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
@ -14,7 +11,7 @@ use peach_lib::error::PeachError;
|
||||||
use peach_lib::password_utils;
|
use peach_lib::password_utils;
|
||||||
|
|
||||||
use crate::error::PeachWebError;
|
use crate::error::PeachWebError;
|
||||||
use crate::utils::{build_json_response, TemplateOrRedirect};
|
use crate::utils::TemplateOrRedirect;
|
||||||
|
|
||||||
// HELPERS AND STRUCTS FOR AUTHENTICATION WITH COOKIES
|
// HELPERS AND STRUCTS FOR AUTHENTICATION WITH COOKIES
|
||||||
|
|
||||||
|
@ -260,25 +257,6 @@ pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Temp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON password reset form request handler. This route is used by a user who is not logged in
|
|
||||||
/// and is specifically for users who have forgotten their password.
|
|
||||||
#[post("/reset_password", data = "<reset_password_form>")]
|
|
||||||
pub fn reset_password_form_endpoint(reset_password_form: Json<ResetPasswordForm>) -> Value {
|
|
||||||
let result = save_reset_password_form(reset_password_form.into_inner());
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "New password is now saved. Return home to login.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = format!("{}", err);
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /send_password_reset
|
// HELPERS AND ROUTES FOR /send_password_reset
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
@ -414,24 +392,3 @@ pub fn change_password_post(password_form: Form<PasswordForm>, _auth: Authentica
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON change password form request handler.
|
|
||||||
#[post("/change_password", data = "<password_form>")]
|
|
||||||
pub fn save_password_form_endpoint(
|
|
||||||
password_form: Json<PasswordForm>,
|
|
||||||
_auth: Authenticated,
|
|
||||||
) -> Value {
|
|
||||||
let result = save_password_form(password_form.into_inner());
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Your password was successfully changed".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = format!("{}", err);
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,10 +3,7 @@ use rocket::{
|
||||||
form::{Form, FromForm},
|
form::{Form, FromForm},
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
serde::{
|
serde::{Deserialize, Serialize},
|
||||||
json::{Json, Value},
|
|
||||||
Deserialize, Serialize,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
@ -23,7 +20,6 @@ use peach_lib::jsonrpc_core::types::error::ErrorCode;
|
||||||
|
|
||||||
use crate::error::PeachWebError;
|
use crate::error::PeachWebError;
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
use crate::utils::build_json_response;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, FromForm)]
|
#[derive(Debug, Deserialize, FromForm)]
|
||||||
pub struct DnsForm {
|
pub struct DnsForm {
|
||||||
|
@ -153,20 +149,3 @@ pub fn configure_dns_post(dns: Form<DnsForm>, _auth: Authenticated) -> Template
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/dns/configure", data = "<dns_form>")]
|
|
||||||
pub fn save_dns_configuration_endpoint(dns_form: Json<DnsForm>, _auth: Authenticated) -> Value {
|
|
||||||
let result = save_dns_configuration(dns_form.into_inner());
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "New dynamic dns configuration is now enabled".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = format!("{}", err);
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,10 +5,7 @@ use rocket::{
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
serde::{
|
serde::{Deserialize, Serialize},
|
||||||
json::{json, Json, Value},
|
|
||||||
Deserialize, Serialize,
|
|
||||||
},
|
|
||||||
uri, UriDisplayQuery,
|
uri, UriDisplayQuery,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
@ -19,7 +16,6 @@ use peach_lib::network_client::{AccessPoint, Networks, Scan};
|
||||||
use peach_lib::stats_client::Traffic;
|
use peach_lib::stats_client::Traffic;
|
||||||
|
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
use crate::utils::build_json_response;
|
|
||||||
use crate::utils::monitor;
|
use crate::utils::monitor;
|
||||||
use crate::utils::monitor::{Alert, Data, Threshold};
|
use crate::utils::monitor::{Alert, Data, Threshold};
|
||||||
|
|
||||||
|
@ -760,311 +756,3 @@ pub fn wifi_usage_alerts(thresholds: Form<Threshold>, _auth: Authenticated) -> F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON ROUTES FOR NETWORK SETTINGS
|
|
||||||
|
|
||||||
#[post("/wifi/usage", data = "<thresholds>")]
|
|
||||||
pub fn update_wifi_alerts(thresholds: Json<Threshold>, _auth: Authenticated) -> Value {
|
|
||||||
match monitor::update_store(thresholds.into_inner()) {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("WiFi data usage thresholds updated.");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Updated alert threshold and flags.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Failed to update WiFi data usage thresholds.");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to update WiFi data usage thresholds.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/usage/reset")]
|
|
||||||
pub fn reset_data_total(_auth: Authenticated) -> Value {
|
|
||||||
match monitor::reset_data() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("Reset network data usage total.");
|
|
||||||
let traffic = match network_client::traffic("wlan0") {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(_) => Traffic {
|
|
||||||
received: 0,
|
|
||||||
transmitted: 0,
|
|
||||||
rx_unit: None,
|
|
||||||
tx_unit: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// current wifi traffic values as bytes
|
|
||||||
let current_traffic = traffic.received + traffic.transmitted;
|
|
||||||
let data = json!(current_traffic);
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Reset network data usage total.".to_string();
|
|
||||||
build_json_response(status, Some(data), Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Failed to reset network data usage total.");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to reset network data usage total.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR ACCESS POINT ACTIVATION
|
|
||||||
|
|
||||||
#[post("/activate_ap")]
|
|
||||||
pub fn activate_ap(_auth: Authenticated) -> Value {
|
|
||||||
// activate the wireless access point
|
|
||||||
debug!("Activating WiFi access point.");
|
|
||||||
match network_client::activate_ap() {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
build_json_response(status, None, None)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to activate WiFi access point.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR WIFI CLIENT MANAGEMENT
|
|
||||||
|
|
||||||
#[post("/activate_client")]
|
|
||||||
pub fn activate_client(_auth: Authenticated) -> Value {
|
|
||||||
// activate the wireless client
|
|
||||||
debug!("Activating WiFi client mode.");
|
|
||||||
match network_client::activate_client() {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
build_json_response(status, None, None)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to activate WiFi client mode.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi", data = "<wifi>")]
|
|
||||||
pub fn add_wifi_credentials(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
|
||||||
// generate and write wifi config to wpa_supplicant
|
|
||||||
match network_client::add(&wifi.ssid, &wifi.pass) {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("Added WiFi credentials.");
|
|
||||||
// force reread of wpa_supplicant.conf file with new credentials
|
|
||||||
match network_client::reconfigure() {
|
|
||||||
Ok(_) => debug!("Successfully reconfigured wpa_supplicant."),
|
|
||||||
Err(_) => warn!("Failed to reconfigure wpa_supplicant."),
|
|
||||||
}
|
|
||||||
// json response for successful update
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "WiFi credentials added.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
debug!("Failed to add WiFi credentials.");
|
|
||||||
// json response for failed update
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to add WiFi credentials.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/connect", data = "<ssid>")]
|
|
||||||
pub fn connect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
|
||||||
// retrieve the id for the given network ssid
|
|
||||||
match network_client::id("wlan0", &ssid.ssid) {
|
|
||||||
// attempt connection with the given network
|
|
||||||
Ok(id) => match network_client::connect(&id, "wlan0") {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Connected to chosen network.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to connect to chosen network.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(_) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to retrieve the network ID.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/disconnect", data = "<ssid>")]
|
|
||||||
pub fn disconnect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
|
||||||
// attempt to disable the current network for wlan0 interface
|
|
||||||
match network_client::disable("wlan0", &ssid.ssid) {
|
|
||||||
Ok(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Disconnected from WiFi network.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to disconnect from WiFi network.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/forget", data = "<network>")]
|
|
||||||
pub fn forget_ap(network: Json<Ssid>, _auth: Authenticated) -> Value {
|
|
||||||
let ssid = &network.ssid;
|
|
||||||
match network_client::forget("wlan0", ssid) {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("Removed WiFi credentials for chosen network.");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "WiFi network credentials removed.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Failed to remove WiFi credentials.");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to remove WiFi network credentials.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/modify", data = "<wifi>")]
|
|
||||||
pub fn modify_password(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
|
||||||
let ssid = &wifi.ssid;
|
|
||||||
let pass = &wifi.pass;
|
|
||||||
// we are using a helper function (`update`) to delete the old
|
|
||||||
// credentials and add the new ones. this is because the wpa_cli method
|
|
||||||
// for updating the password does not work.
|
|
||||||
match network_client::update("wlan0", ssid, pass) {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("WiFi password updated for chosen network.");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "WiFi password updated.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Failed to update WiFi password.");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to update WiFi password.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR NETWORK STATE QUERIES
|
|
||||||
|
|
||||||
#[get("/ip")]
|
|
||||||
pub fn return_ip(_auth: Authenticated) -> Value {
|
|
||||||
// retrieve ip for wlan0 or set to x.x.x.x if not found
|
|
||||||
let wlan_ip = match network_client::ip("wlan0") {
|
|
||||||
Ok(ip) => ip,
|
|
||||||
Err(_) => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
// retrieve ip for ap0 or set to x.x.x.x if not found
|
|
||||||
let ap_ip = match network_client::ip("ap0") {
|
|
||||||
Ok(ip) => ip,
|
|
||||||
Err(_) => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
let data = json!({
|
|
||||||
"wlan0": wlan_ip,
|
|
||||||
"ap0": ap_ip
|
|
||||||
});
|
|
||||||
let status = "success".to_string();
|
|
||||||
build_json_response(status, Some(data), None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/rssi")]
|
|
||||||
pub fn return_rssi(_auth: Authenticated) -> Value {
|
|
||||||
// retrieve rssi for connected network
|
|
||||||
match network_client::rssi("wlan0") {
|
|
||||||
Ok(rssi) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let data = json!(rssi);
|
|
||||||
build_json_response(status, Some(data), None)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Not currently connected to an access point.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/ssid")]
|
|
||||||
pub fn return_ssid(_auth: Authenticated) -> Value {
|
|
||||||
// retrieve ssid for connected network
|
|
||||||
match network_client::ssid("wlan0") {
|
|
||||||
Ok(network) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let data = json!(network);
|
|
||||||
build_json_response(status, Some(data), None)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Not currently connected to an access point.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/state")]
|
|
||||||
pub fn return_state(_auth: Authenticated) -> Value {
|
|
||||||
// retrieve state of wlan0 or set to x.x.x.x if not found
|
|
||||||
let wlan_state = match network_client::state("wlan0") {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(_) => "unavailable".to_string(),
|
|
||||||
};
|
|
||||||
// retrieve state for ap0 or set to x.x.x.x if not found
|
|
||||||
let ap_state = match network_client::state("ap0") {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(_) => "unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let data = json!({
|
|
||||||
"wlan0": wlan_state,
|
|
||||||
"ap0": ap_state
|
|
||||||
});
|
|
||||||
let status = "success".to_string();
|
|
||||||
build_json_response(status, Some(data), None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/status")]
|
|
||||||
pub fn return_status(_auth: Authenticated) -> Value {
|
|
||||||
// retrieve status info for wlan0 interface
|
|
||||||
match network_client::status("wlan0") {
|
|
||||||
Ok(network) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let data = json!(network);
|
|
||||||
build_json_response(status, Some(data), None)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Not currently connected to an access point.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/wifi")]
|
|
||||||
pub fn scan_networks(_auth: Authenticated) -> Value {
|
|
||||||
// retrieve scan results for access-points within range of wlan0
|
|
||||||
match network_client::available_networks("wlan0") {
|
|
||||||
Ok(networks) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let data = json!(networks);
|
|
||||||
build_json_response(status, Some(data), None)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Unable to scan for networks. Interface may be deactivated.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use log::{debug, info, warn};
|
use log::info;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
get, post,
|
get,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
serde::json::Value,
|
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -21,7 +20,6 @@ use peach_stats::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
use crate::utils::build_json_response;
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /status
|
// HELPERS AND ROUTES FOR /status
|
||||||
|
|
||||||
|
@ -189,25 +187,6 @@ pub fn reboot_cmd(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON request handler for device reboot.
|
|
||||||
#[post("/api/v1/admin/reboot")]
|
|
||||||
pub fn reboot_device(_auth: Authenticated) -> Value {
|
|
||||||
match reboot() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("Going down for reboot...");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Going down for reboot.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Reboot failed");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to reboot the device.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /power/shutdown
|
// HELPERS AND ROUTES FOR /power/shutdown
|
||||||
|
|
||||||
/// Executes a system command to shutdown the device immediately.
|
/// Executes a system command to shutdown the device immediately.
|
||||||
|
@ -227,25 +206,6 @@ pub fn shutdown_cmd(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown the device
|
|
||||||
#[post("/power/shutdown")]
|
|
||||||
pub fn shutdown_device(_auth: Authenticated) -> Value {
|
|
||||||
match shutdown() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("Going down for shutdown...");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "Going down for shutdown.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Shutdown failed");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "Failed to shutdown the device.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /power
|
// HELPERS AND ROUTES FOR /power
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod device;
|
pub mod device;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod ping;
|
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
//! Helper routes for pinging services to check that they are active
|
|
||||||
use log::{debug, warn};
|
|
||||||
use rocket::get;
|
|
||||||
use rocket::serde::json::Value;
|
|
||||||
|
|
||||||
use peach_lib::network_client;
|
|
||||||
use peach_lib::oled_client;
|
|
||||||
use peach_lib::stats_client;
|
|
||||||
|
|
||||||
use crate::routes::authentication::Authenticated;
|
|
||||||
use crate::utils::build_json_response;
|
|
||||||
|
|
||||||
/// Status route: useful for checking connectivity from web client.
|
|
||||||
#[get("/ping")]
|
|
||||||
pub fn ping_pong(_auth: Authenticated) -> Value {
|
|
||||||
//pub fn ping_pong() -> Value {
|
|
||||||
// ping pong
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "pong!".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Status route: check availability of `peach-network` microservice.
|
|
||||||
#[get("/ping/network")]
|
|
||||||
pub fn ping_network(_auth: Authenticated) -> Value {
|
|
||||||
match network_client::ping() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("peach-network responded successfully");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "peach-network is available.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("peach-network failed to respond");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "peach-network is unavailable.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Status route: check availability of `peach-oled` microservice.
|
|
||||||
#[get("/ping/oled")]
|
|
||||||
pub fn ping_oled(_auth: Authenticated) -> Value {
|
|
||||||
match oled_client::ping() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("peach-oled responded successfully");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "peach-oled is available.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("peach-oled failed to respond");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "peach-oled is unavailable.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Status route: check availability of `peach-stats` microservice.
|
|
||||||
#[get("/ping/stats")]
|
|
||||||
pub fn ping_stats(_auth: Authenticated) -> Value {
|
|
||||||
match stats_client::ping() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("peach-stats responded successfully");
|
|
||||||
let status = "success".to_string();
|
|
||||||
let msg = "peach-stats is available.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("peach-stats failed to respond");
|
|
||||||
let status = "error".to_string();
|
|
||||||
let msg = "peach-stats is unavailable.".to_string();
|
|
||||||
build_json_response(status, None, Some(msg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,26 +3,16 @@ pub mod monitor;
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
use rocket::response::{Redirect, Responder};
|
use rocket::response::{Redirect, Responder};
|
||||||
use rocket::serde::json::{Value, json};
|
use rocket::serde::Serialize;
|
||||||
use rocket::serde::{Serialize};
|
|
||||||
|
|
||||||
// HELPER FUNCTIONS
|
// HELPER FUNCTIONS
|
||||||
|
|
||||||
pub fn build_json_response(
|
|
||||||
status: String,
|
|
||||||
data: Option<Value>,
|
|
||||||
msg: Option<String>,
|
|
||||||
) -> Value {
|
|
||||||
json!({ "status": status, "data": data, "msg": msg })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct FlashContext {
|
pub struct FlashContext {
|
||||||
pub flash_name: Option<String>,
|
pub flash_name: Option<String>,
|
||||||
pub flash_msg: Option<String>,
|
pub flash_msg: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A helper enum which allows routes to either return a Template or a Redirect
|
/// A helper enum which allows routes to either return a Template or a Redirect
|
||||||
/// from: https://github.com/SergioBenitez/Rocket/issues/253#issuecomment-532356066
|
/// from: https://github.com/SergioBenitez/Rocket/issues/253#issuecomment-532356066
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
@ -30,4 +20,4 @@ pub struct FlashContext {
|
||||||
pub enum TemplateOrRedirect {
|
pub enum TemplateOrRedirect {
|
||||||
Template(Template),
|
Template(Template),
|
||||||
Redirect(Redirect),
|
Redirect(Redirect),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `change_password.html.tera` template
|
|
||||||
|
|
||||||
- intercept button click for save (form submission of passwords)
|
|
||||||
- perform json api call
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_AUTH.changePassword();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_AUTH = {};
|
|
||||||
|
|
||||||
// catch click of 'Save' button and make POST request
|
|
||||||
PEACH_AUTH.changePassword = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.body.addEventListener('submit', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// capture form data
|
|
||||||
var formElement = document.querySelector("form");
|
|
||||||
// create form data object from the changePassword form element
|
|
||||||
var formData = new FormData(formElement);
|
|
||||||
var object = {};
|
|
||||||
// assign values from form
|
|
||||||
formData.forEach(function(value, key){
|
|
||||||
object[key] = value;
|
|
||||||
});
|
|
||||||
// perform json serialization
|
|
||||||
console.log(object);
|
|
||||||
var jsonData = JSON.stringify(object);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Saving new password.");
|
|
||||||
// send change_password POST request
|
|
||||||
fetch("/api/v1/admin/change_password", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var changePassInstance = PEACH_AUTH;
|
|
||||||
changePassInstance.changePassword();
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Common javascript functions shared by multiple pages:
|
|
||||||
* - flashMsg
|
|
||||||
* - logout
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH = {};
|
|
||||||
|
|
||||||
// display a message by appending a paragraph element
|
|
||||||
PEACH.flashMsg = function(status, msg) {
|
|
||||||
// set the class of the element according to status
|
|
||||||
var elementClass;
|
|
||||||
if (status === "success") {
|
|
||||||
elementClass = "capsule center-text flash-message font-success";
|
|
||||||
} else if (status === "info") {
|
|
||||||
elementClass = "capsule center-text flash-message font-info";
|
|
||||||
} else {
|
|
||||||
elementClass = "capsule center-text flash-message font-failure";
|
|
||||||
};
|
|
||||||
|
|
||||||
var flashElement = document.getElementById("flashMsg");
|
|
||||||
// if flashElement exists, update the class & text
|
|
||||||
if (flashElement) {
|
|
||||||
flashElement.className = elementClass;
|
|
||||||
flashElement.innerText = msg;
|
|
||||||
// if flashElement does not exist, create it, set id, class, text & append
|
|
||||||
} else {
|
|
||||||
// create new div for flash message
|
|
||||||
var flashDiv = document.createElement("DIV");
|
|
||||||
// set div attributes
|
|
||||||
flashDiv.id = "flashMsg";
|
|
||||||
flashDiv.className = elementClass;
|
|
||||||
// add json response message to flash message div
|
|
||||||
var flashMsg = document.createTextNode(msg);
|
|
||||||
flashDiv.appendChild(flashMsg);
|
|
||||||
// insert the flash message div below the button div
|
|
||||||
var buttonDiv = document.getElementById("buttonDiv");
|
|
||||||
// flashDiv will be added to the end since buttonDiv is the last
|
|
||||||
// child within the parent element (card-container div)
|
|
||||||
buttonDiv.parentNode.insertBefore(flashDiv, buttonDiv.nextSibling);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var commonInstance = PEACH;
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `configure_dns.html.tera` template,
|
|
||||||
corresponding to the web route `/settings/network/dns`
|
|
||||||
|
|
||||||
- intercept button click for save (form submission of dns settings)
|
|
||||||
- perform json api call
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_DNS = {};
|
|
||||||
|
|
||||||
// catch click of 'Add' button and make POST request
|
|
||||||
PEACH_DNS.configureDns = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.body.addEventListener('submit', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// capture form data
|
|
||||||
var formElement = document.querySelector("form");
|
|
||||||
// create form data object from the configureDNS form element
|
|
||||||
var formData = new FormData(formElement);
|
|
||||||
var object = {};
|
|
||||||
// set checkbox to false (the value is only passed to formData if it is "on")
|
|
||||||
object["enable_dyndns"] = false;
|
|
||||||
// assign values from form
|
|
||||||
formData.forEach(function(value, key){
|
|
||||||
// convert checkbox to bool
|
|
||||||
if (key === "enable_dyndns") {
|
|
||||||
value = (value === "on");
|
|
||||||
}
|
|
||||||
object[key] = value;
|
|
||||||
});
|
|
||||||
// perform json serialization
|
|
||||||
console.log(object);
|
|
||||||
var jsonData = JSON.stringify(object);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Saving new DNS configurations");
|
|
||||||
// send add_wifi POST request
|
|
||||||
fetch("/api/v1/network/dns/configure", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
let statusIndicator = document.getElementById("dyndns-status-indicator");
|
|
||||||
// only remove the "dyndns-status-indicator" element if it exists
|
|
||||||
if (statusIndicator != null ) statusIndicator.remove();
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var configureDnsInstance = PEACH_DNS;
|
|
||||||
configureDnsInstance.configureDns();
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `network_add.html.tera` template,
|
|
||||||
corresponding to the web route `/network/wifi/add`
|
|
||||||
|
|
||||||
- intercept button click for add (form submission of credentials)
|
|
||||||
- perform json api call
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_NETWORK.add();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_NETWORK = {};
|
|
||||||
|
|
||||||
// catch click of 'Add' button and make POST request
|
|
||||||
PEACH_NETWORK.add = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.body.addEventListener('submit', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// capture form data
|
|
||||||
var formElement = document.querySelector("form");
|
|
||||||
// create form data object from the wifiCreds form element
|
|
||||||
var formData = new FormData(formElement);
|
|
||||||
var object = {};
|
|
||||||
// assign ssid and pass from form
|
|
||||||
formData.forEach(function(value, key){
|
|
||||||
object[key] = value;
|
|
||||||
});
|
|
||||||
// perform json serialization
|
|
||||||
var jsonData = JSON.stringify(object);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Adding WiFi credentials...");
|
|
||||||
// send add_wifi POST request
|
|
||||||
fetch("/api/v1/network/wifi", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var addInstance = PEACH_NETWORK;
|
|
||||||
addInstance.add();
|
|
|
@ -1,133 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `network_card.html.tera` template,
|
|
||||||
corresponding to the web route `/settings/network`
|
|
||||||
|
|
||||||
- intercept form submissions
|
|
||||||
- perform json api calls
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_NETWORK.activateAp();
|
|
||||||
PEACH_NETWORK.activateClient();
|
|
||||||
PEACH_NETWORK.apMode();
|
|
||||||
PEACH_NETWORK.clientMode();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_NETWORK = {};
|
|
||||||
|
|
||||||
// catch click of 'Deploy Access Point' and make POST request
|
|
||||||
PEACH_NETWORK.activateAp = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var deployAP = document.getElementById('deployAccessPoint');
|
|
||||||
if (deployAP) {
|
|
||||||
deployAP.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Deploying access point...");
|
|
||||||
// send activate_ap POST request
|
|
||||||
fetch("/api/v1/network/activate_ap", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
console.log(jsonData.msg);
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
// if ap activation is successful, update the ui
|
|
||||||
if (jsonData.status === "success") {
|
|
||||||
PEACH_NETWORK.apMode();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// catch click of 'Enable WiFi' and make POST request
|
|
||||||
PEACH_NETWORK.activateClient = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var enableWifi = document.getElementById('connectWifi');
|
|
||||||
if (enableWifi) {
|
|
||||||
enableWifi.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Enabling WiFi client...");
|
|
||||||
// send activate_ap POST request
|
|
||||||
fetch("/api/v1/network/activate_client", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
console.log(jsonData.msg);
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
// if client activation is successful, update the ui
|
|
||||||
if (jsonData.status === "success") {
|
|
||||||
PEACH_NETWORK.clientMode();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace 'Deploy Access Point' button with 'Enable WiFi' button
|
|
||||||
PEACH_NETWORK.apMode = function() {
|
|
||||||
// create Enable WiFi button and add it to button div
|
|
||||||
var wifiButton = document.createElement("A");
|
|
||||||
wifiButton.className = "button center";
|
|
||||||
wifiButton.href = "/settings/network/wifi/activate";
|
|
||||||
wifiButton.id = "connectWifi";
|
|
||||||
var label = "Enable WiFi";
|
|
||||||
var buttonText = document.createTextNode(label);
|
|
||||||
wifiButton.appendChild(buttonText);
|
|
||||||
|
|
||||||
// append the new button to the buttons div
|
|
||||||
let buttons = document.getElementById("buttons");
|
|
||||||
buttons.appendChild(wifiButton);
|
|
||||||
|
|
||||||
// remove the old 'Deploy Access Point' button
|
|
||||||
let apButton = document.getElementById("deployAccessPoint");
|
|
||||||
apButton.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace 'Enable WiFi' button with 'Deploy Access Point' button
|
|
||||||
PEACH_NETWORK.clientMode = function() {
|
|
||||||
// create Deploy Access Point button and add it to button div
|
|
||||||
var apButton = document.createElement("A");
|
|
||||||
apButton.className = "button center";
|
|
||||||
apButton.href = "/settings/network/ap/activate";
|
|
||||||
apButton.id = "deployAccessPoint";
|
|
||||||
var label = "Deploy Access Point";
|
|
||||||
var buttonText = document.createTextNode(label);
|
|
||||||
apButton.appendChild(buttonText);
|
|
||||||
|
|
||||||
// append the new button to the buttons div
|
|
||||||
let buttons = document.getElementById("buttons");
|
|
||||||
buttons.appendChild(apButton);
|
|
||||||
|
|
||||||
// remove the old 'Enable Wifi' button
|
|
||||||
let wifiButton = document.getElementById("connectWifi");
|
|
||||||
wifiButton.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
var networkInstance = PEACH_NETWORK;
|
|
||||||
networkInstance.activateAp();
|
|
||||||
networkInstance.activateClient();
|
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `network_detail.html.tera` template,
|
|
||||||
corresponding to the web route `/settings/network/wifi?<ssid>`
|
|
||||||
|
|
||||||
- intercept button clicks for connect, disconnect and forget
|
|
||||||
- perform json api call
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_NETWORK.connect();
|
|
||||||
PEACH_NETWORK.disconnect();
|
|
||||||
PEACH_NETWORK.forget();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_NETWORK = {};
|
|
||||||
|
|
||||||
// catch click of 'Connect' button (form) and make POST request
|
|
||||||
PEACH_NETWORK.connect = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var connectWifi = document.getElementById('connectWifi');
|
|
||||||
if (connectWifi) {
|
|
||||||
connectWifi.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// retrieve ssid value and append to form data object
|
|
||||||
var ssid = document.getElementById('connectSsid').value;
|
|
||||||
// create key:value pair
|
|
||||||
var ssidData = { ssid: ssid };
|
|
||||||
// perform json serialization
|
|
||||||
var jsonData = JSON.stringify(ssidData);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Connecting to access point...");
|
|
||||||
// send add_wifi POST request
|
|
||||||
fetch("/api/v1/network/wifi/connect", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// catch click of 'Disconnect' button and make POST request
|
|
||||||
PEACH_NETWORK.disconnect = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var disconnectWifi = document.getElementById('disconnectWifi');
|
|
||||||
if (disconnectWifi) {
|
|
||||||
disconnectWifi.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// retrieve ssid value and append to form data object
|
|
||||||
var ssid = document.getElementById('disconnectSsid').value;
|
|
||||||
// create key:value pair
|
|
||||||
var ssidData = { ssid: ssid };
|
|
||||||
// perform json serialization
|
|
||||||
var jsonData = JSON.stringify(ssidData);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Disconnecting from access point...");
|
|
||||||
// send disconnect_wifi POST request
|
|
||||||
fetch("/api/v1/network/wifi/disconnect", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// catch click of 'Forget' button (form) and make POST request
|
|
||||||
PEACH_NETWORK.forget = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var forgetWifi = document.getElementById('forgetWifi');
|
|
||||||
if (forgetWifi) {
|
|
||||||
forgetWifi.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// retrieve ssid value
|
|
||||||
var ssid = document.getElementById('forgetSsid').value;
|
|
||||||
// create key:value pair
|
|
||||||
var ssidData = { ssid: ssid };
|
|
||||||
// perform json serialization
|
|
||||||
var jsonData = JSON.stringify(ssidData);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Removing credentials for access point...");
|
|
||||||
// send forget_ap POST request
|
|
||||||
fetch("/api/v1/network/wifi/forget", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var detailInstance = PEACH_NETWORK;
|
|
||||||
detailInstance.connect();
|
|
||||||
detailInstance.disconnect();
|
|
||||||
detailInstance.forget();
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `network_modify.html.tera` template
|
|
||||||
|
|
||||||
- intercept button click for modify (form submission of credentials)
|
|
||||||
- perform json api call
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_NETWORK.modify();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_NETWORK = {};
|
|
||||||
|
|
||||||
// catch click of 'Save' button and make POST request
|
|
||||||
PEACH_NETWORK.modify = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.body.addEventListener('submit', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// capture form data
|
|
||||||
var formElement = document.querySelector("form");
|
|
||||||
// create form data object from the wifiModify form element
|
|
||||||
var formData = new FormData(formElement);
|
|
||||||
var object = {};
|
|
||||||
// assign ssid and pass from form
|
|
||||||
formData.forEach(function(value, key){
|
|
||||||
object[key] = value;
|
|
||||||
});
|
|
||||||
// perform json serialization
|
|
||||||
var jsonData = JSON.stringify(object);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Updating WiFi password...");
|
|
||||||
// send new_password POST request
|
|
||||||
fetch("/api/v1/network/wifi/modify", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var modifyInstance = PEACH_NETWORK;
|
|
||||||
modifyInstance.modify();
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `network_usage.html.tera` template,
|
|
||||||
corresponding to the web route `/settings/network/wifi/usage`
|
|
||||||
|
|
||||||
- intercept form submissions
|
|
||||||
- perform json api calls
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_NETWORK.updateAlerts();
|
|
||||||
PEACH_NETWORK.resetUsage();
|
|
||||||
PEACH_NETWORK.toggleWarning();
|
|
||||||
PEACH_NETWORK.toggleCutoff();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_NETWORK = {};
|
|
||||||
|
|
||||||
// catch click of 'Update' and make POST request
|
|
||||||
PEACH_NETWORK.updateAlerts = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.body.addEventListener('submit', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// capture form data
|
|
||||||
var formElement = document.querySelector("form");
|
|
||||||
let warn = formElement.elements.warn.value;
|
|
||||||
let cut = formElement.elements.cut.value;
|
|
||||||
let warn_flag = formElement.elements.warn_flag.checked;
|
|
||||||
let cut_flag = formElement.elements.cut_flag.checked;
|
|
||||||
// perform json serialization
|
|
||||||
var jsonData = JSON.stringify({
|
|
||||||
"warn": parseFloat(warn),
|
|
||||||
"cut": parseFloat(cut),
|
|
||||||
"warn_flag": warn_flag,
|
|
||||||
"cut_flag": cut_flag,
|
|
||||||
});
|
|
||||||
// send update_alerts POST request
|
|
||||||
fetch("/api/v1/network/wifi/usage", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// catch click of 'Reset' and make POST request
|
|
||||||
PEACH_NETWORK.resetUsage = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var resetBtn = document.getElementById('resetTotal');
|
|
||||||
if (resetBtn) {
|
|
||||||
resetBtn.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// send reset_data_usage POST request
|
|
||||||
fetch("/api/v1/network/wifi/usage/reset", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
console.log(jsonData.msg);
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
// if reset is successful, update the ui
|
|
||||||
if (jsonData.status === "success") {
|
|
||||||
console.log(jsonData.data);
|
|
||||||
PEACH_NETWORK.updateTotal(jsonData.data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// update data usage total in ui
|
|
||||||
PEACH_NETWORK.updateTotal = function(data) {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
console.log(data);
|
|
||||||
let label = document.getElementById("dataTotal");
|
|
||||||
// take usage total as bytes, convert to MB and round to nearest integer
|
|
||||||
label.textContent = (data / 1024 / 1024).round();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// update ui for warning
|
|
||||||
PEACH_NETWORK.toggleWarning = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
let i = document.getElementById("warnIcon");
|
|
||||||
let warnCheck = document.getElementById("warnCheck");
|
|
||||||
warnCheck.addEventListener('click', function(e) {
|
|
||||||
console.log('Toggling warning icon state');
|
|
||||||
if (warnCheck.checked) {
|
|
||||||
i.className = "icon";
|
|
||||||
} else {
|
|
||||||
i.className = "icon icon-inactive";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// update ui for cutoff
|
|
||||||
PEACH_NETWORK.toggleCutoff = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
let i = document.getElementById("cutIcon");
|
|
||||||
let cutCheck = document.getElementById("cutCheck");
|
|
||||||
cutCheck.addEventListener('click', function(e) {
|
|
||||||
console.log('Toggling cutoff icon state');
|
|
||||||
if (cutCheck.checked) {
|
|
||||||
i.className = "icon";
|
|
||||||
} else {
|
|
||||||
i.className = "icon icon-inactive";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var usageInstance = PEACH_NETWORK;
|
|
||||||
usageInstance.resetUsage();
|
|
||||||
usageInstance.toggleWarning();
|
|
||||||
usageInstance.toggleCutoff();
|
|
||||||
usageInstance.updateAlerts();
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
behavioural layer for the `power.html.tera` template,
|
|
||||||
corresponding to the web route `/power`
|
|
||||||
|
|
||||||
- intercept button clicks for reboot & shutdown
|
|
||||||
- perform json api calls
|
|
||||||
- update the dom
|
|
||||||
|
|
||||||
methods:
|
|
||||||
|
|
||||||
PEACH_DEVICE.reboot();
|
|
||||||
PEACH_DEVICE.shutdown();
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_DEVICE = {};
|
|
||||||
|
|
||||||
// catch click of 'Reboot' button and make POST request
|
|
||||||
PEACH_DEVICE.reboot = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var rebootDevice = document.getElementById('rebootBtn');
|
|
||||||
if (rebootDevice) {
|
|
||||||
rebootDevice.addEventListener('click', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// write reboot flash message
|
|
||||||
PEACH.flashMsg("success", "Rebooting the device...");
|
|
||||||
// send reboot_device POST request
|
|
||||||
fetch("/api/v1/admin/reboot", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
console.log(jsonData.msg);
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// catch click of 'Shutdown' button and make POST request
|
|
||||||
PEACH_DEVICE.shutdown = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var shutdownDevice = document.getElementById('shutdownBtn');
|
|
||||||
if (shutdownDevice) {
|
|
||||||
shutdownDevice.addEventListener('click', function(e) {
|
|
||||||
// prevent form submission (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// write shutdown flash message
|
|
||||||
PEACH.flashMsg("success", "Shutting down the device...");
|
|
||||||
// send shutdown_device POST request
|
|
||||||
fetch("/api/v1/shutdown", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
console.log(jsonData.msg);
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var deviceInstance = PEACH_DEVICE;
|
|
||||||
deviceInstance.reboot();
|
|
||||||
deviceInstance.shutdown();
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* behavioural layer for the `reset_password.html.tera` template,
|
|
||||||
*/
|
|
||||||
|
|
||||||
var PEACH_AUTH = {};
|
|
||||||
|
|
||||||
// catch click of 'Save' button and make POST request
|
|
||||||
PEACH_AUTH.resetPassword = function() {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.body.addEventListener('submit', function(e) {
|
|
||||||
// prevent redirect on button press (default behavior)
|
|
||||||
e.preventDefault();
|
|
||||||
// capture form data
|
|
||||||
var formElement = document.querySelector("form");
|
|
||||||
// create form data object from the changePassword form element
|
|
||||||
var formData = new FormData(formElement);
|
|
||||||
var object = {};
|
|
||||||
// assign values from form
|
|
||||||
formData.forEach(function(value, key){
|
|
||||||
object[key] = value;
|
|
||||||
});
|
|
||||||
// perform json serialization
|
|
||||||
console.log(object);
|
|
||||||
var jsonData = JSON.stringify(object);
|
|
||||||
// write in-progress status message to ui
|
|
||||||
PEACH.flashMsg("info", "Saving new password.");
|
|
||||||
// send add_wifi POST request
|
|
||||||
fetch("/api/v1/admin/reset_password", {
|
|
||||||
method: "post",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: jsonData
|
|
||||||
})
|
|
||||||
.then( (response) => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then( (jsonData) => {
|
|
||||||
// write json response message to ui
|
|
||||||
PEACH.flashMsg(jsonData.status, jsonData.msg);
|
|
||||||
})
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var resetPassInstance = PEACH_AUTH;
|
|
||||||
resetPassInstance.resetPassword();
|
|
|
@ -13,5 +13,4 @@
|
||||||
<body>
|
<body>
|
||||||
{% block nav %}{% endblock nav %}
|
{% block nav %}{% endblock nav %}
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="/js/common.js"></script>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
<!-- NO SCRIPT FOR WHEN JS IS DISABLED -->
|
|
||||||
{% include "snippets/noscript" %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/power_menu.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
</form>
|
</form>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
<!-- NO SCRIPT FOR WHEN JS IS DISABLED -->
|
|
||||||
{% include "snippets/noscript" %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/change_password.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
|
@ -35,14 +35,8 @@
|
||||||
<input id="changePasswordButton" class="button button-primary center" title="Add" type="submit" value="Save">
|
<input id="changePasswordButton" class="button button-primary center" title="Add" type="submit" value="Save">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
|
|
||||||
<!-- NO SCRIPT FOR WHEN JS IS DISABLED -->
|
|
||||||
{% include "snippets/noscript" %}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/reset_password.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
|
@ -15,9 +15,6 @@
|
||||||
</form>
|
</form>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
<!-- NO SCRIPT FOR WHEN JS IS DISABLED -->
|
|
||||||
{% include "snippets/noscript" %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/network_add.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
|
@ -69,7 +69,6 @@
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/network_detail.js"></script>
|
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
{%- block card %}
|
{%- block card %}
|
||||||
<!-- CONFIGURE DNS FORM -->
|
<!-- CONFIGURE DNS FORM -->
|
||||||
<div class="card center">
|
<div class="card center">
|
||||||
|
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
|
|
||||||
{% if enable_dyndns %}
|
{% if enable_dyndns %}
|
||||||
<!-- DYNDNS STATUS INDICATOR -->
|
<!-- DYNDNS STATUS INDICATOR -->
|
||||||
<div id="dyndns-status-indicator" class="stack capsule{% if is_dyndns_online %} success-border{% else %} warning-border{% endif %}">
|
<div id="dyndns-status-indicator" class="stack capsule{% if is_dyndns_online %} success-border{% else %} warning-border{% endif %}">
|
||||||
|
@ -17,7 +15,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<form id="configureDNS" action="/settings/network/dns" method="post">
|
<form id="configureDNS" action="/settings/network/dns" method="post">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<!-- input for externaldomain -->
|
<!-- input for externaldomain -->
|
||||||
|
@ -25,7 +22,6 @@
|
||||||
<label class="label-small input-label font-gray" for="external_domain" style="padding-top: 0.25rem;">External Domain (optional)</label>
|
<label class="label-small input-label font-gray" for="external_domain" style="padding-top: 0.25rem;">External Domain (optional)</label>
|
||||||
<input id="external_domain" class="form-input" style="margin-bottom: 0;"
|
<input id="external_domain" class="form-input" style="margin-bottom: 0;"
|
||||||
name="external_domain" type="text" title="external domain" value="{{ external_domain }}"></label>
|
name="external_domain" type="text" title="external domain" value="{{ external_domain }}"></label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<div>
|
<div>
|
||||||
|
@ -41,16 +37,13 @@
|
||||||
<label id="cut" class="label-small input-label font-near-black">
|
<label id="cut" class="label-small input-label font-near-black">
|
||||||
<label class="label-small input-label font-gray" for="cut" style="padding-top: 0.25rem;">Dynamic DNS Domain</label>
|
<label class="label-small input-label font-gray" for="cut" style="padding-top: 0.25rem;">Dynamic DNS Domain</label>
|
||||||
<input id="dyndns_domain" class="alert-input" name="dynamic_domain" placeholder="" type="text" title="dyndns_domain" value="{{ dyndns_subdomain }}">.dyn.peachcloud.org</label>
|
<input id="dyndns_domain" class="alert-input" name="dynamic_domain" placeholder="" type="text" title="dyndns_domain" value="{{ dyndns_subdomain }}">.dyn.peachcloud.org</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="buttonDiv">
|
<div id="buttonDiv">
|
||||||
<input id="configureDNSButton" class="button button-primary center" title="Add" type="submit" value="Save">
|
<input id="configureDNSButton" class="button button-primary center" title="Add" type="submit" value="Save">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<!-- FLASH MESSAGE -->
|
||||||
<!-- FLASH MESSAGE -->
|
|
||||||
<!-- check for flash message and display accordingly -->
|
<!-- check for flash message and display accordingly -->
|
||||||
{% if flash_msg and flash_name == "success" %}
|
{% if flash_msg and flash_name == "success" %}
|
||||||
<!-- display success message -->
|
<!-- display success message -->
|
||||||
|
@ -62,14 +55,6 @@
|
||||||
<!-- display error message -->
|
<!-- display error message -->
|
||||||
<div class="capsule center-text flash-message font-failure">{{ flash_msg }}.</div>
|
<div class="capsule center-text flash-message font-failure">{{ flash_msg }}.</div>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
<!-- share ux information with the user if JS is disabled -->
|
|
||||||
<noscript>
|
|
||||||
<div class="capsule flash-message info-border">
|
|
||||||
<p class="center-text">This website may be temporarily unresponsive while settings are being saved.</p>
|
|
||||||
</div>
|
|
||||||
</noscript>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/configure_dns.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
|
@ -43,5 +43,4 @@
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
</form>
|
</form>
|
||||||
<script type="text/javascript" src="/js/network_usage.js"></script>
|
|
||||||
{%- endblock card %}
|
{%- endblock card %}
|
||||||
|
|
|
@ -20,5 +20,4 @@
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/network_card.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
|
@ -17,5 +17,4 @@
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/network_modify.js"></script>
|
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
||||||
|
|
Loading…
Reference in New Issue