Исправить DEVNET topup и автоподстановку пароля

This commit is contained in:
AidarKC 2026-06-03 15:57:49 +04:00
parent 239cc231ea
commit ee3721dfa4
9 changed files with 47 additions and 5 deletions

View File

@ -0,0 +1,15 @@
# Фикс DEVNET topup и автоподстановки пароля
- статус: pending
- кратко: исправлена ширина экрана `devnet-topup-view` после успешного пополнения и отключена нежелательная автоподстановка пароля в server UI и на экранах входа/регистрации.
## Что проверять
- Открыть страницу пополнения DEVNET, выполнить пополнение и убедиться, что после появления `Signature` экран не расширяется по ширине.
- Проверить, что кнопки на странице пополнения остаются аккуратными и не разъезжаются.
- Открыть `server-ui/update-server-pda.html`, загрузить PDA и убедиться, что поле пароля остаётся пустым.
- Проверить обычные экраны входа и регистрации: поле пароля не должно самопроизвольно заполняться длинной строкой.
## Ожидаемый результат
- Длинная transaction signature переносится по строкам внутри прежней ширины экрана.
- Кнопки сохраняют компактный mobile-first layout.
- Поля пароля пустые, пока пользователь сам ничего не вводил.

View File

@ -1,2 +1,2 @@
client.version=1.2.119 client.version=1.2.120
server.version=1.2.111 server.version=1.2.112

View File

