SHiNE-server/shine-UI/js/pages/registration-draft-keys-view.js

141 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { renderHeader } from '../components/header.js';
import { state } from '../state.js';
import { bytesToBase64 } from '../services/crypto-utils.js';
import { extractSeed32FromPkcs8B64 } from '../services/device-key-utils.js';
export const pageMeta = { id: 'registration-draft-keys-view', title: 'Сгенерированные ключи', showAppChrome: false };
function makeSecretField({ label, value }) {
const wrap = document.createElement('div');
wrap.className = 'stack';
const labelEl = document.createElement('span');
labelEl.className = 'field-label';
labelEl.textContent = label;
const row = document.createElement('div');
row.className = 'inline-input-row';
const input = document.createElement('input');
input.className = 'input';
input.type = 'password';
input.readOnly = true;
input.value = value;
const toggleBtn = document.createElement('button');
toggleBtn.className = 'ghost-btn';
toggleBtn.type = 'button';
toggleBtn.textContent = 'Показать';
toggleBtn.addEventListener('click', () => {
if (input.type === 'password') {
input.type = 'text';
toggleBtn.textContent = 'Скрыть';
} else {
input.type = 'password';
toggleBtn.textContent = 'Показать';
}
});
row.append(input, toggleBtn);
wrap.append(labelEl, row);
return wrap;
}
function makePublicField({ label, value }) {
const wrap = document.createElement('div');
wrap.className = 'stack';
const labelEl = document.createElement('span');
labelEl.className = 'field-label';
labelEl.textContent = label;
const input = document.createElement('input');
input.className = 'input';
input.type = 'text';
input.readOnly = true;
input.value = value;
wrap.append(labelEl, input);
return wrap;
}
export function render({ navigate }) {
const screen = document.createElement('section');
screen.className = 'stack';
const keyBundle = state.registrationDraft.preGeneratedKeyBundle;
const card = document.createElement('div');
card.className = 'card stack';
if (!keyBundle) {
const msg = document.createElement('p');
msg.className = 'status-line is-unavailable';
msg.textContent = 'Ключи ещё не сгенерированы. Вернитесь на экран регистрации и введите логин с паролем.';
card.append(msg);
} else {
const warning = document.createElement('p');
warning.className = 'meta-muted';
warning.textContent =
'Никому не сообщайте приватные ключи и секрет. Они не хранятся на сервере и существуют только на вашем устройстве.';
card.append(warning);
// Секрет (root key seed)
let secretB64 = '';
try {
const rootSeed32 = extractSeed32FromPkcs8B64(keyBundle.rootPair.privatePkcs8B64);
secretB64 = bytesToBase64(rootSeed32);
} catch {
secretB64 = '(не удалось извлечь)';
}
card.append(makeSecretField({ label: 'Секрет (root seed, 32 байта)', value: secretB64 }));
// Root key
const rootSep = document.createElement('p');
rootSep.className = 'field-label';
rootSep.textContent = 'Root key';
card.append(rootSep);
card.append(makePublicField({ label: 'Root — публичный', value: keyBundle.rootPair.publicKeyB64 }));
card.append(makeSecretField({ label: 'Root — приватный (PKCS8)', value: keyBundle.rootPair.privatePkcs8B64 }));
// Blockchain key
const bchSep = document.createElement('p');
bchSep.className = 'field-label';
bchSep.textContent = 'Blockchain key';
card.append(bchSep);
card.append(makePublicField({ label: 'Blockchain — публичный', value: keyBundle.blockchainPair.publicKeyB64 }));
card.append(makeSecretField({ label: 'Blockchain — приватный (PKCS8)', value: keyBundle.blockchainPair.privatePkcs8B64 }));
// Device key
const devSep = document.createElement('p');
devSep.className = 'field-label';
devSep.textContent = 'Device key (= Solana wallet)';
card.append(devSep);
card.append(makePublicField({ label: 'Device — публичный', value: keyBundle.devicePair.publicKeyB64 }));
card.append(makeSecretField({ label: 'Device — приватный (PKCS8)', value: keyBundle.devicePair.privatePkcs8B64 }));
}
const actions = document.createElement('div');
actions.className = 'auth-footer-actions';
const backButton = document.createElement('button');
backButton.className = 'ghost-btn';
backButton.type = 'button';
backButton.textContent = 'Назад';
backButton.addEventListener('click', () => navigate('registration-payment-view'));
actions.append(backButton);
screen.append(
renderHeader({
title: 'Сгенерированные ключи',
leftAction: { label: '←', onClick: () => navigate('registration-payment-view') },
}),
card,
actions,
);
return screen;
}