[feat](trx-frontend-http): separate transmit permission
CI / frontend (pull_request) Successful in 5m21s
CI / lint (pull_request) Successful in 2m24s
CI / test (pull_request) Successful in 9m11s
CI / test (push) Successful in 8m16s
CI / frontend (push) Successful in 4m24s
CI / reuse (push) Successful in 5s
CI / reuse (pull_request) Successful in 5s
CI / lint (push) Successful in 2m25s
CI / frontend (pull_request) Successful in 5m21s
CI / lint (pull_request) Successful in 2m24s
CI / test (pull_request) Successful in 9m11s
CI / test (push) Successful in 8m16s
CI / frontend (push) Successful in 4m24s
CI / reuse (push) Successful in 5s
CI / reuse (pull_request) Successful in 5s
CI / lint (push) Successful in 2m25s
Assisted-By: Codex (GPT-5) Signed-off-by: Stan Grams <sjg@haxx.space>
This commit was merged in pull request #64.
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
logout,
|
||||
normalizeAuthRoles,
|
||||
updateUser
|
||||
} from "./chunk-FT2RH7BL.js";
|
||||
} from "./chunk-PISLBJGN.js";
|
||||
|
||||
// src/webgl-renderer.ts
|
||||
(function initTrxWebGl(global) {
|
||||
@@ -1972,30 +1972,33 @@ function updateAuthUI() {
|
||||
}
|
||||
function applyAuthRestrictions() {
|
||||
if (authRoles.length === 0) return;
|
||||
if (!hasAuthRole2("control")) {
|
||||
if (!hasAuthRole2("transmit")) {
|
||||
const pttBtn2 = document.getElementById("ptt-btn");
|
||||
const txLimitInput2 = document.getElementById("tx-limit");
|
||||
const txLimitBtn2 = document.getElementById("tx-limit-btn");
|
||||
const txAudioBtn2 = document.getElementById("tx-audio-btn");
|
||||
const txLimitRow2 = document.getElementById("tx-limit-row");
|
||||
if (pttBtn2) pttBtn2.disabled = true;
|
||||
if (txAudioBtn2) txAudioBtn2.disabled = true;
|
||||
if (txLimitBtn2) txLimitBtn2.disabled = true;
|
||||
if (txLimitInput2) txLimitInput2.disabled = true;
|
||||
if (txLimitRow2) txLimitRow2.style.opacity = "0.5";
|
||||
}
|
||||
if (!hasAuthRole2("control")) {
|
||||
const powerBtn2 = document.getElementById("power-btn");
|
||||
const lockBtn2 = document.getElementById("lock-btn");
|
||||
const freqInput = document.getElementById("freq");
|
||||
const centerFreqInput = document.getElementById("center-freq");
|
||||
const modeSelect = document.getElementById("mode");
|
||||
const txLimitInput2 = document.getElementById("tx-limit");
|
||||
const txLimitBtn2 = document.getElementById("tx-limit-btn");
|
||||
const txAudioBtn2 = document.getElementById("tx-audio-btn");
|
||||
const txLimitRow2 = document.getElementById("tx-limit-row");
|
||||
const jogUp = document.getElementById("jog-up");
|
||||
const jogDown = document.getElementById("jog-down");
|
||||
const jogButtons = document.querySelectorAll(".jog-step button");
|
||||
const vfoButtons = document.querySelectorAll("#vfo-picker button");
|
||||
if (pttBtn2) pttBtn2.disabled = true;
|
||||
if (powerBtn2) powerBtn2.disabled = true;
|
||||
if (lockBtn2) lockBtn2.disabled = true;
|
||||
if (txAudioBtn2) txAudioBtn2.disabled = true;
|
||||
if (txLimitBtn2) txLimitBtn2.disabled = true;
|
||||
if (freqInput) freqInput.disabled = true;
|
||||
if (centerFreqInput) centerFreqInput.disabled = true;
|
||||
if (modeSelect) modeSelect.disabled = true;
|
||||
if (txLimitInput2) txLimitInput2.disabled = true;
|
||||
vfoButtons.forEach((btn) => btn.disabled = true);
|
||||
const jogWheel2 = document.getElementById("jog-wheel");
|
||||
if (jogUp) jogUp.disabled = true;
|
||||
@@ -2032,7 +2035,6 @@ function applyAuthRestrictions() {
|
||||
btn.disabled = true;
|
||||
}
|
||||
});
|
||||
if (txLimitRow2) txLimitRow2.style.opacity = "0.5";
|
||||
}
|
||||
}
|
||||
function applyCapabilities(caps) {
|
||||
@@ -4250,9 +4252,16 @@ function formatSignal(sUnits) {
|
||||
return overDb === 0 ? `${sigUnit("S")}9` : `${sigUnit("S")}9+${overDb}${sigUnit("dB")}`;
|
||||
}
|
||||
function setDisabled(disabled) {
|
||||
[freqEl, centerFreqEl, modeEl, pttBtn, powerBtn, txLimitInput, txLimitBtn, lockBtn].forEach((el) => {
|
||||
if (el) el.disabled = disabled;
|
||||
const controlDisabled = disabled || authEnabled && !hasAuthRole2("control");
|
||||
const transmitDisabled = disabled || authEnabled && !hasAuthRole2("transmit");
|
||||
[freqEl, centerFreqEl, modeEl, powerBtn, lockBtn].forEach((el) => {
|
||||
if (el) el.disabled = controlDisabled;
|
||||
});
|
||||
[pttBtn, txLimitInput, txLimitBtn].forEach((el) => {
|
||||
if (el) el.disabled = transmitDisabled;
|
||||
});
|
||||
const transmitAudio = document.getElementById("tx-audio-btn");
|
||||
if (transmitAudio) transmitAudio.disabled = transmitDisabled || !hasWebCodecs;
|
||||
syncModePicker();
|
||||
}
|
||||
var serverVersion = null;
|
||||
@@ -7329,6 +7338,10 @@ function startTxAudio() {
|
||||
void stopTxAudio();
|
||||
return;
|
||||
}
|
||||
if (authEnabled && !hasAuthRole2("transmit")) {
|
||||
audioStatus.textContent = "Transmit role required";
|
||||
return;
|
||||
}
|
||||
if (!hasWebCodecs) {
|
||||
audioStatus.textContent = "Audio requires Chrome/Edge";
|
||||
return;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
hasAuthRole
|
||||
} from "./chunk-FT2RH7BL.js";
|
||||
} from "./chunk-PISLBJGN.js";
|
||||
import {
|
||||
hostState
|
||||
} from "./chunk-KL66PICH.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
hasAuthRole
|
||||
} from "./chunk-FT2RH7BL.js";
|
||||
} from "./chunk-PISLBJGN.js";
|
||||
import {
|
||||
hostCore,
|
||||
hostState
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
// src/api/auth.ts
|
||||
var AUTH_ROLES = ["guest", "read", "control", "write", "administrator"];
|
||||
var AUTH_ROLES = ["guest", "read", "control", "transmit", "write", "administrator"];
|
||||
var AUTH_ADMIN_ROLES = AUTH_ROLES.filter((role) => role !== "guest");
|
||||
var AUTH_ROLE_LABELS = {
|
||||
guest: "Guest",
|
||||
read: "Read",
|
||||
control: "Control",
|
||||
transmit: "Transmit",
|
||||
write: "Write",
|
||||
administrator: "Administrator"
|
||||
};
|
||||
@@ -15,7 +16,7 @@ function normalizeAuthRoles(roles) {
|
||||
return AUTH_ROLES.filter((role) => roles.includes(role));
|
||||
}
|
||||
function hasAuthRole(roles, required) {
|
||||
return roles.includes("administrator") || roles.includes(required) || required === "read" && roles.includes("guest") || required === "read" && roles.includes("control");
|
||||
return roles.includes("administrator") || roles.includes(required) || required === "read" && roles.includes("guest") || required === "read" && (roles.includes("control") || roles.includes("transmit"));
|
||||
}
|
||||
function hasAccountControls(roles) {
|
||||
return roles.length > 0 && !roles.includes("guest");
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
hasAuthRole
|
||||
} from "./chunk-FT2RH7BL.js";
|
||||
} from "./chunk-PISLBJGN.js";
|
||||
import {
|
||||
hostCore,
|
||||
hostState
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
hasAuthRole
|
||||
} from "./chunk-FT2RH7BL.js";
|
||||
} from "./chunk-PISLBJGN.js";
|
||||
import {
|
||||
hostState
|
||||
} from "./chunk-KL66PICH.js";
|
||||
|
||||
Reference in New Issue
Block a user