v0.1.66: token input visible, display name in navbar
This commit is contained in:
@@ -275,14 +275,36 @@ const S = {
|
|||||||
telemetryAutoRefresh: false,
|
telemetryAutoRefresh: false,
|
||||||
telemetryRefreshTimer: null,
|
telemetryRefreshTimer: null,
|
||||||
telemetryDeviceFilter: '', // '' = все устройства
|
telemetryDeviceFilter: '', // '' = все устройства
|
||||||
|
|
||||||
|
// Отображаемое имя пользователя: email из JWT или plain token
|
||||||
|
displayName: localStorage.getItem('iot_display_name') || '',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Сохраняем auth-параметры в localStorage
|
// Сохраняем auth-параметры в localStorage
|
||||||
function saveSettings() {
|
function saveSettings() {
|
||||||
localStorage.setItem('iot_token', S.token);
|
localStorage.setItem('iot_token', S.token);
|
||||||
localStorage.setItem('iot_ns', S.ns); // сохраняем для восстановления сессии
|
localStorage.setItem('iot_ns', S.ns);
|
||||||
localStorage.setItem('iot_api_base', S.apiBase);
|
localStorage.setItem('iot_api_base', S.apiBase);
|
||||||
localStorage.setItem('iot_mqtt_base',S.mqttBase);
|
localStorage.setItem('iot_mqtt_base', S.mqttBase);
|
||||||
|
localStorage.setItem('iot_display_name', S.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// displayNameFromToken — возвращает человекочитаемое имя для отображения в navbar.
|
||||||
|
// JWT: берём email (предпочтительно) или sub. Plain token: сама строка.
|
||||||
|
function displayNameFromToken(token) {
|
||||||
|
const parts = token.split('.');
|
||||||
|
if (parts.length === 3) {
|
||||||
|
try {
|
||||||
|
let payload = parts[1].replace(/-/g, '+').replace(/_/g, '/');
|
||||||
|
while (payload.length % 4) payload += '=';
|
||||||
|
const claims = JSON.parse(atob(payload));
|
||||||
|
return claims.email || claims.sub || token;
|
||||||
|
} catch(e) {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Plain token — показываем как есть
|
||||||
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// namespaceFromToken — вычисляет k8s namespace из токена.
|
// namespaceFromToken — вычисляет k8s namespace из токена.
|
||||||
@@ -573,7 +595,7 @@ function renderLogin() {
|
|||||||
<div id="login-err"></div>
|
<div id="login-err"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Bearer токен <span style="color:#e08020;font-size:10px;font-weight:600;">· тестовый режим</span></label>
|
<label>Bearer токен <span style="color:#e08020;font-size:10px;font-weight:600;">· тестовый режим</span></label>
|
||||||
<input id="f-tok" type="password" value="${h(S.token)}" placeholder="любая-уникальная-строка или eyJ...JWT">
|
<input id="f-tok" type="text" value="${h(S.token)}" placeholder="любая-уникальная-строка или eyJ...JWT">
|
||||||
<div class="hint" style="margin-top:6px;">
|
<div class="hint" style="margin-top:6px;">
|
||||||
<b>Тест:</b> введите любую строку без пробелов — например <code>alice</code> или <code>my-device-test</code>.<br>
|
<b>Тест:</b> введите любую строку без пробелов — например <code>alice</code> или <code>my-device-test</code>.<br>
|
||||||
Каждая строка → отдельный изолированный namespace.<br>
|
Каждая строка → отдельный изолированный namespace.<br>
|
||||||
@@ -613,10 +635,11 @@ async function doLogin() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
S.apiBase = 'https://sless.kube5s.ru';
|
S.apiBase = 'https://sless.kube5s.ru';
|
||||||
S.mqttBase = 'wss://iot.kube5s.ru/mqtt';
|
S.mqttBase = 'wss://iot.kube5s.ru/mqtt';
|
||||||
S.ns = ns;
|
S.ns = ns;
|
||||||
S.token = tok;
|
S.token = tok;
|
||||||
|
S.displayName = displayNameFromToken(tok);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Создаём namespace если не существует — идемпотентный вызов.
|
// Создаём namespace если не существует — идемпотентный вызов.
|
||||||
@@ -1253,6 +1276,7 @@ function navbar() {
|
|||||||
<span class="navbar-logo-product">IoT Console</span>
|
<span class="navbar-logo-product">IoT Console</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-spacer"></div>
|
<div class="navbar-spacer"></div>
|
||||||
|
${S.displayName ? `<span style="font-size:13px;color:#7eb8e0;margin-right:12px;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="${h(S.displayName)}">${h(S.displayName)}</span>` : ''}
|
||||||
<button class="btn btn-ghost btn-sm" onclick="doLogout()">Выйти</button>
|
<button class="btn btn-ghost btn-sm" onclick="doLogout()">Выйти</button>
|
||||||
</nav>`;
|
</nav>`;
|
||||||
}
|
}
|
||||||
@@ -1260,8 +1284,10 @@ function navbar() {
|
|||||||
function doLogout() {
|
function doLogout() {
|
||||||
mqttStopAuto();
|
mqttStopAuto();
|
||||||
mqttCleanup();
|
mqttCleanup();
|
||||||
S.token = '';
|
S.token = '';
|
||||||
|
S.displayName = '';
|
||||||
localStorage.removeItem('iot_token');
|
localStorage.removeItem('iot_token');
|
||||||
|
localStorage.removeItem('iot_display_name');
|
||||||
nav('login');
|
nav('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user