Manage master keys through the external API
API keys now see a set of servers instead of one, and /api/v1 gains the master-key operations the panel already had. - api_key_servers holds each key's servers (migrated from server_id, which stays the default server for /api/v1/users). /users follows X-Server-Id within the set; a server outside it is 404. PATCH /ui/apikeys/:id changes the set without reissuing the key. - /api/v1/masterkeys: create (returns the sen:// link), list, get with link and devices, patch label/limit/servers, rotate, rekey, delete, and nested device routes (unlink, rekey, PSK). A key sees a master key only if all of its servers are in the key's set, so it cannot delete or re-point service on a server it cannot see; anything else is 404, servers outside the set are 403. Creating refuses with 503 before writing anything if the subscription cannot issue links. - sub.ts: the panel routes and the API share one service layer, the panel's behaviour is unchanged. - Node deletion: owners check in beforeDelete (no writes, a later hook may still veto) and clean up in afterDelete. Previously a forced delete could release a waiting master key and then be vetoed. A node that is the only server of an API key is refused; other keys just lose it. - Panel: server checkboxes are a shared ServerPicker, used by the master key settings and the new API key settings row; the API keys table shows each key's servers. - README: the API section covers server sets and master keys.
This commit is contained in:
@@ -149,24 +149,6 @@ LICENSE file in the root directory of this source tree.
|
||||
.mk-meter--full { --meter-fill: var(--error-dot); --meter-on: #fff; } /* лимит — красный */
|
||||
:root[data-theme="dark"] .mk-meter--full { --meter-on: #2a2118; }
|
||||
|
||||
/* серверы, отдаваемые по ключу (заглушка) */
|
||||
.mk-server {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
background: var(--surface-container);
|
||||
border-radius: 12px;
|
||||
padding: 10px 14px;
|
||||
font-size: 13px;
|
||||
color: var(--on-surface);
|
||||
}
|
||||
.mk-server input { accent-color: var(--primary); margin: 0; }
|
||||
.mk-server-name { font-weight: 500; }
|
||||
.mk-server-ip, .mk-server-gen { font-size: 12px; color: var(--neutral-text); }
|
||||
.mk-server-ip { font-family: var(--mono); margin-left: auto; }
|
||||
.mk-server { cursor: pointer; }
|
||||
.mk-server:hover { background: var(--state-primary); }
|
||||
.mk-server--locked { cursor: default; }
|
||||
.mk-server--locked:hover { background: var(--surface-container); }
|
||||
.mk-server-dot { padding: 0; background: none; }
|
||||
.mk-box .tip-wrap { width: 100%; }
|
||||
|
||||
/* дети: вертикальная линия слева и «ножка» к каждому узлу */
|
||||
|
||||
Reference in New Issue
Block a user