SHA256
Убрали старый sync и обновили bundle
Что сделано: вычистили неиспользуемый user-settings sync/DM sync хвост, сохранили сборку, обновили bundle.sh так, чтобы gradle-wrapper.jar всегда попадал в архив. Проверено: compileJava и deploy на t2 (server + UI). Не проверяли: полные интеграционные сценарии, ручные UI-флоу и продовый деплой.
This commit is contained in:
@@ -6,8 +6,8 @@ import { resolveShineServerByServerLogin } from '../services/shine-server-resolv
|
||||
import { readShineUserPda, updateShineUserPdaOnSolana } from '../services/shine-user-pda-service.js';
|
||||
import { getTopupSiteUrl } from '../services/solana-wallet-service.js';
|
||||
|
||||
export const pageMeta = { id: 'access-servers-view', title: 'Серверы доступа' };
|
||||
const MAX_ACCESS_SERVERS = 2;
|
||||
export const pageMeta = { id: 'access-servers-view', title: 'Сервер доступа' };
|
||||
const MAX_ACCESS_SERVERS = 1;
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value || '')
|
||||
@@ -281,9 +281,10 @@ export function render({ navigate }) {
|
||||
introCard.innerHTML = `
|
||||
<p class="field-label">Где хранятся личные данные</p>
|
||||
<p class="meta-muted">
|
||||
Серверы доступа хранят зашифрованную личную переписку пользователя и участвуют в звонках.
|
||||
Единственный сервер доступа хранит зашифрованную личную переписку пользователя и участвует в звонках.
|
||||
Всё, что публикуется в блокчейне SHiNE, доступно через любой сервер Сияния,
|
||||
а доступ пользователя и приватная переписка хранятся только на этих серверах.
|
||||
а настройки и приватная переписка хранятся только на выбранном сервере.
|
||||
При смене сервера прежняя переписка и настройки автоматически не переносятся.
|
||||
</p>
|
||||
`;
|
||||
|
||||
@@ -291,7 +292,7 @@ export function render({ navigate }) {
|
||||
listCard.className = 'card stack';
|
||||
const listTitle = document.createElement('p');
|
||||
listTitle.className = 'field-label';
|
||||
listTitle.textContent = 'Текущий список серверов доступа';
|
||||
listTitle.textContent = 'Текущий сервер доступа';
|
||||
const listHint = document.createElement('p');
|
||||
listHint.className = 'meta-muted';
|
||||
listHint.textContent = sessionLogin
|
||||
@@ -308,10 +309,10 @@ export function render({ navigate }) {
|
||||
addCard.className = 'card stack';
|
||||
const addTitle = document.createElement('p');
|
||||
addTitle.className = 'field-label';
|
||||
addTitle.textContent = 'Добавить сервер доступа';
|
||||
addTitle.textContent = 'Сменить сервер доступа';
|
||||
const addHint = document.createElement('p');
|
||||
addHint.className = 'meta-muted';
|
||||
addHint.textContent = 'Можно использовать максимум два сервера доступа. Введите логин сервера или несколько первых букв, затем выберите сервер из подсказок.';
|
||||
addHint.textContent = 'Введите логин нового сервера или несколько первых букв, затем выберите сервер из подсказок. Новый сервер заменит текущий.';
|
||||
const addInput = document.createElement('input');
|
||||
addInput.className = 'input';
|
||||
addInput.type = 'text';
|
||||
@@ -326,13 +327,12 @@ export function render({ navigate }) {
|
||||
const addButton = document.createElement('button');
|
||||
addButton.className = 'primary-btn';
|
||||
addButton.type = 'button';
|
||||
addButton.textContent = 'Добавить сервер';
|
||||
addButton.textContent = 'Сменить сервер';
|
||||
addButton.disabled = true;
|
||||
addCard.append(addTitle, addHint, addInput, suggestEl, addStatus, addButton);
|
||||
|
||||
const refreshAddButton = () => {
|
||||
addButton.disabled = operationBusy
|
||||
|| currentAccessServers.length >= MAX_ACCESS_SERVERS
|
||||
|| (!selectedCandidate && !normalizeLogin(addInput.value));
|
||||
};
|
||||
|
||||
@@ -352,9 +352,7 @@ export function render({ navigate }) {
|
||||
addInput.value = candidate.login;
|
||||
addStatus.textContent = `Выбран сервер @${candidate.login}${candidate.url ? ` (${candidate.url})` : ''}`;
|
||||
} else {
|
||||
addStatus.textContent = currentAccessServers.length >= MAX_ACCESS_SERVERS
|
||||
? 'У пользователя уже выбраны два сервера доступа. Сначала отключите один из них.'
|
||||
: 'Для изменения списка понадобится подпись root key.';
|
||||
addStatus.textContent = 'Для смены сервера понадобится подпись root key.';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -368,69 +366,15 @@ export function render({ navigate }) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentAccessServers.forEach((server, index) => {
|
||||
const button = document.createElement('button');
|
||||
button.className = 'text-btn';
|
||||
button.type = 'button';
|
||||
button.disabled = operationBusy;
|
||||
button.innerHTML = `
|
||||
currentAccessServers.forEach((server) => {
|
||||
const row = document.createElement('div');
|
||||
row.innerHTML = `
|
||||
<span style="display:block; text-align:left;">
|
||||
<strong>@${escapeHtml(server.login)}</strong>
|
||||
<span class="meta-muted" style="display:block; margin-top:0.2rem;">${escapeHtml(server.url || 'URL не указан')}</span>
|
||||
</span>
|
||||
`;
|
||||
button.addEventListener('click', () => {
|
||||
if (operationBusy) return;
|
||||
const isLast = currentAccessServers.length <= 1;
|
||||
const performDisable = async () => {
|
||||
const nextList = currentAccessServers
|
||||
.map((item) => item.login)
|
||||
.filter((login) => login !== server.login);
|
||||
try {
|
||||
await updateAccessServers(nextList, {
|
||||
statusTarget: listStatus,
|
||||
successText: `Сервер доступа @${server.login} отключён.`,
|
||||
inFlightText: `Обновляем PDA и отключаем сервер @${server.login}...`,
|
||||
});
|
||||
} catch {
|
||||
// Сообщение уже показано в статусе.
|
||||
}
|
||||
};
|
||||
|
||||
const askFinal = (noteText = '') => {
|
||||
confirmModal?.open({
|
||||
title: isLast ? 'Последний сервер доступа' : 'Отключить сервер доступа?',
|
||||
text: isLast
|
||||
? 'Это последний сервер доступа пользователя. Если его отключить, личная переписка пользователя на серверах доступа будет удалена.'
|
||||
: `Хотите изменить запись в блокчейне Solana и отключить сервер доступа @${server.login}?`,
|
||||
note: noteText,
|
||||
confirmLabel: isLast ? 'Понимаю' : 'Да',
|
||||
cancelLabel: isLast ? 'Отмена' : 'Нет',
|
||||
onConfirm: performDisable,
|
||||
});
|
||||
};
|
||||
|
||||
if (isLast) {
|
||||
confirmModal?.open({
|
||||
title: 'Отключить последний сервер?',
|
||||
text: `У пользователя остался только один сервер доступа: @${server.login}.`,
|
||||
note: 'После отключения последнего сервера доступа личная переписка пользователя на серверах доступа будет удалена.',
|
||||
confirmLabel: 'Продолжить',
|
||||
cancelLabel: 'Отмена',
|
||||
onConfirm: () => askFinal('Это повторное предупреждение перед записью нового списка серверов в Solana PDA.'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
askFinal();
|
||||
});
|
||||
listBody.append(button);
|
||||
if (index < currentAccessServers.length - 1) {
|
||||
const divider = document.createElement('div');
|
||||
divider.style.height = '1px';
|
||||
divider.style.background = 'rgba(255,255,255,0.08)';
|
||||
listBody.append(divider);
|
||||
}
|
||||
listBody.append(row);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -465,16 +409,13 @@ export function render({ navigate }) {
|
||||
renderServerList();
|
||||
refreshAddButton();
|
||||
listStatus.textContent = rows.length
|
||||
? `Найдено серверов доступа: ${rows.length}`
|
||||
? 'Сервер доступа загружен из PDA.'
|
||||
: 'В PDA пользователя пока нет серверов доступа.';
|
||||
if (rows.length >= MAX_ACCESS_SERVERS) {
|
||||
addStatus.textContent = 'У пользователя уже выбраны два сервера доступа. Сначала отключите один из них.';
|
||||
}
|
||||
} catch (error) {
|
||||
currentAccessServers = [];
|
||||
renderServerList();
|
||||
refreshAddButton();
|
||||
listStatus.textContent = error?.message || 'Не удалось прочитать список серверов доступа.';
|
||||
listStatus.textContent = error?.message || 'Не удалось прочитать сервер доступа.';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -559,7 +500,7 @@ export function render({ navigate }) {
|
||||
|
||||
const passwordResult = await passwordModal?.open({
|
||||
title: 'Нужен пароль для обновления серверов доступа',
|
||||
text: 'Чтобы изменить список серверов доступа, нужно подписать обновление user PDA через root key. Этот ключ не найден в локальном зашифрованном контейнере устройства.',
|
||||
text: 'Чтобы изменить сервер доступа, нужно подписать обновление user PDA через root key. Этот ключ не найден в локальном зашифрованном контейнере устройства.',
|
||||
note: savedClient
|
||||
? 'client key уже сохранён на устройстве. Из пароля будет восстановлен только root key.'
|
||||
: 'На устройстве не хватает root key и/или client key. Они будут восстановлены из пароля аккаунта.',
|
||||
@@ -604,7 +545,7 @@ export function render({ navigate }) {
|
||||
|
||||
const normalizedList = uniqueLogins(nextLogins);
|
||||
setOperationBusy(true);
|
||||
target.textContent = String(inFlightText || 'Обновляем список серверов доступа...');
|
||||
target.textContent = String(inFlightText || 'Обновляем сервер доступа...');
|
||||
let signingMaterial = null;
|
||||
try {
|
||||
const currentPda = await readShineUserPda({ login: sessionLogin, solanaEndpoint });
|
||||
@@ -626,7 +567,7 @@ export function render({ navigate }) {
|
||||
if (isInsufficientFundsForRentError(error)) {
|
||||
showTopupRequiredStatus(target, signingMaterial?.clientAddress);
|
||||
} else {
|
||||
target.textContent = error?.message || 'Не удалось обновить список серверов доступа.';
|
||||
target.textContent = error?.message || 'Не удалось обновить сервер доступа.';
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
@@ -662,29 +603,25 @@ export function render({ navigate }) {
|
||||
return;
|
||||
}
|
||||
if (currentAccessServers.some((item) => item.login === login)) {
|
||||
addStatus.textContent = `Сервер @${login} уже есть в списке.`;
|
||||
return;
|
||||
}
|
||||
if (currentAccessServers.length >= MAX_ACCESS_SERVERS) {
|
||||
addStatus.textContent = 'Нельзя добавить больше двух серверов доступа. Сначала отключите один из текущих.';
|
||||
addStatus.textContent = `Сервер @${login} уже выбран.`;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const resolved = await resolveShineServerByServerLogin({ serverLogin: login, solanaEndpoint });
|
||||
confirmModal?.open({
|
||||
title: 'Добавить сервер доступа?',
|
||||
text: `Вы хотите добавить сервер доступа @${resolved.serverLogin}?`,
|
||||
title: 'Сменить сервер доступа?',
|
||||
text: `Заменить текущий сервер доступа на @${resolved.serverLogin}?`,
|
||||
note: resolved.httpBase
|
||||
? `Адрес сервера: ${resolved.httpBase}\nИзменение будет записано в Solana user PDA.`
|
||||
: 'Изменение будет записано в Solana user PDA.',
|
||||
? `Адрес сервера: ${resolved.httpBase}\nПрежняя переписка и настройки автоматически не перенесутся. Изменение будет записано в Solana user PDA.`
|
||||
: 'Прежняя переписка и настройки автоматически не перенесутся. Изменение будет записано в Solana user PDA.',
|
||||
onConfirm: async () => {
|
||||
const nextList = uniqueLogins([...currentAccessServers.map((item) => item.login), resolved.serverLogin]);
|
||||
const nextList = [resolved.serverLogin];
|
||||
try {
|
||||
await updateAccessServers(nextList, {
|
||||
statusTarget: addStatus,
|
||||
successText: `Сервер доступа @${resolved.serverLogin} добавлен.`,
|
||||
inFlightText: `Обновляем PDA и добавляем сервер @${resolved.serverLogin}...`,
|
||||
successText: `Сервер доступа заменён на @${resolved.serverLogin}.`,
|
||||
inFlightText: `Обновляем PDA и меняем сервер на @${resolved.serverLogin}...`,
|
||||
});
|
||||
} catch {
|
||||
// Сообщение уже показано в статусе.
|
||||
@@ -698,7 +635,7 @@ export function render({ navigate }) {
|
||||
|
||||
screen.append(
|
||||
renderHeader({
|
||||
title: 'Серверы доступа',
|
||||
title: 'Сервер доступа',
|
||||
leftAction: { label: '←', onClick: () => navigate('settings-view') },
|
||||
}),
|
||||
introCard,
|
||||
|
||||
@@ -44,7 +44,7 @@ export function render({ navigate }) {
|
||||
<button class="text-btn" type="button" id="settings-remote-addblock">Remote AddBlock через homeserver</button>
|
||||
<button class="text-btn" type="button" id="settings-access-servers">
|
||||
<span style="display:block; text-align:left;">
|
||||
<strong>Серверы доступа</strong>
|
||||
<strong>Сервер доступа</strong>
|
||||
<span class="meta-muted" style="display:block; margin-top:0.2rem;">Личная переписка, звонки и зашифрованные данные</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user