SHA256
GPT: сгенерено и не проверено (смена ключей пользователя)
This commit is contained in:
@@ -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,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user