Add WS debug console
This commit is contained in:
parent
558d5cda3f
commit
b8a8e14f3c
68
assets/ws_debug.js
Normal file
68
assets/ws_debug.js
Normal file
@ -0,0 +1,68 @@
|
||||
let ws;
|
||||
|
||||
const JS_MESSAGE = "JS code";
|
||||
const IN_MESSAGE = "Incoming";
|
||||
|
||||
/**
|
||||
* Log message
|
||||
*/
|
||||
function log(src, txt) {
|
||||
const target = document.getElementById("ws_log");
|
||||
const msg = document.createElement("div");
|
||||
msg.className = "message";
|
||||
msg.innerHTML = `<div class='type'>${src}</div><div>${txt}</div>`
|
||||
target.insertBefore(msg, target.firstChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of the WebSocket
|
||||
*/
|
||||
function setState(state) {
|
||||
document.getElementById("state").innerText = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize WebSocket connection
|
||||
*/
|
||||
function connect() {
|
||||
disconnect();
|
||||
log(JS_MESSAGE, "Initialize connection...");
|
||||
ws = new WebSocket("/api/ws");
|
||||
setState("Connecting...");
|
||||
ws.onopen = function () {
|
||||
log(JS_MESSAGE, "Connected to WebSocket !");
|
||||
setState("Connected");
|
||||
}
|
||||
ws.onmessage = function (event) {
|
||||
log(IN_MESSAGE, event.data);
|
||||
}
|
||||
ws.onclose = function () {
|
||||
log(JS_MESSAGE, "Disconnected from WebSocket !");
|
||||
setState("Disconnected");
|
||||
}
|
||||
ws.onerror = function (event) {
|
||||
console.error("WS Error!", event);
|
||||
log(JS_MESSAGE, `Error with websocket! ${event}`);
|
||||
setState("Error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close WebSocket connection
|
||||
*/
|
||||
function disconnect() {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
log(JS_MESSAGE, "Close connection...");
|
||||
ws.close();
|
||||
}
|
||||
|
||||
setState("Disconnected");
|
||||
ws = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear WS logs
|
||||
*/
|
||||
function clearLogs() {
|
||||
document.getElementById("ws_log").innerHTML = "";
|
||||
}
|
@ -48,6 +48,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.route("/", web::post().to(web_ui::home))
|
||||
.route("/oidc_cb", web::get().to(web_ui::oidc_cb))
|
||||
.route("/sign_out", web::get().to(web_ui::sign_out))
|
||||
.route("/ws_debug", web::get().to(web_ui::ws_debug))
|
||||
// API routes
|
||||
.route("/api", web::get().to(api::api_home))
|
||||
.route("/api", web::post().to(api::api_home))
|
||||
|
@ -223,3 +223,22 @@ pub async fn sign_out(session: Session) -> HttpResult {
|
||||
.insert_header(("location", "/"))
|
||||
.finish())
|
||||
}
|
||||
|
||||
#[derive(askama::Template)]
|
||||
#[template(path = "ws_debug.html")]
|
||||
struct WsDebugTemplate {
|
||||
name: String,
|
||||
}
|
||||
|
||||
/// WebSocket debug
|
||||
pub async fn ws_debug(session: Session) -> HttpResult {
|
||||
let Some(user): Option<User> = session.get(USER_SESSION_KEY)? else {
|
||||
return Ok(HttpResponse::Found()
|
||||
.insert_header(("location", "/"))
|
||||
.finish());
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html")
|
||||
.body(WsDebugTemplate { name: user.name }.render().unwrap()))
|
||||
}
|
||||
|
46
templates/base_page.html
Normal file
46
templates/base_page.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Matrix GW</title>
|
||||
<link rel="icon" type="image/png" href="/assets/favicon.png"/>
|
||||
|
||||
<link rel="stylesheet" href="/assets/bootstrap.css"/>
|
||||
<link rel="stylesheet" href="/assets/style.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Header -->
|
||||
<header data-bs-theme="dark">
|
||||
<div class="navbar navbar-dark bg-dark shadow-sm">
|
||||
<div class="container">
|
||||
<a href="/" class="navbar-brand d-flex align-items-center">
|
||||
<svg xxmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor"
|
||||
stroke-linecap="round" stroke-linejoin="round" stroke-width="1" aria-hidden="true" class="me-2"
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M10 11.5H17V13H10V11.5M10 8.5H19V10H10V8.5M20 5H9C7.9 5 7 5.9 7 7V21L11 17H20C21.1 17 22 16.1 22 15V7C22 5.9 21.1 5 20 5M20 15H10.2L9 16.2V7H20V15M3 7C2.4 7 2 7.4 2 8S2.4 9 3 9H5V7H3M2 11C1.4 11 1 11.4 1 12S1.4 13 2 13H5V11H2M1 15C.4 15 0 15.4 0 16C0 16.6 .4 17 1 17H5V15H1Z"/>
|
||||
</svg>
|
||||
<strong>Matrix GW</strong>
|
||||
</a>
|
||||
<ul class="navbar-nav mr-auto" style="flex: 1">
|
||||
<li class="nav-item"><a href="/ws_debug" class="nav-link">WS Debug</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="navbar" >
|
||||
<span>Hi <span style="font-style: italic;">{{ name }}</span> </span>
|
||||
<a href="/sign_out">Sign out</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="body-content">
|
||||
{% block content %}
|
||||
TO_REPLACE
|
||||
{% endblock content %}
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,181 +1,146 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Matrix GW</title>
|
||||
<link rel="icon" type="image/png" href="/assets/favicon.png"/>
|
||||
{% extends "base_page.html" %}
|
||||
{% block content %}
|
||||
<!-- Success message -->
|
||||
{% if let Some(msg) = success_message %}
|
||||
<div class="alert alert-success">
|
||||
{{ msg }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<link rel="stylesheet" href="/assets/bootstrap.css"/>
|
||||
<link rel="stylesheet" href="/assets/style.css"/>
|
||||
<script src="/assets/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Error message -->
|
||||
{% if let Some(msg) = error_message %}
|
||||
<div class="alert alert-danger">
|
||||
{{ msg }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Header -->
|
||||
<header data-bs-theme="dark">
|
||||
<div class="navbar navbar-dark bg-dark shadow-sm">
|
||||
<div class="container">
|
||||
<a href="/" class="navbar-brand d-flex align-items-center">
|
||||
<svg xxmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor"
|
||||
stroke-linecap="round" stroke-linejoin="round" stroke-width="1" aria-hidden="true" class="me-2"
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M10 11.5H17V13H10V11.5M10 8.5H19V10H10V8.5M20 5H9C7.9 5 7 5.9 7 7V21L11 17H20C21.1 17 22 16.1 22 15V7C22 5.9 21.1 5 20 5M20 15H10.2L9 16.2V7H20V15M3 7C2.4 7 2 7.4 2 8S2.4 9 3 9H5V7H3M2 11C1.4 11 1 11.4 1 12S1.4 13 2 13H5V11H2M1 15C.4 15 0 15.4 0 16C0 16.6 .4 17 1 17H5V15H1Z"/>
|
||||
</svg>
|
||||
<strong>Matrix GW</strong>
|
||||
</a>
|
||||
<div class="navbar">
|
||||
<span>Hi <span style="font-style: italic;">{{ name }}</span> </span>
|
||||
<a href="/sign_out">Sign out</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- User ID -->
|
||||
<div id="user_id_container"><strong>Current user ID</strong>: {{ user_id.0 }}</div>
|
||||
|
||||
<!-- Display clients list -->
|
||||
<div class="card border-light mb-3">
|
||||
<div class="card-header">Registered clients</div>
|
||||
<div class="card-body">
|
||||
{% if clients.len() > 0 %}
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Description</th>
|
||||
<th scope="col">Read only</th>
|
||||
<th scope="col">Network</th>
|
||||
<th scope="col">Created</th>
|
||||
<th scope="col">Used</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for client in clients %}
|
||||
<tr>
|
||||
<th scope="row">{{ client.id.0 }}</th>
|
||||
<td>{{ client.description }}</td>
|
||||
<td>
|
||||
{% if client.readonly_client %}
|
||||
<strong>YES</strong>
|
||||
{% else %}
|
||||
<i>NO</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if let Some(net) = client.network %}
|
||||
{{ net }}
|
||||
{% else %}
|
||||
<i>Unrestricted</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ client.fmt_created() }}</td>
|
||||
<td>{{ client.fmt_used() }}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger btn-sm" onclick="deleteClient('{{ client.id.0 }}');">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
<div class="body-content">
|
||||
<!-- Success message -->
|
||||
{% if let Some(msg) = success_message %}
|
||||
<div class="alert alert-success">
|
||||
{{ msg }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Error message -->
|
||||
{% if let Some(msg) = error_message %}
|
||||
<div class="alert alert-danger">
|
||||
{{ msg }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- User ID -->
|
||||
<div id="user_id_container"><strong>Current user ID</strong>: {{ user_id.0 }}</div>
|
||||
|
||||
<!-- Display clients list -->
|
||||
<div class="card border-light mb-3">
|
||||
<div class="card-header">Registered clients</div>
|
||||
<div class="card-body">
|
||||
{% if clients.len() > 0 %}
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Description</th>
|
||||
<th scope="col">Read only</th>
|
||||
<th scope="col">Network</th>
|
||||
<th scope="col">Created</th>
|
||||
<th scope="col">Used</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for client in clients %}
|
||||
<tr>
|
||||
<th scope="row">{{ client.id.0 }}</th>
|
||||
<td>{{ client.description }}</td>
|
||||
<td>
|
||||
{% if client.readonly_client %}
|
||||
<strong>YES</strong>
|
||||
{% else %}
|
||||
<i>NO</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if let Some(net) = client.network %}
|
||||
{{ net }}
|
||||
{% else %}
|
||||
<i>Unrestricted</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ client.fmt_created() }}</td>
|
||||
<td>{{ client.fmt_used() }}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger btn-sm" onclick="deleteClient('{{ client.id.0 }}');">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if clients.len() == 0 %}
|
||||
<p>No client registered yet!</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New client -->
|
||||
<div class="card border-light mb-3">
|
||||
<div class="card-header">New client</div>
|
||||
<div class="card-body">
|
||||
<form action="/" method="post">
|
||||
<div>
|
||||
<label for="new_client_desc" class="form-label">Description</label>
|
||||
<input type="text" class="form-control" id="new_client_desc" required minlength="3"
|
||||
aria-describedby="new_client_desc" placeholder="New client description..."
|
||||
name="new_client_desc"/>
|
||||
<small class="form-text text-muted">Client description helps with identification.</small>
|
||||
</div>
|
||||
<div>
|
||||
<label for="ip_network" class="form-label">Allowed IP network</label>
|
||||
<input type="text" class="form-control" id="ip_network" aria-describedby="ip_network"
|
||||
placeholder="Client network (x.x.x.x/x or x:x:x:x:x:x/x" name="ip_network"/>
|
||||
<small class="form-text text-muted">Restrict the networks this IP address can be used from.</small>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" checked id="readonly_client"
|
||||
name="readonly_client"/>
|
||||
<label class="form-check-label" for="readonly_client">
|
||||
Readonly client
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="Create client"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Matrix authentication token -->
|
||||
<div class="card border-light mb-3">
|
||||
<div class="card-header">Matrix authentication token</div>
|
||||
<div class="card-body">
|
||||
<p>To obtain a new Matrix authentication token:</p>
|
||||
<ol>
|
||||
<li>Sign in to Element <strong>from a private browser window</strong></li>
|
||||
<li>Open <em>All settings</em> and access the <em>Help & About</em> tag</li>
|
||||
<li>Expand <em>Access Token</em> and copy the value</li>
|
||||
<li>Paste the copied value below</li>
|
||||
<li>Close the private browser window <strong>without signing out</strong>!</li>
|
||||
</ol>
|
||||
|
||||
<p>You should not need to replace this value unless you explicitly signed out the associated browser
|
||||
session.</p>
|
||||
|
||||
<p>Tip: you can rename the session to easily identify it among all your other sessions!</p>
|
||||
|
||||
<form action="/" method="post">
|
||||
<div>
|
||||
<label for="accessTokenInput" class="form-label mt-4">New Matrix access token</label>
|
||||
<input type="text" class="form-control" id="accessTokenInput" aria-describedby="tokenHelp"
|
||||
placeholder="{{ matrix_token }}" required minlength="2" name="new_matrix_token"/>
|
||||
<small id="tokenHelp" class="form-text text-muted">Changing this value will reset all active
|
||||
connections
|
||||
to Matrix GW.</small>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="Update"/>
|
||||
</form>
|
||||
</div>
|
||||
{% if clients.len() == 0 %}
|
||||
<p>No client registered yet!</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New client -->
|
||||
<div class="card border-light mb-3">
|
||||
<div class="card-header">New client</div>
|
||||
<div class="card-body">
|
||||
<form action="/" method="post">
|
||||
<div>
|
||||
<label for="new_client_desc" class="form-label">Description</label>
|
||||
<input type="text" class="form-control" id="new_client_desc" required minlength="3"
|
||||
aria-describedby="new_client_desc" placeholder="New client description..."
|
||||
name="new_client_desc"/>
|
||||
<small class="form-text text-muted">Client description helps with identification.</small>
|
||||
</div>
|
||||
<div>
|
||||
<label for="ip_network" class="form-label">Allowed IP network</label>
|
||||
<input type="text" class="form-control" id="ip_network" aria-describedby="ip_network"
|
||||
placeholder="Client network (x.x.x.x/x or x:x:x:x:x:x/x" name="ip_network"/>
|
||||
<small class="form-text text-muted">Restrict the networks this IP address can be used from.</small>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<br/>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" checked id="readonly_client"
|
||||
name="readonly_client"/>
|
||||
<label class="form-check-label" for="readonly_client">
|
||||
Readonly client
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="Create client"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Matrix authentication token -->
|
||||
<div class="card border-light mb-3">
|
||||
<div class="card-header">Matrix authentication token</div>
|
||||
<div class="card-body">
|
||||
<p>To obtain a new Matrix authentication token:</p>
|
||||
<ol>
|
||||
<li>Sign in to Element <strong>from a private browser window</strong></li>
|
||||
<li>Open <em>All settings</em> and access the <em>Help & About</em> tag</li>
|
||||
<li>Expand <em>Access Token</em> and copy the value</li>
|
||||
<li>Paste the copied value below</li>
|
||||
<li>Close the private browser window <strong>without signing out</strong>!</li>
|
||||
</ol>
|
||||
|
||||
<p>You should not need to replace this value unless you explicitly signed out the associated browser
|
||||
session.</p>
|
||||
|
||||
<p>Tip: you can rename the session to easily identify it among all your other sessions!</p>
|
||||
|
||||
<form action="/" method="post">
|
||||
<div>
|
||||
<label for="accessTokenInput" class="form-label mt-4">New Matrix access token</label>
|
||||
<input type="text" class="form-control" id="accessTokenInput" aria-describedby="tokenHelp"
|
||||
placeholder="{{ matrix_token }}" required minlength="2" name="new_matrix_token"/>
|
||||
<small id="tokenHelp" class="form-text text-muted">Changing this value will reset all active
|
||||
connections
|
||||
to Matrix GW.</small>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="Update"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/assets/script.js"></script>
|
||||
{% endblock content %}
|
46
templates/ws_debug.html
Normal file
46
templates/ws_debug.html
Normal file
@ -0,0 +1,46 @@
|
||||
{% extends "base_page.html" %}
|
||||
{% block content %}
|
||||
|
||||
<style>
|
||||
#ws_actions {
|
||||
margin: 30px;
|
||||
border: 1px white solid;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#ws_log {
|
||||
margin: 30px;
|
||||
border: 1px white solid;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#ws_log .message {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#ws_log .message .type {
|
||||
font-style: italic;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<h2>WS Debug</h2>
|
||||
|
||||
<div id="ws_actions">
|
||||
<button onclick="connect()">Reconnect</button>
|
||||
<button onclick="disconnect()">Disconnect</button>
|
||||
<button onclick="clearLogs()">Clear logs</button>
|
||||
<span>State: <span id="state">DISCONNECTED</span></span>
|
||||
</div>
|
||||
|
||||
<div id="ws_log">
|
||||
<div class="message">
|
||||
<div class="type">INFO</div>
|
||||
<div>Welcome!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/assets/ws_debug.js"></script>
|
||||
{% endblock content %}
|
Loading…
x
Reference in New Issue
Block a user