GPT: сгенерено и не проверено (смена ключей пользователя)

This commit is contained in:
AidarKC
2026-09-27 15:50:27 +03:00
parent 13693a0a53
commit 151a2c1754
94 changed files with 5327 additions and 815 deletions
+90 -64
View File
@@ -553,31 +553,31 @@ function makeUserParamBodyBytes({ lineCode, prevLineNumber, prevLineHashHex, thi
);
}
function makeReactionLikeBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHex }) {
const cleanBch = String(toBlockchainName || '').trim();
if (!cleanBch) throw new Error('toBlockchainName is required for like');
function makeReactionLikeBodyBytes({ toLogin, toBlockNumber, toBlockHashHex }) {
const cleanLogin = String(toLogin || '').trim();
if (!cleanLogin) throw new Error('toLogin is required for like');
const blockNumber = Number(toBlockNumber);
if (!Number.isFinite(blockNumber) || blockNumber < 0) {
throw new Error('Invalid toBlockNumber for like');
}
const bchBytes = utf8Bytes(cleanBch);
if (bchBytes.length < 1 || bchBytes.length > 255) {
throw new Error('toBlockchainName must be 1..255 bytes');
const loginBytes = utf8Bytes(cleanLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) {
throw new Error('toLogin must be 1..255 bytes');
}
return concatBytes(
int8Byte(bchBytes.length),
bchBytes,
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(blockNumber),
hexToBytes(normalizeHex32(toBlockHashHex))
);
}
function makeTextReplyBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHex, text }) {
const cleanBch = String(toBlockchainName || '').trim();
if (!cleanBch) throw new Error('toBlockchainName is required for reply');
function makeTextReplyBodyBytes({ toLogin, toBlockNumber, toBlockHashHex, text }) {
const cleanLogin = String(toLogin || '').trim();
if (!cleanLogin) throw new Error('toLogin is required for reply');
const blockNumber = Number(toBlockNumber);
if (!Number.isFinite(blockNumber) || blockNumber < 0) {
@@ -587,9 +587,9 @@ function makeTextReplyBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHe
const message = String(text || '').trim();
if (!message) throw new Error('Reply text is required');
const bchBytes = utf8Bytes(cleanBch);
if (bchBytes.length < 1 || bchBytes.length > 255) {
throw new Error('toBlockchainName must be 1..255 bytes');
const loginBytes = utf8Bytes(cleanLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) {
throw new Error('toLogin must be 1..255 bytes');
}
const textBytes = utf8Bytes(message);
@@ -598,8 +598,8 @@ function makeTextReplyBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHe
}
return concatBytes(
int8Byte(bchBytes.length),
bchBytes,
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(blockNumber),
hexToBytes(normalizeHex32(toBlockHashHex)),
int16Bytes(textBytes.length),
@@ -607,9 +607,9 @@ function makeTextReplyBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHe
);
}
function makeTextRatingBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHex, text }) {
const cleanBch = String(toBlockchainName || '').trim();
if (!cleanBch) throw new Error('toBlockchainName is required for rating');
function makeTextRatingBodyBytes({ toLogin, toBlockNumber, toBlockHashHex, text }) {
const cleanLogin = String(toLogin || '').trim();
if (!cleanLogin) throw new Error('toLogin is required for rating');
const blockNumber = Number(toBlockNumber);
if (!Number.isFinite(blockNumber) || blockNumber < 0) {
@@ -619,9 +619,9 @@ function makeTextRatingBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashH
const message = String(text || '').trim();
if (!message) throw new Error('Rating text is required');
const bchBytes = utf8Bytes(cleanBch);
if (bchBytes.length < 1 || bchBytes.length > 255) {
throw new Error('toBlockchainName must be 1..255 bytes');
const loginBytes = utf8Bytes(cleanLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) {
throw new Error('toLogin must be 1..255 bytes');
}
const textBytes = utf8Bytes(message);
@@ -630,8 +630,8 @@ function makeTextRatingBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashH
}
return concatBytes(
int8Byte(bchBytes.length),
bchBytes,
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(blockNumber),
hexToBytes(normalizeHex32(toBlockHashHex)),
int16Bytes(textBytes.length),
@@ -639,18 +639,18 @@ function makeTextRatingBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashH
);
}
function makeStatusActionBodyBytes({ toBlockchainName, toBlockNumber, toBlockHashHex, text = '' }) {
const cleanBch = String(toBlockchainName || '').trim();
if (!cleanBch) throw new Error('toBlockchainName is required for status action');
function makeStatusActionBodyBytes({ toLogin, toBlockNumber, toBlockHashHex, text = '' }) {
const cleanLogin = String(toLogin || '').trim();
if (!cleanLogin) throw new Error('toLogin is required for status action');
const blockNumber = Number(toBlockNumber);
if (!Number.isFinite(blockNumber) || blockNumber < 0) {
throw new Error('Invalid toBlockNumber for status action');
}
const bchBytes = utf8Bytes(cleanBch);
if (bchBytes.length < 1 || bchBytes.length > 255) {
throw new Error('toBlockchainName must be 1..255 bytes');
const loginBytes = utf8Bytes(cleanLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) {
throw new Error('toLogin must be 1..255 bytes');
}
const textBytes = utf8Bytes(String(text || '').trim());
@@ -659,8 +659,8 @@ function makeStatusActionBodyBytes({ toBlockchainName, toBlockNumber, toBlockHas
}
return concatBytes(
int8Byte(bchBytes.length),
bchBytes,
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(blockNumber),
hexToBytes(normalizeHex32(toBlockHashHex)),
int16Bytes(textBytes.length),
@@ -673,7 +673,7 @@ function makeTextRepostBodyBytes({
prevLineNumber,
prevLineHashHex,
thisLineNumber,
toBlockchainName,
toLogin,
toBlockNumber,
toBlockHashHex,
text,
@@ -681,11 +681,11 @@ function makeTextRepostBodyBytes({
const message = String(text || '').trim();
if (!message) throw new Error('Комментарий к репосту обязателен');
const bch = String(toBlockchainName || '').trim();
if (!bch) throw new Error('toBlockchainName is required for repost');
const bchBytes = utf8Bytes(bch);
if (bchBytes.length < 1 || bchBytes.length > 255) {
throw new Error('toBlockchainName must be 1..255 bytes');
const cleanTargetLogin = String(toLogin || '').trim();
if (!cleanTargetLogin) throw new Error('toLogin is required for repost');
const loginBytes = utf8Bytes(cleanTargetLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) {
throw new Error('toLogin must be 1..255 bytes');
}
const blockNumber = Number(toBlockNumber);
@@ -703,8 +703,8 @@ function makeTextRepostBodyBytes({
int32Bytes(prevLineNumber),
hexToBytes(normalizeHex32(prevLineHashHex)),
int32Bytes(thisLineNumber),
int8Byte(bchBytes.length),
bchBytes,
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(blockNumber),
hexToBytes(normalizeHex32(toBlockHashHex)),
int16Bytes(textBytes.length),
@@ -717,11 +717,16 @@ function makeTextEditPostBodyBytes({
prevLineNumber,
prevLineHashHex,
thisLineNumber,
toLogin,
toBlockNumber,
toBlockHashHex,
text,
}) {
const message = String(text || '').trim();
const cleanTargetLogin = String(toLogin || '').trim();
if (!cleanTargetLogin) throw new Error('toLogin is required for edit post');
const loginBytes = utf8Bytes(cleanTargetLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) throw new Error('toLogin must be 1..255 bytes');
const targetBlockNumber = Number(toBlockNumber);
if (!Number.isFinite(targetBlockNumber) || targetBlockNumber < 0) {
throw new Error('Invalid target block number for edit post');
@@ -736,6 +741,8 @@ function makeTextEditPostBodyBytes({
int32Bytes(prevLineNumber),
hexToBytes(normalizeHex32(prevLineHashHex)),
int32Bytes(thisLineNumber),
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(targetBlockNumber),
hexToBytes(normalizeHex32(toBlockHashHex)),
int16Bytes(textBytes.length),
@@ -743,8 +750,12 @@ function makeTextEditPostBodyBytes({
);
}
function makeTextEditReplyBodyBytes({ toBlockNumber, toBlockHashHex, text }) {
function makeTextEditReplyBodyBytes({ toLogin, toBlockNumber, toBlockHashHex, text }) {
const message = String(text || '').trim();
const cleanTargetLogin = String(toLogin || '').trim();
if (!cleanTargetLogin) throw new Error('toLogin is required for edit reply');
const loginBytes = utf8Bytes(cleanTargetLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) throw new Error('toLogin must be 1..255 bytes');
const targetBlockNumber = Number(toBlockNumber);
if (!Number.isFinite(targetBlockNumber) || targetBlockNumber < 0) {
throw new Error('Invalid target block number for edit reply');
@@ -755,6 +766,8 @@ function makeTextEditReplyBodyBytes({ toBlockNumber, toBlockHashHex, text }) {
}
return concatBytes(
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(targetBlockNumber),
hexToBytes(normalizeHex32(toBlockHashHex)),
int16Bytes(textBytes.length),
@@ -767,21 +780,21 @@ function makeConnectionBodyBytes({
prevLineNumber = -1,
prevLineHashHex = ZERO64,
thisLineNumber = -1,
toBlockchainName,
toLogin,
toBlockNumber,
toBlockHashHex,
}) {
const cleanBch = String(toBlockchainName || '').trim();
if (!cleanBch) throw new Error('toBlockchainName is required for connection');
const cleanTargetLogin = String(toLogin || '').trim();
if (!cleanTargetLogin) throw new Error('toLogin is required for connection');
const blockNumber = Number(toBlockNumber);
if (!Number.isFinite(blockNumber) || blockNumber < 0) {
throw new Error('Invalid toBlockNumber for connection');
}
const bchBytes = utf8Bytes(cleanBch);
if (bchBytes.length < 1 || bchBytes.length > 255) {
throw new Error('toBlockchainName must be 1..255 bytes');
const loginBytes = utf8Bytes(cleanTargetLogin);
if (loginBytes.length < 1 || loginBytes.length > 255) {
throw new Error('toLogin must be 1..255 bytes');
}
return concatBytes(
@@ -789,8 +802,8 @@ function makeConnectionBodyBytes({
int32Bytes(prevLineNumber),
hexToBytes(normalizeHex32(prevLineHashHex)),
int32Bytes(thisLineNumber),
int8Byte(bchBytes.length),
bchBytes,
int8Byte(loginBytes.length),
loginBytes,
int32Bytes(blockNumber),
hexToBytes(normalizeHex32(toBlockHashHex))
);
@@ -938,13 +951,20 @@ function makeTextLineBodyBytesAllowEmpty({ lineCode, prevLineNumber, prevLineHas
);
}
function normalizeMessageRefTarget(target, actionName = 'action') {
const cleanBch = String(target?.blockchainName || '').trim();
const cleanBlockNumber = Number(target?.blockNumber);
const cleanBlockHash = String(target?.blockHash || '').trim().toLowerCase();
function loginFromBlockchainNameValue(value) {
const name = String(value || '').trim();
const match = name.match(/^(.*)-\d{3}$/u);
return match?.[1] ? match[1] : '';
}
if (!cleanBch) {
throw new Error(`Missing message target blockchain for ${actionName}`);
function normalizeMessageRefTarget(target, actionName = 'action') {
const cleanBch = String(target?.blockchainName || target?.authorBlockchainName || '').trim();
const cleanLogin = String(target?.login || target?.authorLogin || target?.ownerLogin || loginFromBlockchainNameValue(cleanBch)).trim();
const cleanBlockNumber = Number(target?.blockNumber ?? target?.messageRef?.blockNumber);
const cleanBlockHash = String(target?.blockHash ?? target?.messageRef?.blockHash ?? '').trim().toLowerCase();
if (!cleanLogin) {
throw new Error(`Missing message target login for ${actionName}`);
}
if (!Number.isFinite(cleanBlockNumber) || cleanBlockNumber < 0) {
throw new Error(`Invalid message target block number for ${actionName}`);
@@ -954,6 +974,7 @@ function normalizeMessageRefTarget(target, actionName = 'action') {
}
return {
login: cleanLogin,
blockchainName: cleanBch,
blockNumber: cleanBlockNumber,
blockHash: cleanBlockHash,
@@ -1892,7 +1913,7 @@ export class AuthService {
return this.runWriteLocked(key, async () => {
const bodyBytes = makeReactionLikeBodyBytes({
toBlockchainName: target.blockchainName,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
});
@@ -1915,7 +1936,7 @@ export class AuthService {
return this.runWriteLocked(key, async () => {
const bodyBytes = makeReactionLikeBodyBytes({
toBlockchainName: target.blockchainName,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
});
@@ -1939,7 +1960,7 @@ export class AuthService {
return this.runWriteLocked(key, async () => {
const bodyBytes = makeTextReplyBodyBytes({
toBlockchainName: target.blockchainName,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
text: cleanText,
@@ -1964,7 +1985,7 @@ export class AuthService {
return this.runWriteLocked(key, async () => {
const bodyBytes = makeTextRatingBodyBytes({
toBlockchainName: target.blockchainName,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
text: cleanText,
@@ -2004,7 +2025,7 @@ export class AuthService {
return this.runWriteLocked(key, async () => {
const bodyBytes = makeStatusActionBodyBytes({
toBlockchainName: target.blockchainName,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
text: cleanText,
@@ -2077,7 +2098,7 @@ export class AuthService {
prevLineNumber,
prevLineHashHex,
thisLineNumber,
toBlockchainName: target.blockchainName,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
text: cleanText,
@@ -2159,6 +2180,7 @@ export class AuthService {
prevLineNumber,
prevLineHashHex,
thisLineNumber,
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
text: cleanText,
@@ -2176,6 +2198,7 @@ export class AuthService {
}
const bodyBytes = makeTextEditReplyBodyBytes({
toLogin: target.login,
toBlockNumber: target.blockNumber,
toBlockHashHex: target.blockHash,
text: cleanText,
@@ -2206,6 +2229,7 @@ export class AuthService {
return this.addBlockFollowChannel({
login: cleanLogin,
storagePwd,
targetLogin: cleanTargetLogin,
targetBlockchainName: targetUser.blockchainName,
targetBlockNumber: 0,
targetBlockHashHex: targetHeaderHash,
@@ -2217,6 +2241,7 @@ export class AuthService {
async addBlockFollowChannel({
login,
storagePwd,
targetLogin = '',
targetBlockchainName,
targetBlockNumber,
targetBlockHashHex,
@@ -2224,8 +2249,10 @@ export class AuthService {
}) {
const cleanLogin = String(login || '').trim();
const cleanTargetBch = String(targetBlockchainName || '').trim();
const cleanTargetLogin = String(targetLogin || loginFromBlockchainNameValue(cleanTargetBch)).trim();
const cleanTargetBlockNumber = Number(targetBlockNumber);
if (!cleanTargetBch) throw new Error('Target blockchain is required');
if (!cleanTargetLogin) throw new Error('Target login is required');
if (!Number.isFinite(cleanTargetBlockNumber) || cleanTargetBlockNumber < 0) {
throw new Error('Invalid target block number');
}
@@ -2245,7 +2272,7 @@ export class AuthService {
prevLineNumber: -1,
prevLineHashHex: ZERO64,
thisLineNumber: -1,
toBlockchainName: cleanTargetBch,
toLogin: cleanTargetLogin,
toBlockNumber: cleanTargetBlockNumber,
toBlockHashHex: targetHashHex,
});
@@ -3228,13 +3255,12 @@ export class AuthService {
const targetUser = await this.getUser(cleanToLogin);
if (!targetUser?.exists) throw new Error('Пользователь цели не найден.');
const toBlockchainName = String(targetUser?.blockchainName || `${cleanToLogin}-${BCH_SUFFIX}`).trim();
const bodyBytes = makeConnectionBodyBytes({
lineCode: 0,
prevLineNumber: -1,
prevLineHashHex: ZERO_HASH_HEX,
thisLineNumber: -1,
toBlockchainName,
toLogin: cleanToLogin,
toBlockNumber: 0,
toBlockHashHex: ZERO_HASH_HEX,
});