UI: каналы 1..32, публичный type=1 и актуальный prevLine перед записью

This commit is contained in:
AidarKC
2026-05-14 17:58:16 +03:00
parent 01b38952e5
commit ab31ccf6d8
6 changed files with 55 additions and 58 deletions
+43 -11
View File
@@ -791,14 +791,21 @@ export class AuthService {
if (!cleanLogin) throw new Error('Missing login for AddBlock');
if (!storagePwd) throw new Error('Missing storagePwd for AddBlock signing');
const user = await this.getUser(cleanLogin);
const blockchainName = String(user?.blockchainName || `${cleanLogin}-${BCH_SUFFIX}`).trim();
const freshNum = Number(user?.serverLastGlobalNumber);
const freshHash = normalizeHex32(user?.serverLastGlobalHash, ZERO64);
const freshCursor = {
serverLastGlobalNumber: Number.isFinite(freshNum) ? freshNum : -1,
serverLastGlobalHash: freshHash,
const resolveFreshCursor = async () => {
const user = await this.getUser(cleanLogin);
const blockchainName = String(user?.blockchainName || `${cleanLogin}-${BCH_SUFFIX}`).trim();
const freshNum = Number(user?.serverLastGlobalNumber);
const freshHash = normalizeHex32(user?.serverLastGlobalHash, ZERO64);
return {
blockchainName,
cursor: {
serverLastGlobalNumber: Number.isFinite(freshNum) ? freshNum : -1,
serverLastGlobalHash: freshHash,
},
};
};
const freshState = await resolveFreshCursor();
const blockchainName = freshState.blockchainName;
const savedKeys = await loadEncryptedUserSecrets(cleanLogin, storagePwd);
const blockchainPrivatePkcs8 = savedKeys?.blockchainKey;
@@ -832,7 +839,7 @@ export class AuthService {
});
};
let cursor = freshCursor;
let cursor = freshState.cursor;
let response = await tryAdd(cursor);
if (response.status !== 200) {
const knownNum = Number(response?.payload?.serverLastGlobalNumber);
@@ -840,6 +847,10 @@ export class AuthService {
if (Number.isFinite(knownNum) && /^[0-9a-fA-F]{64}$/.test(knownHash)) {
cursor = { serverLastGlobalNumber: knownNum, serverLastGlobalHash: knownHash.toLowerCase() };
response = await tryAdd(cursor);
} else {
const refreshed = await resolveFreshCursor();
cursor = refreshed.cursor;
response = await tryAdd(cursor);
}
}
@@ -1211,11 +1222,32 @@ export class AuthService {
rootHashHex = normalizeHex32(rootChannel.rootBlockHash, ZERO64);
}
let prevLineNumber = lineCode;
let prevLineHashHex = rootHashHex;
let thisLineNumber = 0;
try {
const latestPayload = await this.getChannelMessages({
ownerBlockchainName,
channelRootBlockNumber: lineCode,
channelRootBlockHash: rootHashHex,
}, 1, 'desc', cleanLogin);
const latestMessage = Array.isArray(latestPayload?.messages) ? latestPayload.messages[0] : null;
const latestBlockNumber = Number(latestMessage?.messageRef?.blockNumber);
const latestBlockHash = normalizeHex32(latestMessage?.messageRef?.blockHash, '');
if (Number.isFinite(latestBlockNumber) && latestBlockNumber >= 0 && latestBlockHash) {
prevLineNumber = latestBlockNumber;
prevLineHashHex = latestBlockHash;
thisLineNumber = latestBlockNumber + 1;
}
} catch {
// fallback to root anchor
}
const bodyBytes = makeTextPostBodyBytes({
lineCode,
prevLineNumber: lineCode,
prevLineHashHex: rootHashHex,
thisLineNumber: 0,
prevLineNumber,
prevLineHashHex,
thisLineNumber,
text: cleanText,
});
+2 -2
View File
@@ -1,4 +1,4 @@
const MIN_LEN = 3;
const MIN_LEN = 1;
const MAX_LEN = 32;
const ALLOWED_CHARS_RE = /^[A-Za-z0-9_-]+$/;
@@ -54,7 +54,7 @@ export function channelNameErrorText(code) {
case 'blank':
return 'Введите название канала.';
case 'too_short':
return 'Название слишком короткое: минимум 3 символа.';
return 'Название слишком короткое: минимум 1 символ.';
case 'too_long':
return 'Название слишком длинное: максимум 32 символа.';
case 'bad_chars':
+2 -1
View File
@@ -55,9 +55,10 @@ export function toUserMessage(error, fallback = 'Действие не выпо
text.includes('channel name must match') ||
text.includes('channelname contains unsupported') ||
text.includes('channelname length must be 3..32') ||
text.includes('channelname length must be 1..32') ||
text.includes('bad_channel_name')
) {
return 'Некорректное название канала. Разрешены кириллица, латиница, цифры, пробел, _ и - (3..32 символа).';
return 'Некорректное название канала. Разрешены кириллица, латиница, цифры, пробел, _ и - (1..32 символа).';
}
if (text.includes('channel name is required') || text.includes('введите имя канала')) {