SHA256
Доработать вложенные файлы и архив проекта
This commit is contained in:
@@ -9,6 +9,7 @@ function defaultParsed(rawText = '') {
|
||||
replyRef: null,
|
||||
callSummary: null,
|
||||
fileAttachment: null,
|
||||
fileAttachments: [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -97,17 +98,46 @@ function decodeFileField(value = '') {
|
||||
}
|
||||
|
||||
function normalizeFileAttachment(fields = {}) {
|
||||
const version = Number(fields.v || 0);
|
||||
const id = String(fields.id || '').trim();
|
||||
const url = decodeFileField(fields.url || '').trim();
|
||||
const keyB64Url = String(fields.key || '').trim();
|
||||
const ivB64Url = String(fields.iv || '').trim();
|
||||
const name = decodeFileField(fields.name || '').trim() || 'file';
|
||||
const mime = decodeFileField(fields.mime || '').trim() || 'application/octet-stream';
|
||||
const size = Number(fields.size || 0);
|
||||
const encryptedSize = Number(fields.encsize || 0);
|
||||
if (!id || !url || !keyB64Url || !ivB64Url || !Number.isFinite(size) || size < 0) return null;
|
||||
if (!id || !url || !keyB64Url || !Number.isFinite(size) || size < 0) return null;
|
||||
|
||||
if (version >= 2) {
|
||||
const ivPrefixB64Url = String(fields.ivp || '').trim();
|
||||
if (!ivPrefixB64Url) return null;
|
||||
const chunkSize = Number(fields.chunk || 0);
|
||||
const chunkCount = Number(fields.chunks || 0);
|
||||
const kind = String(fields.kind || 'file').trim().toLowerCase() === 'voice' ? 'voice' : 'file';
|
||||
const durationMs = Math.max(0, Math.floor(Number(fields.dur || 0)));
|
||||
return {
|
||||
version,
|
||||
id,
|
||||
url,
|
||||
keyB64Url,
|
||||
ivPrefixB64Url,
|
||||
name,
|
||||
mime,
|
||||
size,
|
||||
encryptedSize: Number.isFinite(encryptedSize) && encryptedSize > 0 ? encryptedSize : 0,
|
||||
chunkSize: Number.isFinite(chunkSize) && chunkSize > 0 ? chunkSize : 0,
|
||||
chunkCount: Number.isFinite(chunkCount) && chunkCount >= 0 ? Math.floor(chunkCount) : 0,
|
||||
torrentV2InfoHashB64Url: String(fields.th || '').trim(),
|
||||
torrentV2PiecesRootB64Url: String(fields.pr || '').trim(),
|
||||
kind,
|
||||
durationMs,
|
||||
};
|
||||
}
|
||||
|
||||
const ivB64Url = String(fields.iv || '').trim();
|
||||
if (!ivB64Url) return null;
|
||||
return {
|
||||
version: Number(fields.v || 0),
|
||||
version: version || 1,
|
||||
id,
|
||||
url,
|
||||
keyB64Url,
|
||||
@@ -116,20 +146,37 @@ function normalizeFileAttachment(fields = {}) {
|
||||
mime,
|
||||
size,
|
||||
encryptedSize: Number.isFinite(encryptedSize) && encryptedSize > 0 ? encryptedSize : 0,
|
||||
kind: 'file',
|
||||
durationMs: 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildDmFileTechBlock(attachment = {}) {
|
||||
const version = Math.max(1, Math.floor(Number(attachment?.version || 1)));
|
||||
const id = String(attachment?.id || '').trim();
|
||||
const url = String(attachment?.url || '').trim();
|
||||
const keyB64Url = String(attachment?.keyB64Url || '').trim();
|
||||
const ivB64Url = String(attachment?.ivB64Url || '').trim();
|
||||
const size = Math.max(0, Math.floor(Number(attachment?.size || 0)));
|
||||
const encryptedSize = Math.max(0, Math.floor(Number(attachment?.encryptedSize || 0)));
|
||||
if (!id || !url || !keyB64Url || !ivB64Url) throw new Error('Не хватает данных для технического блока файла');
|
||||
if (!id || !url || !keyB64Url) throw new Error('Не хватает данных для технического блока файла');
|
||||
const name = encodeURIComponent(String(attachment?.name || 'file'));
|
||||
const mime = encodeURIComponent(String(attachment?.mime || 'application/octet-stream'));
|
||||
const encodedUrl = encodeURIComponent(url);
|
||||
|
||||
if (version >= 2) {
|
||||
const ivPrefix = String(attachment?.ivPrefixB64Url || '').trim();
|
||||
if (!ivPrefix) throw new Error('Не хватает IV prefix для chunked-файла');
|
||||
const chunkSize = Math.max(0, Math.floor(Number(attachment?.chunkSize || 0)));
|
||||
const chunkCount = Math.max(0, Math.floor(Number(attachment?.chunkCount || 0)));
|
||||
const torrentHash = String(attachment?.torrentV2InfoHashB64Url || '').trim();
|
||||
const piecesRoot = String(attachment?.torrentV2PiecesRootB64Url || '').trim();
|
||||
const kind = String(attachment?.kind || 'file') === 'voice' ? 'voice' : 'file';
|
||||
const durationMs = Math.max(0, Math.floor(Number(attachment?.durationMs || 0)));
|
||||
return `<S:file;v=2;id=${id};url=${encodedUrl};key=${keyB64Url};ivp=${ivPrefix};name=${name};mime=${mime};size=${size};encsize=${encryptedSize};chunk=${chunkSize};chunks=${chunkCount};th=${torrentHash};pr=${piecesRoot};kind=${kind};dur=${durationMs}>`;
|
||||
}
|
||||
|
||||
const ivB64Url = String(attachment?.ivB64Url || '').trim();
|
||||
if (!ivB64Url) throw new Error('Не хватает IV для файла v1');
|
||||
return `<S:file;v=1;id=${id};url=${encodedUrl};key=${keyB64Url};iv=${ivB64Url};name=${name};mime=${mime};size=${size};encsize=${encryptedSize}>`;
|
||||
}
|
||||
|
||||
@@ -142,6 +189,7 @@ export function parseDmTechBlocks(rawText = '') {
|
||||
let replyRef = null;
|
||||
let callSummary = null;
|
||||
let fileAttachment = null;
|
||||
const fileAttachments = [];
|
||||
|
||||
while (hasTechPrefix(text, cursor)) {
|
||||
const end = text.indexOf('>', cursor);
|
||||
@@ -189,8 +237,12 @@ export function parseDmTechBlocks(rawText = '') {
|
||||
reason: String(fields.reason || '').trim().toLowerCase(),
|
||||
};
|
||||
}
|
||||
} else if (kind === 'file' && !fileAttachment) {
|
||||
fileAttachment = normalizeFileAttachment(fields);
|
||||
} else if (kind === 'file') {
|
||||
const attachment = normalizeFileAttachment(fields);
|
||||
if (attachment) {
|
||||
fileAttachments.push(attachment);
|
||||
if (!fileAttachment) fileAttachment = attachment;
|
||||
}
|
||||
}
|
||||
|
||||
cursor = end + 1;
|
||||
@@ -207,5 +259,6 @@ export function parseDmTechBlocks(rawText = '') {
|
||||
replyRef,
|
||||
callSummary,
|
||||
fileAttachment,
|
||||
fileAttachments,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user