feat: add read-only mode to API and UI, disable write actions
This commit is contained in:
+17
-1
@@ -52,8 +52,24 @@
|
||||
drawTable(table, await r.json());
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
if (!window.go2rtcReady) return;
|
||||
window.go2rtcReady.then(data => {
|
||||
if (!data || !data.read_only) return;
|
||||
const banner = document.getElementById('readonly-banner');
|
||||
if (banner) banner.style.display = 'block';
|
||||
document.querySelectorAll('main input, main select, main button, main textarea').forEach(el => {
|
||||
el.disabled = true;
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div id="readonly-banner" style="display: none; padding: 10px; background: #ffe9e9; border: 1px solid #f0b4b4;">
|
||||
Read-only mode: add actions are disabled.
|
||||
</div>
|
||||
<button id="stream">Temporary stream</button>
|
||||
<div>
|
||||
<form id="stream-form">
|
||||
@@ -566,4 +582,4 @@
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
+14
-1
@@ -1182,7 +1182,20 @@
|
||||
|
||||
let dump;
|
||||
|
||||
document.getElementById('save').addEventListener('click', async () => {
|
||||
const saveButton = document.getElementById('save');
|
||||
const applyReadOnly = () => {
|
||||
saveButton.disabled = true;
|
||||
saveButton.title = 'Read-only mode';
|
||||
editor.updateOptions({readOnly: true});
|
||||
};
|
||||
|
||||
if (window.go2rtcReady) {
|
||||
window.go2rtcReady.then(data => {
|
||||
if (data && data.read_only) applyReadOnly();
|
||||
});
|
||||
}
|
||||
|
||||
saveButton.addEventListener('click', async () => {
|
||||
let r = await fetch('api/config', {cache: 'no-cache'});
|
||||
if (r.ok && dump !== await r.text()) {
|
||||
alert('Config was changed from another place. Refresh the page and make changes again');
|
||||
|
||||
+21
-6
@@ -45,11 +45,18 @@
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const templates = [
|
||||
let templates = [
|
||||
'<a href="stream.html?src={name}">stream</a>',
|
||||
'<a href="links.html?src={name}">links</a>',
|
||||
'<a href="#" data-name="{name}">delete</a>',
|
||||
];
|
||||
let readOnly = false;
|
||||
|
||||
const applyReadOnly = (flag) => {
|
||||
if (!flag || readOnly) return;
|
||||
readOnly = true;
|
||||
templates = templates.filter(link => link.indexOf('delete') < 0);
|
||||
};
|
||||
|
||||
document.querySelector('.controls > button')
|
||||
.addEventListener('click', () => {
|
||||
@@ -144,13 +151,21 @@
|
||||
// Auto-reload
|
||||
setInterval(reload, 1000);
|
||||
|
||||
const url = new URL('api', location.href);
|
||||
fetch(url, {cache: 'no-cache'}).then(r => r.json()).then(data => {
|
||||
const info = document.querySelector('.info');
|
||||
const info = document.querySelector('.info');
|
||||
const applyInfo = (data) => {
|
||||
info.innerText = `version: ${data.version} / config: ${data.config_path}`;
|
||||
});
|
||||
applyReadOnly(Boolean(data.read_only));
|
||||
reload();
|
||||
};
|
||||
|
||||
reload();
|
||||
if (window.go2rtcReady) {
|
||||
window.go2rtcReady.then(data => {
|
||||
if (data) applyInfo(data);
|
||||
});
|
||||
} else {
|
||||
const url = new URL('api', location.href);
|
||||
fetch(url, {cache: 'no-cache'}).then(r => r.json()).then(data => applyInfo(data));
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -152,6 +152,21 @@ Telegram: rtmps://xxx-x.rtmp.t.me/s/xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxx</pre>
|
||||
fetch(url, {method: 'POST'});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
const applyReadOnly = () => {
|
||||
const ids = ['play-send', 'play-url', 'pub-send', 'pub-url'];
|
||||
ids.forEach(id => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.disabled = true;
|
||||
});
|
||||
};
|
||||
|
||||
if (window.go2rtcReady) {
|
||||
window.go2rtcReady.then(data => {
|
||||
if (data && data.read_only) applyReadOnly();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="webrtc">
|
||||
<h2>WebRTC Magic</h2>
|
||||
|
||||
+21
@@ -133,3 +133,24 @@ document.body.innerHTML = `
|
||||
</nav>
|
||||
</header>
|
||||
` + document.body.innerHTML;
|
||||
|
||||
window.go2rtcReady = (async () => {
|
||||
try {
|
||||
const url = new URL('api', location.href);
|
||||
const r = await fetch(url, {cache: 'no-cache'});
|
||||
if (!r.ok) return null;
|
||||
const data = await r.json();
|
||||
window.go2rtcInfo = data;
|
||||
return data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
window.go2rtcReady.then(data => {
|
||||
if (!data || !data.read_only) return;
|
||||
const links = document.querySelectorAll('nav a[href="add.html"], nav a[href="config.html"]');
|
||||
links.forEach(link => {
|
||||
link.style.display = 'none';
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,6 +68,11 @@
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"read_only": {
|
||||
"description": "Disable write actions in WebUI/API",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"local_auth": {
|
||||
"description": "Enable auth check for localhost requests",
|
||||
"type": "boolean",
|
||||
|
||||
Reference in New Issue
Block a user