feat: restrict user permissions and multi-node IP constraints (#262)

* feat: restrict user permissions and multi-node IP constraints

- Non-admin users cannot set speedId or inPort on forward create/update
- Multi-entrance tunnels disable custom listen IP for forwards
- Multi-exit tunnels disable custom connect IP
- Multi-node hop chains disable custom connect IP per hop
- Remove tunnel-first-IP fallback in forward ingress resolution
- Add contract tests for non-admin permission restrictions

Entire-Checkpoint: 133693290660

* fix: allow non-admin users to submit null speedId and zero inPort

- Backend: Check speedId is not nil before rejecting non-admin requests
- Backend: Only reject inPort if value > 0 for non-admin users
- Frontend: Only include speedId and inPort in payload for admin users
- Tests: Add contract tests for null speedId and zero inPort cases

* refactor: simplify forward mutation payload construction
This commit is contained in:
sagit
2026-03-04 15:05:05 +08:00
committed by GitHub
parent a43653f252
commit 9703e4a081
+2 -3
View File
@@ -1426,9 +1426,8 @@ export default function ForwardPage() {
const speedLimitAutoCleared = isMissingSpeedLimit(form.speedId);
if (isEdit) {
const updateData: ForwardMutationPayload = {
const updateData = {
id: form.id,
userId: form.userId,
name: form.name,
tunnelId: form.tunnelId,
...(isAdmin ? { inPort: form.inPort } : {}),
@@ -1440,7 +1439,7 @@ export default function ForwardPage() {
res = await updateForward(updateData);
} else {
const createData: ForwardMutationPayload = {
const createData = {
name: form.name,
tunnelId: form.tunnelId,
...(isAdmin ? { inPort: form.inPort } : {}),