@ -19,11 +19,14 @@ function readWalletFromUrl() {
export function render({ navigate }) { export function render({ navigate }) {
const screen = document.createElement('section'); const screen = document.createElement('section');
screen.className = 'stack'; screen.className = 'stack';
screen.style.width = '100%';
screen.style.justifyItems = 'center';
const targetWallet = readWalletFromUrl(); const targetWallet = readWalletFromUrl();
const senderBox = document.createElement('div'); const senderBox = document.createElement('div');
senderBox.className = 'card stack'; senderBox.className = 'card stack';
senderBox.style.width = 'min(100%, 320px)';
senderBox.innerHTML = ` senderBox.innerHTML = `
<strong>Тестовый DEVNET-кошелёк</strong> <strong>Тестовый DEVNET-кошелёк</strong>
<p class="meta-muted" id="devnet-topup-sender-address">Адрес: ...</p> <p class="meta-muted" id="devnet-topup-sender-address">Адрес: ...</p>
@ -32,6 +35,7 @@ export function render({ navigate }) {
const targetBox = document.createElement('div'); const targetBox = document.createElement('div');
targetBox.className = 'card stack'; targetBox.className = 'card stack';
targetBox.style.width = 'min(100%, 320px)';
targetBox.innerHTML = ` targetBox.innerHTML = `
<strong>Кошелёк получателя</strong> <strong>Кошелёк получателя</strong>
<p class="meta-muted" style="word-break:break-all;">${targetWallet || 'Не передан параметр wallet'}</p> <p class="meta-muted" style="word-break:break-all;">${targetWallet || 'Не передан параметр wallet'}</p>
@ -40,6 +44,10 @@ export function render({ navigate }) {
const status = document.createElement('p'); const status = document.createElement('p');
status.className = 'meta-muted'; status.className = 'meta-muted';
status.style.width = 'min(100%, 320px)';
status.style.overflowWrap = 'anywhere';
status.style.wordBreak = 'break-word';
status.style.whiteSpace = 'pre-wrap';
status.textContent = 'Готово к пополнению.'; status.textContent = 'Готово к пополнению.';
const fillBtn = document.createElement('button'); const fillBtn = document.createElement('button');
@ -55,6 +63,8 @@ export function render({ navigate }) {
const actions = document.createElement('div'); const actions = document.createElement('div');
actions.className = 'auth-footer-actions'; actions.className = 'auth-footer-actions';
actions.style.width = 'min(100%, 320px)';
actions.style.justifySelf = 'center';
actions.append(fillBtn, backBtn); actions.append(fillBtn, backBtn);
let senderAddress = ''; let senderAddress = '';
@ -90,7 +100,7 @@ export function render({ navigate }) {
amountSol: TRANSFER_AMOUNT_SOL, amountSol: TRANSFER_AMOUNT_SOL,
}); });
await updateSenderBalance(); await updateSenderBalance();
status.textContent = `Готово. Signature: ${tx.signature}`; status.textContent = `Готово.\nSignature: ${tx.signature}`;
} catch (error) { } catch (error) {
status.textContent = `Ошибка перевода: ${error?.message || 'unknown'}`; status.textContent = `Ошибка перевода: ${error?.message || 'unknown'}`;
} finally { } finally {

View File

@ -22,12 +22,19 @@ export function render({ navigate }) {
const loginInput = document.createElement('input'); const loginInput = document.createElement('input');
loginInput.className = 'input'; loginInput.className = 'input';
loginInput.type = 'text'; loginInput.type = 'text';
loginInput.autocomplete = 'off';
loginInput.autocapitalize = 'off';
loginInput.spellcheck = false;
loginInput.value = state.loginDraft.login; loginInput.value = state.loginDraft.login;
loginInput.placeholder = 'Введите логин'; loginInput.placeholder = 'Введите логин';
const passwordInput = document.createElement('input'); const passwordInput = document.createElement('input');
passwordInput.className = 'input'; passwordInput.className = 'input';
passwordInput.type = 'password'; passwordInput.type = 'password';
passwordInput.name = 'shine-login-password';
passwordInput.autocomplete = 'new-password';
passwordInput.autocapitalize = 'off';
passwordInput.spellcheck = false;
passwordInput.value = state.loginDraft.password; passwordInput.value = state.loginDraft.password;
passwordInput.placeholder = 'Введите пароль (можно оставить пустым)'; passwordInput.placeholder = 'Введите пароль (можно оставить пустым)';

View File

@ -21,12 +21,19 @@ export function render({ navigate }) {
const loginInput = document.createElement('input'); const loginInput = document.createElement('input');
loginInput.className = 'input'; loginInput.className = 'input';
loginInput.type = 'text'; loginInput.type = 'text';
loginInput.autocomplete = 'off';
loginInput.autocapitalize = 'off';
loginInput.spellcheck = false;
loginInput.value = state.registrationDraft.login; loginInput.value = state.registrationDraft.login;
loginInput.placeholder = 'Введите логин'; loginInput.placeholder = 'Введите логин';
const passwordInput = document.createElement('input'); const passwordInput = document.createElement('input');
passwordInput.className = 'input'; passwordInput.className = 'input';
passwordInput.type = 'password'; passwordInput.type = 'password';
passwordInput.name = 'shine-register-password';
passwordInput.autocomplete = 'new-password';
passwordInput.autocapitalize = 'off';
passwordInput.spellcheck = false;
passwordInput.value = state.registrationDraft.password; passwordInput.value = state.registrationDraft.password;
passwordInput.placeholder = 'Введите пароль (можно оставить пустым)'; passwordInput.placeholder = 'Введите пароль (можно оставить пустым)';

View File

@ -77,7 +77,7 @@
<div class="field"> <div class="field">
<label>Пароль</label> <label>Пароль</label>
<div class="pwd-wrap"> <div class="pwd-wrap">
<input type="password" id="password" placeholder="Пароль аккаунта сервера" autocomplete="new-password" /> <input type="password" id="password" name="server-ui-password-create" placeholder="Пароль аккаунта сервера" autocomplete="new-password" autocapitalize="off" spellcheck="false" />
<button class="btn-eye" id="btnEye" type="button">Показать</button> <button class="btn-eye" id="btnEye" type="button">Показать</button>
</div> </div>
<div class="hint">Нажмите «Сгенерировать» — поля ниже заполнятся из логина + пароля (Argon2id).<br/>Или введите ключи вручную.</div> <div class="hint">Нажмите «Сгенерировать» — поля ниже заполнятся из логина + пароля (Argon2id).<br/>Или введите ключи вручную.</div>

View File

@ -30,6 +30,7 @@ const fieldMap = {
setupPasswordEye($('btnEye'), $('password')); setupPasswordEye($('btnEye'), $('password'));
wireDeviceAddressPreview(fieldMap); wireDeviceAddressPreview(fieldMap);
$('password').value = '';
$('btnTopupDevnet').addEventListener('click', () => { $('btnTopupDevnet').addEventListener('click', () => {
try { try {

View File

@ -34,6 +34,7 @@ let currentPda = null;
setupPasswordEye($('btnEye'), $('password')); setupPasswordEye($('btnEye'), $('password'));
wireDeviceAddressPreview(fieldMap); wireDeviceAddressPreview(fieldMap);
$('password').value = '';
$('btnTopupDevnet').addEventListener('click', () => { $('btnTopupDevnet').addEventListener('click', () => {
try { try {
@ -87,6 +88,7 @@ $('btnLoad').addEventListener('click', async () => {
$('iBch').textContent = parsed.blockchain.blockchainName; $('iBch').textContent = parsed.blockchain.blockchainName;
$('iLimit').textContent = formatBigInt(parsed.blockchain.paidLimitBytes); $('iLimit').textContent = formatBigInt(parsed.blockchain.paidLimitBytes);
$('password').value = '';
$('serverAddress').value = parsed.serverAddress || ''; $('serverAddress').value = parsed.serverAddress || '';
$('syncServers').value = parsed.syncServers.join('\n'); $('syncServers').value = parsed.syncServers.join('\n');
$('pdaInfo').style.display = 'block'; $('pdaInfo').style.display = 'block';

View File

@ -92,7 +92,7 @@
<div class="field"> <div class="field">
<label>Пароль</label> <label>Пароль</label>
<div class="pwd-wrap"> <div class="pwd-wrap">
<input type="password" id="password" placeholder="Пароль аккаунта сервера" autocomplete="current-password" /> <input type="password" id="password" name="server-ui-password-update" placeholder="Пароль аккаунта сервера" autocomplete="new-password" autocapitalize="off" spellcheck="false" />
<button class="btn-eye" id="btnEye" type="button">Показать</button> <button class="btn-eye" id="btnEye" type="button">Показать</button>
</div> </div>
<div class="hint">Нажмите «Сгенерировать» — поля ниже заполнятся из логина + пароля.<br/>Или введите ключи вручную.</div> <div class="hint">Нажмите «Сгенерировать» — поля ниже заполнятся из логина + пароля.<br/>Или введите ключи вручную.</div>