@melandlabs/integrations-telegram 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/adapter.d.ts +2 -2
- package/dist/adapter.js +3 -3
- package/dist/adapter.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/tdata-converter.js +2 -2
- package/dist/tdata-converter.js.map +1 -1
- package/package.json +6 -6
package/dist/tdata-converter.js
CHANGED
|
@@ -3,8 +3,8 @@ import * as crypto from 'crypto';
|
|
|
3
3
|
import * as fs2 from 'fs';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import { AuthKey } from 'telegram/crypto/AuthKey';
|
|
7
|
-
import { StringSession } from 'telegram/sessions';
|
|
6
|
+
import { AuthKey } from 'telegram/crypto/AuthKey.js';
|
|
7
|
+
import { StringSession } from 'telegram/sessions/index.js';
|
|
8
8
|
|
|
9
9
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
10
|
var __esm = (fn, res) => function __init() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tdata-decrypter/crypto.ts","../src/tdata-decrypter/qt.ts","../src/tdata-decrypter/settings.ts","../src/tdata-decrypter/storage.ts","../src/tdata-decrypter/tdf.ts","../src/tdata-decrypter/decrypter.ts","../src/tdata-decrypter/index.ts","../src/tdata-converter.ts"],"names":["Buffer","crypto2","fs","crypto3","__filename","path2"],"mappings":"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","file":"tdata-converter.js","sourcesContent":["// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Cryptography utilities for Telegram Desktop tdata decryption.\n * Ported from telegram-tdata-decrypter crypto.py\n *\n * AES-256-IGE implementation based on:\n * https://gist.github.com/f4ddf6e7a859b837f996b3f50097153a\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as crypto from \"node:crypto\";\n\nconst LocalEncryptNoPwdIterCount = 4;\nconst LocalEncryptIterCount = 400;\nconst kStrongIterationsCount = 100000;\n\nexport class CryptoException extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"CryptoException\";\n\t}\n}\n\n/**\n * XOR two buffers in place\n */\nfunction xorBuffer(a: Buffer, b: Buffer): void {\n\tfor (let i = 0; i < a.length; i++) {\n\t\ta.writeUInt8(a.readUInt8(i) ^ b.readUInt8(i), i);\n\t}\n}\n\n/**\n * AES-256-IGE encrypt/decrypt\n */\nfunction igeCrypt(buffer: Buffer, aesKey: Buffer, aesIv: Buffer, isEncrypt: boolean): Buffer {\n\t// AES-256-ECB cipher (no IV, we handle IGE manually)\n\tconst cipher = isEncrypt\n\t\t? crypto.createCipheriv(\"aes-256-ecb\", aesKey, null)\n\t\t: crypto.createDecipheriv(\"aes-256-ecb\", aesKey, null);\n\n\tcipher.setAutoPadding(false);\n\n\tconst result = Buffer.allocUnsafe(buffer.length);\n\n\t// IGE uses IV as two 16-byte blocks\n\tlet prevCipherblock: Buffer;\n\tlet prevPlainblock: Buffer;\n\n\tif (isEncrypt) {\n\t\tprevCipherblock = aesIv.subarray(0, 16); // IV1\n\t\tprevPlainblock = aesIv.subarray(16, 32); // IV2\n\t} else {\n\t\t// For decryption, swap the order\n\t\tprevCipherblock = aesIv.subarray(16, 32); // IV2\n\t\tprevPlainblock = aesIv.subarray(0, 16); // IV1\n\t}\n\n\tconst current = Buffer.allocUnsafe(16);\n\n\tfor (let offset = 0; offset < buffer.length; offset += 16) {\n\t\tconst chunk = buffer.subarray(offset, offset + 16);\n\t\tchunk.copy(current);\n\n\t\t// IGE: XOR with previous cipher block before AES\n\t\txorBuffer(current, prevCipherblock);\n\n\t\t// AES encryption/decryption\n\t\tconst crypted = Buffer.from(cipher.update(current));\n\n\t\t// IGE: XOR with previous plaintext block after AES\n\t\txorBuffer(crypted, prevPlainblock);\n\n\t\tcrypted.copy(result, offset);\n\n\t\tprevCipherblock = crypted;\n\t\tprevPlainblock = chunk;\n\t}\n\n\t// Finalize (should produce empty buffer for full blocks)\n\tcipher.final();\n\n\treturn result;\n}\n\n/**\n * Create local key from passcode and salt\n */\nexport function createLocalKey(passcode: Buffer, salt: Buffer): Buffer {\n\tconst iterations = passcode.length > 0 ? kStrongIterationsCount : 1;\n\n\tconst password = crypto.createHash(\"sha512\");\n\tpassword.update(salt);\n\tpassword.update(passcode);\n\tpassword.update(salt);\n\n\treturn crypto.pbkdf2Sync(password.digest(), salt, iterations, 256, \"sha512\");\n}\n\n/**\n * Create legacy local key (for older Telegram Desktop versions)\n */\nexport function createLegacyLocalKey(passcode: Buffer, salt: Buffer): Buffer {\n\tconst iterations = passcode.length > 0 ? LocalEncryptIterCount : LocalEncryptNoPwdIterCount;\n\n\treturn crypto.pbkdf2Sync(passcode, salt, iterations, 256, \"sha1\");\n}\n\n/**\n * Decrypt local encrypted data\n */\nexport function decryptLocal(encryptedMsg: Buffer, localKey: Buffer): Buffer {\n\tconst msgKey = encryptedMsg.subarray(0, 16);\n\tconst encryptedData = encryptedMsg.subarray(16);\n\n\tconst decrypted = aesDecryptLocal(encryptedData, msgKey, localKey);\n\n\t// Verify SHA1 hash\n\tconst sha1 = crypto.createHash(\"sha1\");\n\tsha1.update(decrypted);\n\tconst calculatedMsgKey = sha1.digest().subarray(0, 16);\n\n\tif (calculatedMsgKey.compare(msgKey) !== 0) {\n\t\tthrow new CryptoException(\"bad decrypt key, data not decrypted - incorrect password\");\n\t}\n\n\t// Read length\n\tconst length = decrypted.readUInt32LE(0);\n\tif (length > decrypted.length) {\n\t\tthrow new CryptoException(`corrupted data. wrong length: ${length}`);\n\t}\n\n\treturn decrypted.subarray(4, 4 + length);\n}\n\n/**\n * AES-256-IGE decrypt for local data\n */\nexport function aesDecryptLocal(encryptedData: Buffer, msgKey: Buffer, localKey: Buffer): Buffer {\n\tconst { aesKey, aesIv } = prepareAesOldMtp(localKey, msgKey, false);\n\treturn igeCrypt(encryptedData, aesKey, aesIv, false);\n}\n\n/**\n * Prepare AES key and IV for old MTProto format\n */\ninterface AesKeyIv {\n\taesKey: Buffer;\n\taesIv: Buffer;\n}\n\nexport function prepareAesOldMtp(localKey: Buffer, msgKey: Buffer, send = false): AesKeyIv {\n\tconst x = send ? 0 : 8;\n\n\tconst keyPos = (pos: number, size: number): Buffer => {\n\t\treturn localKey.subarray(pos, pos + size);\n\t};\n\n\tconst dataA = Buffer.concat([msgKey, keyPos(x, 32)]);\n\tconst dataB = Buffer.concat([keyPos(x + 32, 16), msgKey, keyPos(x + 48, 16)]);\n\tconst dataC = Buffer.concat([keyPos(x + 64, 32), msgKey]);\n\tconst dataD = Buffer.concat([msgKey, keyPos(x + 96, 32)]);\n\n\tconst sha1A = crypto.createHash(\"sha1\").update(dataA).digest();\n\tconst sha1B = crypto.createHash(\"sha1\").update(dataB).digest();\n\tconst sha1C = crypto.createHash(\"sha1\").update(dataC).digest();\n\tconst sha1D = crypto.createHash(\"sha1\").update(dataD).digest();\n\n\tconst aesKey = Buffer.concat([sha1A.subarray(0, 8), sha1B.subarray(8, 20), sha1C.subarray(4, 16)]);\n\n\tconst aesIv = Buffer.concat([\n\t\tsha1A.subarray(8, 20),\n\t\tsha1B.subarray(0, 8),\n\t\tsha1C.subarray(16, 20),\n\t\tsha1D.subarray(0, 8),\n\t]);\n\n\treturn { aesKey, aesIv };\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Qt binary data format reader utilities.\n * Ported from telegram-tdata-decrypter qt.py\n */\n\nimport { Buffer } from \"node:buffer\";\n\n/**\n * Read N bytes from buffer\n */\nexport function readBytes(buffer: Buffer, offset: number, size: number): Buffer {\n\tif (offset + size > buffer.length) {\n\t\tthrow new Error(`Cannot read ${size} bytes at offset ${offset}, buffer length is ${buffer.length}`);\n\t}\n\treturn buffer.subarray(offset, offset + size);\n}\n\n/**\n * Read integer in big-endian format\n */\nexport function readQtInteger(buffer: Buffer, offset: number, size: number, signed: boolean): number {\n\tconst value = readBytes(buffer, offset, size);\n\tconst hex = value.toString(\"hex\");\n\n\t// Convert to number (big-endian)\n\tlet num = BigInt(`0x${hex}`);\n\n\tif (signed && num >= BigInt(2) ** BigInt(size * 8 - 1)) {\n\t\tnum -= BigInt(2) ** BigInt(size * 8);\n\t}\n\n\t// Convert to Number (safe for 32-bit, for 64-bit return as Number but may lose precision)\n\treturn Number(num);\n}\n\n/**\n * Read 32-bit signed integer (big-endian)\n */\nexport function readQtInt32(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 4, true);\n}\n\n/**\n * Read 32-bit unsigned integer (big-endian)\n */\nexport function readQtUint32(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 4, false);\n}\n\n/**\n * Read 64-bit signed integer (big-endian)\n */\nexport function readQtInt64(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 8, true);\n}\n\n/**\n * Read 64-bit unsigned integer (big-endian)\n */\nexport function readQtUint64(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 8, false);\n}\n\n/**\n * Read byte array (length-prefixed)\n * Returns { value, newOffset }\n */\nexport interface ReadResult<T> {\n\tvalue: T;\n\tnewOffset: number;\n}\n\nexport function readQtByteArray(buffer: Buffer, offset: number): ReadResult<Buffer> {\n\tconst length = readQtInt32(buffer, offset);\n\tlet newOffset = offset + 4;\n\n\tif (length <= 0) {\n\t\treturn { value: Buffer.alloc(0), newOffset };\n\t}\n\n\tconst value = readBytes(buffer, newOffset, length);\n\tnewOffset += length;\n\n\treturn { value, newOffset };\n}\n\n/**\n * Read UTF-16 string (byte array decoded as UTF-16)\n */\nexport function readQtUtf8(buffer: Buffer, offset: number): ReadResult<string> {\n\tconst { value, newOffset } = readQtByteArray(buffer, offset);\n\t// The original Python code decodes as utf16\n\tconst str = value.toString(\"utf16le\");\n\treturn { value: str, newOffset };\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Settings block reader.\n * Ported from telegram-tdata-decrypter settings.py\n */\n\nimport type { Buffer } from \"node:buffer\";\nimport { readQtByteArray, readQtInt32, readQtUint64, readQtUtf8 } from \"./qt\";\n\n/**\n * Settings block IDs\n */\nexport enum SettingsBlocks {\n\tdbiKey = 0x00,\n\tdbiUser = 0x01,\n\tdbiDcOptionOldOld = 0x02,\n\tdbiChatSizeMaxOld = 0x03,\n\tdbiMutePeerOld = 0x04,\n\tdbiSendKeyOld = 0x05,\n\tdbiAutoStart = 0x06,\n\tdbiStartMinimized = 0x07,\n\tdbiSoundFlashBounceNotifyOld = 0x08,\n\tdbiWorkModeOld = 0x09,\n\tdbiSeenTrayTooltip = 0x0a,\n\tdbiDesktopNotifyOld = 0x0b,\n\tdbiAutoUpdate = 0x0c,\n\tdbiLastUpdateCheck = 0x0d,\n\tdbiWindowPositionOld = 0x0e,\n\tdbiConnectionTypeOldOld = 0x0f,\n\tdbiDefaultAttach = 0x11,\n\tdbiCatsAndDogsOld = 0x12,\n\tdbiReplaceEmojiOld = 0x13,\n\tdbiAskDownloadPathOld = 0x14,\n\tdbiDownloadPathOldOld = 0x15,\n\tdbiScaleOld = 0x16,\n\tdbiEmojiTabOld = 0x17,\n\tdbiRecentEmojiOldOldOld = 0x18,\n\tdbiLoggedPhoneNumberOld = 0x19,\n\tdbiMutedPeersOld = 0x1a,\n\tdbiNotifyViewOld = 0x1c,\n\tdbiSendToMenu = 0x1d,\n\tdbiCompressPastedImageOld = 0x1e,\n\tdbiLangOld = 0x1f,\n\tdbiLangFileOld = 0x20,\n\tdbiTileBackgroundOld = 0x21,\n\tdbiAutoLockOld = 0x22,\n\tdbiDialogLastPath = 0x23,\n\tdbiRecentEmojiOldOld = 0x24,\n\tdbiEmojiVariantsOldOld = 0x25,\n\tdbiRecentStickers = 0x26,\n\tdbiDcOptionOld = 0x27,\n\tdbiTryIPv6Old = 0x28,\n\tdbiSongVolumeOld = 0x29,\n\tdbiWindowsNotificationsOld = 0x30,\n\tdbiIncludeMutedOld = 0x31,\n\tdbiMegagroupSizeMaxOld = 0x32,\n\tdbiDownloadPathOld = 0x33,\n\tdbiAutoDownloadOld = 0x34,\n\tdbiSavedGifsLimitOld = 0x35,\n\tdbiShowingSavedGifsOld = 0x36,\n\tdbiAutoPlayOld = 0x37,\n\tdbiAdaptiveForWideOld = 0x38,\n\tdbiHiddenPinnedMessagesOld = 0x39,\n\tdbiRecentEmojiOld = 0x3a,\n\tdbiEmojiVariantsOld = 0x3b,\n\tdbiDialogsModeOld = 0x40,\n\tdbiModerateModeOld = 0x41,\n\tdbiVideoVolumeOld = 0x42,\n\tdbiStickersRecentLimitOld = 0x43,\n\tdbiNativeNotificationsOld = 0x44,\n\tdbiNotificationsCountOld = 0x45,\n\tdbiNotificationsCornerOld = 0x46,\n\tdbiThemeKeyOld = 0x47,\n\tdbiDialogsWidthRatioOld = 0x48,\n\tdbiUseExternalVideoPlayerOld = 0x49,\n\tdbiDcOptionsOld = 0x4a,\n\tdbiMtpAuthorization = 0x4b,\n\tdbiLastSeenWarningSeenOld = 0x4c,\n\tdbiSessionSettings = 0x4d,\n\tdbiLangPackKey = 0x4e,\n\tdbiConnectionTypeOld = 0x4f,\n\tdbiStickersFavedLimitOld = 0x50,\n\tdbiSuggestStickersByEmojiOld = 0x51,\n\tdbiSuggestEmojiOld = 0x52,\n\tdbiTxtDomainStringOldOld = 0x53,\n\tdbiThemeKey = 0x54,\n\tdbiTileBackground = 0x55,\n\tdbiCacheSettingsOld = 0x56,\n\tdbiPowerSaving = 0x57,\n\tdbiScalePercent = 0x58,\n\tdbiPlaybackSpeedOld = 0x59,\n\tdbiLanguagesKey = 0x5a,\n\tdbiCallSettingsOld = 0x5b,\n\tdbiCacheSettings = 0x5c,\n\tdbiTxtDomainStringOld = 0x5d,\n\tdbiApplicationSettings = 0x5e,\n\tdbiDialogsFiltersOld = 0x5f,\n\tdbiFallbackProductionConfig = 0x60,\n\tdbiBackgroundKey = 0x61,\n\tdbiEncryptedWithSalt = 333,\n\tdbiEncrypted = 444,\n\tdbiVersion = 666,\n}\n\n/**\n * Read settings block value based on block ID\n */\nexport function readSettingsBlock(\n\tversion: number,\n\tbuffer: Buffer,\n\toffset: number,\n\tblockId: SettingsBlocks,\n): { value: unknown; newOffset: number } {\n\tswitch (blockId) {\n\t\tcase SettingsBlocks.dbiAutoStart:\n\t\tcase SettingsBlocks.dbiStartMinimized:\n\t\tcase SettingsBlocks.dbiSendToMenu:\n\t\tcase SettingsBlocks.dbiSeenTrayTooltip:\n\t\tcase SettingsBlocks.dbiAutoUpdate: {\n\t\t\tconst value = readQtInt32(buffer, offset) === 1;\n\t\t\treturn { value, newOffset: offset + 4 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiSongVolumeOld: {\n\t\t\tconst value = readQtInt32(buffer, offset) / 1e6;\n\t\t\treturn { value, newOffset: offset + 4 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiLastUpdateCheck:\n\t\tcase SettingsBlocks.dbiScalePercent:\n\t\tcase SettingsBlocks.dbiPowerSaving: {\n\t\t\tconst value = readQtInt32(buffer, offset);\n\t\t\treturn { value, newOffset: offset + 4 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiFallbackProductionConfig:\n\t\tcase SettingsBlocks.dbiApplicationSettings: {\n\t\t\tconst { value, newOffset } = readQtByteArray(buffer, offset);\n\t\t\treturn { value, newOffset };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiDialogLastPath: {\n\t\t\tconst { value, newOffset } = readQtUtf8(buffer, offset);\n\t\t\treturn { value, newOffset };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiThemeKey: {\n\t\t\tconst day = readQtUint64(buffer, offset);\n\t\t\tconst night = readQtUint64(buffer, offset + 8);\n\t\t\tconst nightMode = readQtInt32(buffer, offset + 16) === 1;\n\t\t\treturn {\n\t\t\t\tvalue: { day, night, nightMode },\n\t\t\t\tnewOffset: offset + 20,\n\t\t\t};\n\t\t}\n\n\t\tcase SettingsBlocks.dbiBackgroundKey: {\n\t\t\tconst day = readQtUint64(buffer, offset);\n\t\t\tconst night = readQtUint64(buffer, offset + 8);\n\t\t\treturn {\n\t\t\t\tvalue: { day, night },\n\t\t\t\tnewOffset: offset + 16,\n\t\t\t};\n\t\t}\n\n\t\tcase SettingsBlocks.dbiTileBackground: {\n\t\t\tconst day = readQtInt32(buffer, offset);\n\t\t\tconst night = readQtInt32(buffer, offset + 4);\n\t\t\treturn {\n\t\t\t\tvalue: { day, night },\n\t\t\t\tnewOffset: offset + 8,\n\t\t\t};\n\t\t}\n\n\t\tcase SettingsBlocks.dbiLangPackKey: {\n\t\t\tconst value = readQtUint64(buffer, offset);\n\t\t\treturn { value, newOffset: offset + 8 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiMtpAuthorization: {\n\t\t\tconst { value, newOffset } = readQtByteArray(buffer, offset);\n\t\t\treturn { value, newOffset };\n\t\t}\n\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown block ID while reading settings: ${blockId}`);\n\t}\n}\n\n/**\n * Read all settings blocks from buffer\n */\nexport function readSettingsBlocks(version: number, buffer: Buffer): Map<SettingsBlocks, unknown> {\n\tconst blocks = new Map<SettingsBlocks, unknown>();\n\tlet offset = 0;\n\n\ttry {\n\t\twhile (offset < buffer.length) {\n\t\t\tconst blockId = readQtInt32(buffer, offset) as SettingsBlocks;\n\t\t\toffset += 4;\n\n\t\t\tconst { value, newOffset } = readSettingsBlock(version, buffer, offset, blockId);\n\t\t\toffset = newOffset;\n\n\t\t\tblocks.set(blockId, value);\n\t\t}\n\t} catch {\n\t\t// End of data\n\t}\n\n\treturn blocks;\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Storage decryption utilities.\n * Ported from telegram-tdata-decrypter storage.py\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { createLegacyLocalKey, createLocalKey, decryptLocal } from \"./crypto\";\nimport { readQtByteArray } from \"./qt\";\nimport type { RawTdfFile } from \"./tdf\";\n\n/**\n * Decrypt settings TDF file\n */\nexport function decryptSettingsTdf(settingsTdf: RawTdfFile): Buffer {\n\tconst encryptedData = settingsTdf.encryptedData;\n\n\tlet offset = 0;\n\tconst { value: salt, newOffset: offset1 } = readQtByteArray(encryptedData, offset);\n\toffset = offset1;\n\tconst { value: encryptedSettings, newOffset: _ } = readQtByteArray(encryptedData, offset);\n\n\t// Settings key is created with empty passcode\n\tconst settingsKey = createLegacyLocalKey(Buffer.alloc(0), salt);\n\n\treturn decryptLocal(encryptedSettings, settingsKey);\n}\n\n/**\n * Decrypt key data TDF file\n * Returns [localKey, infoDecrypted]\n */\nexport function decryptKeyDataTdf(passcode: Buffer, keyDataTdf: RawTdfFile): [Buffer, Buffer] {\n\tconst stream = keyDataTdf.encryptedData;\n\n\tlet offset = 0;\n\tconst { value: salt, newOffset: offset1 } = readQtByteArray(stream, offset);\n\toffset = offset1;\n\tconst { value: keyEncrypted, newOffset: offset2 } = readQtByteArray(stream, offset);\n\toffset = offset2;\n\tconst { value: infoEncrypted, newOffset: _ } = readQtByteArray(stream, offset);\n\n\t// Create passcode key\n\tconst passcodeKey = createLocalKey(passcode, salt);\n\n\t// Decrypt local key\n\tconst localKey = decryptLocal(keyEncrypted, passcodeKey);\n\n\t// Decrypt info\n\tconst infoDecrypted = decryptLocal(infoEncrypted, localKey);\n\n\treturn [localKey, infoDecrypted];\n}\n\n/**\n * Read key data accounts\n * Returns [indexes, mainAccount]\n */\nexport function readKeyDataAccounts(data: Buffer): [number[], number] {\n\tlet offset = 0;\n\tconst count = data.readInt32BE(offset);\n\toffset += 4;\n\n\tconst indexes: number[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tconst index = data.readInt32BE(offset);\n\t\toffset += 4;\n\t\tindexes.push(index);\n\t}\n\n\tconst mainAccount = data.readInt32BE(offset);\n\n\treturn [indexes, mainAccount];\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * TDF (Telegram Desktop File) format parser.\n * Ported from telegram-tdata-decrypter tdf.py\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\n\nexport const TDF_MAGIC = Buffer.from(\"TDF$\", \"ascii\");\n\nexport class TdfParserError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"TdfParserError\";\n\t}\n}\n\nexport class WrongMagicTdfParserError extends TdfParserError {\n\tconstructor(message = \"Wrong magic. Not a TDF file?\") {\n\t\tsuper(message);\n\t\tthis.name = \"WrongMagicTdfParserError\";\n\t}\n}\n\nexport class WrongHashsumTdfParserError extends TdfParserError {\n\tconstructor(message = \"Wrong hashsum. Corrupted file?\") {\n\t\tsuper(message);\n\t\tthis.name = \"WrongHashsumTdfParserError\";\n\t}\n}\n\nexport interface RawTdfFile {\n\tversion: number;\n\tencryptedData: Buffer;\n\thashsum: Buffer;\n}\n\n/**\n * Parse raw TDF file from buffer\n */\nexport function parseRawTdf(data: Buffer): RawTdfFile {\n\t// Check magic\n\tif (data.subarray(0, 4).compare(TDF_MAGIC) !== 0) {\n\t\tthrow new WrongMagicTdfParserError();\n\t}\n\n\t// Read version (little-endian)\n\tconst version = data.readUInt32LE(4);\n\n\t// Extract encrypted data and hashsum\n\tconst encryptedData = data.subarray(8, data.length - 16);\n\tconst hashsum = data.subarray(data.length - 16);\n\n\t// Verify MD5 hashsum\n\tconst actualMd5 = crypto.createHash(\"md5\");\n\tactualMd5.update(encryptedData);\n\n\tconst lengthBuffer = Buffer.allocUnsafe(4);\n\tlengthBuffer.writeUInt32LE(encryptedData.length, 0);\n\tactualMd5.update(lengthBuffer);\n\n\tconst versionBuffer = Buffer.allocUnsafe(4);\n\tversionBuffer.writeUInt32LE(version, 0);\n\tactualMd5.update(versionBuffer);\n\n\tactualMd5.update(TDF_MAGIC);\n\n\tconst actualMd5Digest = actualMd5.digest();\n\n\tif (actualMd5Digest.compare(hashsum) !== 0) {\n\t\tthrow new WrongHashsumTdfParserError();\n\t}\n\n\treturn {\n\t\tversion,\n\t\tencryptedData,\n\t\thashsum,\n\t};\n}\n\n/**\n * Read TDF file from disk\n * Tries both filepath + 's' and filepath\n */\nexport function readTdfFile(filepath: string): RawTdfFile {\n\tconst candidates = [`${filepath}s`, filepath];\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst data = fs.readFileSync(candidate);\n\t\t\treturn parseRawTdf(data);\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error(`TDF file not found: ${filepath}`);\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Main tdata decrypter.\n * Ported from telegram-tdata-decrypter decrypter.py\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as crypto from \"node:crypto\";\nimport * as path from \"node:path\";\nimport { decryptLocal } from \"./crypto\";\nimport { readQtByteArray, readQtInt32, readQtUint64 } from \"./qt\";\nimport { readSettingsBlocks } from \"./settings\";\nimport { decryptKeyDataTdf, readKeyDataAccounts } from \"./storage\";\nimport { readTdfFile } from \"./tdf\";\n\n/**\n * Convert file key to string representation\n * Reverses each byte's hex pair (e.g., D8 -> 8D)\n */\nfunction fileKeyToStr(fileKey: Buffer): string {\n\tlet result = \"\";\n\tfor (const b of fileKey) {\n\t\tconst hex = b.toString(16).toUpperCase();\n\t\tconst padded = hex.length === 1 ? `0${hex}` : hex;\n\t\t// Reverse the 2-character hex string\n\t\tresult += padded[1] + padded[0];\n\t}\n\treturn result;\n}\n\n/**\n * Compute data name key from dataname string\n */\nfunction computeDataNameKey(dataName: string): string {\n\tconst fileKey = crypto.createHash(\"md5\").update(dataName, \"utf8\").digest().subarray(0, 8);\n\treturn fileKeyToStr(fileKey);\n}\n\n/**\n * Compose account name with index\n */\nfunction composeAccountName(dataName: string, index: number): string {\n\tif (index > 0) {\n\t\treturn `${dataName}#${index + 1}`;\n\t}\n\treturn dataName;\n}\n\n/**\n * MTP authorization data\n */\nexport interface MtpData {\n\tuserId: number;\n\tcurrentDcId: number;\n\tkeys: Map<number, Buffer>;\n\tkeysToDestroy: Map<number, Buffer>;\n}\n\n/**\n * Read MTP authorization from buffer\n */\nfunction readMtpAuthorization(buffer: Buffer): MtpData {\n\tlet offset = 0;\n\n\tconst legacyUserId = readQtInt32(buffer, offset);\n\tconst legacyMainDcId = readQtInt32(buffer, offset + 4);\n\toffset += 8;\n\n\tlet userId: number;\n\tlet mainDcId: number;\n\n\tif (legacyUserId === -1 && legacyMainDcId === -1) {\n\t\tuserId = Number(readQtUint64(buffer, offset));\n\t\toffset += 8;\n\t\tmainDcId = readQtInt32(buffer, offset);\n\t\toffset += 4;\n\t} else {\n\t\tuserId = legacyUserId;\n\t\tmainDcId = legacyMainDcId;\n\t}\n\n\t// Read keys\n\tconst count = readQtInt32(buffer, offset);\n\toffset += 4;\n\n\tconst keys = new Map<number, Buffer>();\n\tfor (let i = 0; i < count; i++) {\n\t\tconst dcId = readQtInt32(buffer, offset);\n\t\toffset += 4;\n\t\tconst key = Buffer.from(buffer.subarray(offset, offset + 256));\n\t\toffset += 256;\n\t\tkeys.set(dcId, key);\n\t}\n\n\t// Read keys to destroy\n\tconst destroyCount = readQtInt32(buffer, offset);\n\toffset += 4;\n\n\tconst keysToDestroy = new Map<number, Buffer>();\n\tfor (let i = 0; i < destroyCount; i++) {\n\t\tconst dcId = readQtInt32(buffer, offset);\n\t\toffset += 4;\n\t\tconst key = Buffer.from(buffer.subarray(offset, offset + 256));\n\t\toffset += 256;\n\t\tkeysToDestroy.set(dcId, key);\n\t}\n\n\treturn {\n\t\tuserId,\n\t\tcurrentDcId: mainDcId,\n\t\tkeys,\n\t\tkeysToDestroy,\n\t};\n}\n\n/**\n * Parsed account data\n */\nexport interface ParsedAccount {\n\tindex: number;\n\tmtpData: MtpData;\n}\n\n/**\n * Account reader class\n */\nclass AccountReader {\n\tprivate basePath: string;\n\tprivate index: number;\n\tprivate accountName: string;\n\tprivate dataNameKey: string;\n\n\tconstructor(basePath: string, index: number, dataName: string) {\n\t\tthis.basePath = basePath;\n\t\tthis.index = index;\n\t\tthis.accountName = composeAccountName(dataName, index);\n\t\tthis.dataNameKey = computeDataNameKey(this.accountName);\n\t}\n\n\t/**\n\t * Read account data using local key\n\t */\n\tread(localKey: Buffer): ParsedAccount {\n\t\tconst mtpData = this.readMtpData(localKey);\n\t\treturn {\n\t\t\tindex: this.index,\n\t\t\tmtpData,\n\t\t};\n\t}\n\n\t/**\n\t * Read MTP data\n\t */\n\treadMtpData(localKey: Buffer): MtpData {\n\t\tconst mtpDataFilePath = path.join(this.basePath, this.dataNameKey);\n\n\t\t// Read TDF file\n\t\tconst tdfFile = readTdfFile(mtpDataFilePath);\n\n\t\t// Read encrypted data\n\t\tconst offset = 0;\n\t\tconst { value: encryptedData, newOffset: _ } = readQtByteArray(\n\t\t\tBuffer.from(tdfFile.encryptedData),\n\t\t\toffset,\n\t\t);\n\n\t\t// Decrypt\n\t\tconst decrypted = decryptLocal(encryptedData, localKey);\n\n\t\t// Read settings blocks\n\t\tconst blocks = readSettingsBlocks(tdfFile.version, decrypted);\n\n\t\t// Get MTP authorization block\n\t\tconst mtpAuth = blocks.get(0x4b); // dbiMtpAuthorization\n\t\tif (!mtpAuth || !(mtpAuth instanceof Buffer)) {\n\t\t\tthrow new Error(\"MTP authorization not found\");\n\t\t}\n\n\t\treturn readMtpAuthorization(mtpAuth);\n\t}\n}\n\n/**\n * Parsed tdata result\n */\nexport interface ParsedTdata {\n\tsettings: Map<number, unknown>;\n\taccounts: Map<number, ParsedAccount>;\n}\n\n/**\n * Tdata Reader class\n */\nexport class TdataReader {\n\tprivate basePath: string;\n\tprivate dataName: string;\n\n\tstatic readonly DEFAULT_DATANAME = \"data\";\n\n\tconstructor(basePath: string, dataName?: string) {\n\t\tthis.basePath = basePath;\n\t\tthis.dataName = dataName ?? TdataReader.DEFAULT_DATANAME;\n\t}\n\n\t/**\n\t * Read tdata directory\n\t */\n\tread(passcode?: string): ParsedTdata {\n\t\t// Read settings\n\t\tconst settings = this.readSettings();\n\n\t\t// Read key data\n\t\tconst [localKey, accountIndexes] = this.readKeyData(passcode ?? \"\");\n\n\t\t// Read accounts\n\t\tconst accounts = new Map<number, ParsedAccount>();\n\t\tfor (const accountIndex of accountIndexes) {\n\t\t\tconst reader = new AccountReader(this.basePath, accountIndex, this.dataName);\n\t\t\tconst account = reader.read(localKey);\n\t\t\taccounts.set(accountIndex, account);\n\t\t}\n\n\t\treturn { settings, accounts };\n\t}\n\n\t/**\n\t * Read key data\n\t */\n\treadKeyData(passcode: string): [Buffer, number[]] {\n\t\tconst keyDataName = `key_${this.dataName}`;\n\t\tconst keyDataPath = path.join(this.basePath, keyDataName);\n\n\t\tconst keyDataTdf = readTdfFile(keyDataPath);\n\t\tconst [localKey, infoDecrypted] = decryptKeyDataTdf(Buffer.from(passcode), keyDataTdf);\n\t\tconst [accountIndexes, _] = readKeyDataAccounts(infoDecrypted);\n\n\t\treturn [localKey, accountIndexes];\n\t}\n\n\t/**\n\t * Read settings\n\t */\n\treadSettings(): Map<number, unknown> {\n\t\tconst settingsPath = path.join(this.basePath, \"settings\");\n\t\tconst settingsTdf = readTdfFile(settingsPath);\n\n\t\tconst decrypted = settingsTdf.encryptedData;\n\n\t\treturn readSettingsBlocks(settingsTdf.version, decrypted);\n\t}\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Pure TypeScript implementation of Telegram Desktop tdata decryption.\n * Ported from telegram-tdata-decrypter Python library.\n *\n * This module provides functionality to extract auth keys from\n * Telegram Desktop's tdata folder without requiring Python.\n */\n\nexport { TdataReader } from \"./decrypter\";\nexport type { MtpData, ParsedAccount, ParsedTdata } from \"./decrypter\";\n\nexport { readTdfFile, parseRawTdf, TDF_MAGIC } from \"./tdf\";\nexport type { RawTdfFile } from \"./tdf\";\n\nexport {\n\tcreateLocalKey,\n\tcreateLegacyLocalKey,\n\tdecryptLocal,\n\taesDecryptLocal,\n\tprepareAesOldMtp,\n} from \"./crypto\";\n\nexport {\n\treadQtInt32,\n\treadQtUint32,\n\treadQtInt64,\n\treadQtUint64,\n\treadQtByteArray,\n\treadQtUtf8,\n\treadBytes,\n\treadQtInteger,\n} from \"./qt\";\n\nexport type { ReadResult } from \"./qt\";\n\nexport {\n\tdecryptSettingsTdf,\n\tdecryptKeyDataTdf,\n\treadKeyDataAccounts,\n} from \"./storage\";\n\nexport {\n\treadSettingsBlocks,\n\treadSettingsBlock,\n\tSettingsBlocks,\n} from \"./settings\";\n\n// Re-export errors\nexport {\n\tTdfParserError,\n\tWrongMagicTdfParserError,\n\tWrongHashsumTdfParserError,\n} from \"./tdf\";\n\nexport { CryptoException } from \"./crypto\";\n\n/**\n * Extract auth key from tdata directory\n * @param tdataPath Path to tdata directory\n * @returns Auth key data\n */\nexport async function extractAuthKey(tdataPath: string): Promise<{\n\tsuccess: boolean;\n\tuserId?: number;\n\tdcId?: number;\n\tauthKey?: string;\n\terror?: string;\n}> {\n\ttry {\n\t\tconst { TdataReader } = await import(\"./decrypter\");\n\n\t\t// Normalize path\n\t\tlet path = tdataPath;\n\t\tif (!path.endsWith(\"tdata\")) {\n\t\t\tconst tdataDir = require(\"node:path\").join(tdataPath, \"tdata\");\n\t\t\tif (require(\"node:fs\").existsSync(tdataDir)) {\n\t\t\t\tpath = tdataDir;\n\t\t\t}\n\t\t}\n\n\t\tconst reader = new TdataReader(path);\n\t\tconst result = reader.read();\n\n\t\tif (!result.accounts || result.accounts.size === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"No accounts found in tdata. Please make sure you're logged into Telegram Desktop.\",\n\t\t\t};\n\t\t}\n\n\t\t// Get first account\n\t\tconst firstAccount = result.accounts.values().next().value;\n\t\tif (!firstAccount) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"No accounts found in tdata.\",\n\t\t\t};\n\t\t}\n\n\t\tconst { mtpData } = firstAccount;\n\t\tconst authKeyBytes = mtpData.keys.get(mtpData.currentDcId);\n\n\t\tif (!authKeyBytes) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `No auth key found for DC ${mtpData.currentDcId}`,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tuserId: mtpData.userId,\n\t\t\tdcId: mtpData.currentDcId,\n\t\t\tauthKey: authKeyBytes.toString(\"hex\"),\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t};\n\t}\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Telegram Desktop tdata to GramJS StringSession converter\n *\n * Now uses pure TypeScript implementation (tdata-decrypter)\n * instead of Python telegram-tdata-decrypter library.\n *\n * No external Python dependencies required!\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { AuthKey } from \"telegram/crypto/AuthKey\";\nimport { StringSession } from \"telegram/sessions\";\nimport { TdataReader } from \"./tdata-decrypter/index\";\n\n// Get the directory name of the current module (ESM equivalent of __dirname)\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// DC server addresses\nfunction getServerAddress(dcId: number): string {\n\tconst addresses: Record<number, string> = {\n\t\t1: \"149.154.175.53\",\n\t\t2: \"149.154.167.51\",\n\t\t3: \"149.154.175.100\",\n\t\t4: \"149.154.167.92\",\n\t\t5: \"149.154.171.5\",\n\t};\n\treturn addresses[dcId] || \"149.154.175.53\";\n}\n\n/**\n * Extract auth key from tdata using pure TypeScript implementation\n */\nfunction extractAuthKey(tdataPath: string): {\n\tuserId: number;\n\tdcId: number;\n\tauthKey: Buffer;\n} {\n\tconsole.log(\"[TdataConverter] Using pure JS implementation to extract auth key...\");\n\n\ttry {\n\t\tconst reader = new TdataReader(tdataPath);\n\t\tconst result = reader.read();\n\n\t\tif (!result.accounts || result.accounts.size === 0) {\n\t\t\tthrow new Error(\"No accounts found in tdata. Please make sure you're logged into Telegram Desktop.\");\n\t\t}\n\n\t\t// Get first account\n\t\tconst firstAccount = result.accounts.values().next().value;\n\t\tif (!firstAccount) {\n\t\t\tthrow new Error(\"No accounts found in tdata.\");\n\t\t}\n\n\t\tconst { mtpData } = firstAccount;\n\t\tconst authKeyBytes = mtpData.keys.get(mtpData.currentDcId);\n\n\t\tif (!authKeyBytes) {\n\t\t\tthrow new Error(`No auth key found for DC ${mtpData.currentDcId}`);\n\t\t}\n\n\t\tconsole.log(\"[TdataConverter] Pure JS implementation extracted:\", {\n\t\t\tuserId: mtpData.userId,\n\t\t\tdcId: mtpData.currentDcId,\n\t\t\tauthKeyLength: authKeyBytes.length,\n\t\t});\n\n\t\treturn {\n\t\t\tuserId: mtpData.userId,\n\t\t\tdcId: mtpData.currentDcId,\n\t\t\tauthKey: authKeyBytes,\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof Error) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new Error(\"Failed to extract auth key from tdata\");\n\t}\n}\n\n/**\n * Normalize tdata path\n */\nfunction normalizeTdataPath(inputPath: string): string {\n\tif (inputPath.endsWith(\"tdata\")) {\n\t\treturn inputPath;\n\t}\n\n\tconst tdataSubdir = path.join(inputPath, \"tdata\");\n\tif (fs.existsSync(tdataSubdir) && fs.statSync(tdataSubdir).isDirectory()) {\n\t\treturn tdataSubdir;\n\t}\n\n\treturn inputPath;\n}\n\n/**\n * Main conversion function: Convert tdata to StringSession\n */\nexport async function convertTdataToStringSession(tdataPath: string): Promise<string> {\n\tconst normalizedPath = normalizeTdataPath(tdataPath);\n\tconsole.log(\"[TdataConverter] Starting conversion from:\", tdataPath);\n\tconsole.log(\"[TdataConverter] Normalized path:\", normalizedPath);\n\n\tif (!fs.existsSync(normalizedPath)) {\n\t\tthrow new Error(`tdata directory not found: ${normalizedPath}`);\n\t}\n\n\ttry {\n\t\t// Use pure JS implementation to extract auth key\n\t\tconst { userId, dcId, authKey } = extractAuthKey(normalizedPath);\n\n\t\tconsole.log(\"[TdataConverter] Creating GramJS StringSession...\");\n\n\t\t// Create GramJS StringSession\n\t\tconst mainAuthKey = new AuthKey();\n\t\tawait mainAuthKey.setKey(authKey);\n\n\t\tconst session = new StringSession(\"\");\n\t\tsession.setDC(dcId, getServerAddress(dcId), 443);\n\t\tsession.setAuthKey(mainAuthKey);\n\n\t\tconst sessionString = session.save();\n\t\tconsole.log(\"[TdataConverter] Conversion successful!\");\n\n\t\treturn sessionString;\n\t} catch (error) {\n\t\tconsole.error(\"[TdataConverter] Conversion error:\", error);\n\n\t\tif (error instanceof Error) {\n\t\t\tconst errorMessage = error.message;\n\n\t\t\t// No accounts found\n\t\t\tif (\n\t\t\t\terrorMessage.includes(\"No accounts found\") ||\n\t\t\t\terrorMessage.includes(\"logged into Telegram Desktop\")\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"No active session found in Telegram Desktop.\\n\\n\" +\n\t\t\t\t\t\t\"Please make sure:\\n\" +\n\t\t\t\t\t\t\"• You're logged into Telegram Desktop\\n\" +\n\t\t\t\t\t\t\"• You've logged in at least once before\\n\" +\n\t\t\t\t\t\t\"• You're using the official Telegram Desktop from desktop.telegram.org\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Generic error with original message\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to read Telegram Desktop session: ${errorMessage}\\n\\nSuggestions:\\n1. Make sure Telegram Desktop is closed\\n2. Verify you're using the official Telegram Desktop from desktop.telegram.org\\n3. Try using the QR code or phone number login method instead`,\n\t\t\t);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t\"Failed to read Telegram Desktop session: Unknown error\\n\\n\" +\n\t\t\t\t\"Please try:\\n\" +\n\t\t\t\t\"1. Closing Telegram Desktop completely\\n\" +\n\t\t\t\t\"2. Using the QR code or phone number login method instead\",\n\t\t);\n\t}\n}\n\n/**\n * Validate if a directory contains valid Telegram Desktop tdata\n */\nexport function validateTdataDirectory(tdataPath: string): {\n\tvalid: boolean;\n\terror?: string;\n} {\n\ttry {\n\t\tif (!fs.existsSync(tdataPath)) {\n\t\t\treturn { valid: false, error: \"Directory does not exist\" };\n\t\t}\n\n\t\tif (!fs.statSync(tdataPath).isDirectory()) {\n\t\t\treturn { valid: false, error: \"Path is not a directory\" };\n\t\t}\n\n\t\tconst normalizedPath = normalizeTdataPath(tdataPath);\n\t\tconst keyDataPath = path.join(normalizedPath, \"key_datas\");\n\n\t\tif (!fs.existsSync(keyDataPath)) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\terror: `key_datas file missing.\\n\\nChecked path: ${normalizedPath}\\n\\nThis usually means:\\n1. Telegram Desktop has never been logged in on this machine\\n2. You're using the macOS App Store version (not supported)\\n3. The tdata path is incorrect`,\n\t\t\t};\n\t\t}\n\n\t\treturn { valid: true };\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t};\n\t}\n}\n\n/**\n * Extract basic account info from tdata\n */\nexport interface TdataAccountInfo {\n\tuserId: number;\n\tdcId: number;\n}\n\nexport function extractAccountInfo(tdataPath: string): TdataAccountInfo | null {\n\ttry {\n\t\tconst normalizedPath = normalizeTdataPath(tdataPath);\n\n\t\t// Use pure JS implementation to extract account info\n\t\tconst { userId, dcId } = extractAuthKey(normalizedPath);\n\n\t\treturn {\n\t\t\tuserId,\n\t\t\tdcId,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[TdataConverter] Failed to extract account info:\", error);\n\t\treturn null;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tdata-decrypter/crypto.ts","../src/tdata-decrypter/qt.ts","../src/tdata-decrypter/settings.ts","../src/tdata-decrypter/storage.ts","../src/tdata-decrypter/tdf.ts","../src/tdata-decrypter/decrypter.ts","../src/tdata-decrypter/index.ts","../src/tdata-converter.ts"],"names":["Buffer","crypto2","fs","crypto3","__filename","path2"],"mappings":"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","file":"tdata-converter.js","sourcesContent":["// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Cryptography utilities for Telegram Desktop tdata decryption.\n * Ported from telegram-tdata-decrypter crypto.py\n *\n * AES-256-IGE implementation based on:\n * https://gist.github.com/f4ddf6e7a859b837f996b3f50097153a\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as crypto from \"node:crypto\";\n\nconst LocalEncryptNoPwdIterCount = 4;\nconst LocalEncryptIterCount = 400;\nconst kStrongIterationsCount = 100000;\n\nexport class CryptoException extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"CryptoException\";\n\t}\n}\n\n/**\n * XOR two buffers in place\n */\nfunction xorBuffer(a: Buffer, b: Buffer): void {\n\tfor (let i = 0; i < a.length; i++) {\n\t\ta.writeUInt8(a.readUInt8(i) ^ b.readUInt8(i), i);\n\t}\n}\n\n/**\n * AES-256-IGE encrypt/decrypt\n */\nfunction igeCrypt(buffer: Buffer, aesKey: Buffer, aesIv: Buffer, isEncrypt: boolean): Buffer {\n\t// AES-256-ECB cipher (no IV, we handle IGE manually)\n\tconst cipher = isEncrypt\n\t\t? crypto.createCipheriv(\"aes-256-ecb\", aesKey, null)\n\t\t: crypto.createDecipheriv(\"aes-256-ecb\", aesKey, null);\n\n\tcipher.setAutoPadding(false);\n\n\tconst result = Buffer.allocUnsafe(buffer.length);\n\n\t// IGE uses IV as two 16-byte blocks\n\tlet prevCipherblock: Buffer;\n\tlet prevPlainblock: Buffer;\n\n\tif (isEncrypt) {\n\t\tprevCipherblock = aesIv.subarray(0, 16); // IV1\n\t\tprevPlainblock = aesIv.subarray(16, 32); // IV2\n\t} else {\n\t\t// For decryption, swap the order\n\t\tprevCipherblock = aesIv.subarray(16, 32); // IV2\n\t\tprevPlainblock = aesIv.subarray(0, 16); // IV1\n\t}\n\n\tconst current = Buffer.allocUnsafe(16);\n\n\tfor (let offset = 0; offset < buffer.length; offset += 16) {\n\t\tconst chunk = buffer.subarray(offset, offset + 16);\n\t\tchunk.copy(current);\n\n\t\t// IGE: XOR with previous cipher block before AES\n\t\txorBuffer(current, prevCipherblock);\n\n\t\t// AES encryption/decryption\n\t\tconst crypted = Buffer.from(cipher.update(current));\n\n\t\t// IGE: XOR with previous plaintext block after AES\n\t\txorBuffer(crypted, prevPlainblock);\n\n\t\tcrypted.copy(result, offset);\n\n\t\tprevCipherblock = crypted;\n\t\tprevPlainblock = chunk;\n\t}\n\n\t// Finalize (should produce empty buffer for full blocks)\n\tcipher.final();\n\n\treturn result;\n}\n\n/**\n * Create local key from passcode and salt\n */\nexport function createLocalKey(passcode: Buffer, salt: Buffer): Buffer {\n\tconst iterations = passcode.length > 0 ? kStrongIterationsCount : 1;\n\n\tconst password = crypto.createHash(\"sha512\");\n\tpassword.update(salt);\n\tpassword.update(passcode);\n\tpassword.update(salt);\n\n\treturn crypto.pbkdf2Sync(password.digest(), salt, iterations, 256, \"sha512\");\n}\n\n/**\n * Create legacy local key (for older Telegram Desktop versions)\n */\nexport function createLegacyLocalKey(passcode: Buffer, salt: Buffer): Buffer {\n\tconst iterations = passcode.length > 0 ? LocalEncryptIterCount : LocalEncryptNoPwdIterCount;\n\n\treturn crypto.pbkdf2Sync(passcode, salt, iterations, 256, \"sha1\");\n}\n\n/**\n * Decrypt local encrypted data\n */\nexport function decryptLocal(encryptedMsg: Buffer, localKey: Buffer): Buffer {\n\tconst msgKey = encryptedMsg.subarray(0, 16);\n\tconst encryptedData = encryptedMsg.subarray(16);\n\n\tconst decrypted = aesDecryptLocal(encryptedData, msgKey, localKey);\n\n\t// Verify SHA1 hash\n\tconst sha1 = crypto.createHash(\"sha1\");\n\tsha1.update(decrypted);\n\tconst calculatedMsgKey = sha1.digest().subarray(0, 16);\n\n\tif (calculatedMsgKey.compare(msgKey) !== 0) {\n\t\tthrow new CryptoException(\"bad decrypt key, data not decrypted - incorrect password\");\n\t}\n\n\t// Read length\n\tconst length = decrypted.readUInt32LE(0);\n\tif (length > decrypted.length) {\n\t\tthrow new CryptoException(`corrupted data. wrong length: ${length}`);\n\t}\n\n\treturn decrypted.subarray(4, 4 + length);\n}\n\n/**\n * AES-256-IGE decrypt for local data\n */\nexport function aesDecryptLocal(encryptedData: Buffer, msgKey: Buffer, localKey: Buffer): Buffer {\n\tconst { aesKey, aesIv } = prepareAesOldMtp(localKey, msgKey, false);\n\treturn igeCrypt(encryptedData, aesKey, aesIv, false);\n}\n\n/**\n * Prepare AES key and IV for old MTProto format\n */\ninterface AesKeyIv {\n\taesKey: Buffer;\n\taesIv: Buffer;\n}\n\nexport function prepareAesOldMtp(localKey: Buffer, msgKey: Buffer, send = false): AesKeyIv {\n\tconst x = send ? 0 : 8;\n\n\tconst keyPos = (pos: number, size: number): Buffer => {\n\t\treturn localKey.subarray(pos, pos + size);\n\t};\n\n\tconst dataA = Buffer.concat([msgKey, keyPos(x, 32)]);\n\tconst dataB = Buffer.concat([keyPos(x + 32, 16), msgKey, keyPos(x + 48, 16)]);\n\tconst dataC = Buffer.concat([keyPos(x + 64, 32), msgKey]);\n\tconst dataD = Buffer.concat([msgKey, keyPos(x + 96, 32)]);\n\n\tconst sha1A = crypto.createHash(\"sha1\").update(dataA).digest();\n\tconst sha1B = crypto.createHash(\"sha1\").update(dataB).digest();\n\tconst sha1C = crypto.createHash(\"sha1\").update(dataC).digest();\n\tconst sha1D = crypto.createHash(\"sha1\").update(dataD).digest();\n\n\tconst aesKey = Buffer.concat([sha1A.subarray(0, 8), sha1B.subarray(8, 20), sha1C.subarray(4, 16)]);\n\n\tconst aesIv = Buffer.concat([\n\t\tsha1A.subarray(8, 20),\n\t\tsha1B.subarray(0, 8),\n\t\tsha1C.subarray(16, 20),\n\t\tsha1D.subarray(0, 8),\n\t]);\n\n\treturn { aesKey, aesIv };\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Qt binary data format reader utilities.\n * Ported from telegram-tdata-decrypter qt.py\n */\n\nimport { Buffer } from \"node:buffer\";\n\n/**\n * Read N bytes from buffer\n */\nexport function readBytes(buffer: Buffer, offset: number, size: number): Buffer {\n\tif (offset + size > buffer.length) {\n\t\tthrow new Error(`Cannot read ${size} bytes at offset ${offset}, buffer length is ${buffer.length}`);\n\t}\n\treturn buffer.subarray(offset, offset + size);\n}\n\n/**\n * Read integer in big-endian format\n */\nexport function readQtInteger(buffer: Buffer, offset: number, size: number, signed: boolean): number {\n\tconst value = readBytes(buffer, offset, size);\n\tconst hex = value.toString(\"hex\");\n\n\t// Convert to number (big-endian)\n\tlet num = BigInt(`0x${hex}`);\n\n\tif (signed && num >= BigInt(2) ** BigInt(size * 8 - 1)) {\n\t\tnum -= BigInt(2) ** BigInt(size * 8);\n\t}\n\n\t// Convert to Number (safe for 32-bit, for 64-bit return as Number but may lose precision)\n\treturn Number(num);\n}\n\n/**\n * Read 32-bit signed integer (big-endian)\n */\nexport function readQtInt32(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 4, true);\n}\n\n/**\n * Read 32-bit unsigned integer (big-endian)\n */\nexport function readQtUint32(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 4, false);\n}\n\n/**\n * Read 64-bit signed integer (big-endian)\n */\nexport function readQtInt64(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 8, true);\n}\n\n/**\n * Read 64-bit unsigned integer (big-endian)\n */\nexport function readQtUint64(buffer: Buffer, offset: number): number {\n\treturn readQtInteger(buffer, offset, 8, false);\n}\n\n/**\n * Read byte array (length-prefixed)\n * Returns { value, newOffset }\n */\nexport interface ReadResult<T> {\n\tvalue: T;\n\tnewOffset: number;\n}\n\nexport function readQtByteArray(buffer: Buffer, offset: number): ReadResult<Buffer> {\n\tconst length = readQtInt32(buffer, offset);\n\tlet newOffset = offset + 4;\n\n\tif (length <= 0) {\n\t\treturn { value: Buffer.alloc(0), newOffset };\n\t}\n\n\tconst value = readBytes(buffer, newOffset, length);\n\tnewOffset += length;\n\n\treturn { value, newOffset };\n}\n\n/**\n * Read UTF-16 string (byte array decoded as UTF-16)\n */\nexport function readQtUtf8(buffer: Buffer, offset: number): ReadResult<string> {\n\tconst { value, newOffset } = readQtByteArray(buffer, offset);\n\t// The original Python code decodes as utf16\n\tconst str = value.toString(\"utf16le\");\n\treturn { value: str, newOffset };\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Settings block reader.\n * Ported from telegram-tdata-decrypter settings.py\n */\n\nimport type { Buffer } from \"node:buffer\";\nimport { readQtByteArray, readQtInt32, readQtUint64, readQtUtf8 } from \"./qt\";\n\n/**\n * Settings block IDs\n */\nexport enum SettingsBlocks {\n\tdbiKey = 0x00,\n\tdbiUser = 0x01,\n\tdbiDcOptionOldOld = 0x02,\n\tdbiChatSizeMaxOld = 0x03,\n\tdbiMutePeerOld = 0x04,\n\tdbiSendKeyOld = 0x05,\n\tdbiAutoStart = 0x06,\n\tdbiStartMinimized = 0x07,\n\tdbiSoundFlashBounceNotifyOld = 0x08,\n\tdbiWorkModeOld = 0x09,\n\tdbiSeenTrayTooltip = 0x0a,\n\tdbiDesktopNotifyOld = 0x0b,\n\tdbiAutoUpdate = 0x0c,\n\tdbiLastUpdateCheck = 0x0d,\n\tdbiWindowPositionOld = 0x0e,\n\tdbiConnectionTypeOldOld = 0x0f,\n\tdbiDefaultAttach = 0x11,\n\tdbiCatsAndDogsOld = 0x12,\n\tdbiReplaceEmojiOld = 0x13,\n\tdbiAskDownloadPathOld = 0x14,\n\tdbiDownloadPathOldOld = 0x15,\n\tdbiScaleOld = 0x16,\n\tdbiEmojiTabOld = 0x17,\n\tdbiRecentEmojiOldOldOld = 0x18,\n\tdbiLoggedPhoneNumberOld = 0x19,\n\tdbiMutedPeersOld = 0x1a,\n\tdbiNotifyViewOld = 0x1c,\n\tdbiSendToMenu = 0x1d,\n\tdbiCompressPastedImageOld = 0x1e,\n\tdbiLangOld = 0x1f,\n\tdbiLangFileOld = 0x20,\n\tdbiTileBackgroundOld = 0x21,\n\tdbiAutoLockOld = 0x22,\n\tdbiDialogLastPath = 0x23,\n\tdbiRecentEmojiOldOld = 0x24,\n\tdbiEmojiVariantsOldOld = 0x25,\n\tdbiRecentStickers = 0x26,\n\tdbiDcOptionOld = 0x27,\n\tdbiTryIPv6Old = 0x28,\n\tdbiSongVolumeOld = 0x29,\n\tdbiWindowsNotificationsOld = 0x30,\n\tdbiIncludeMutedOld = 0x31,\n\tdbiMegagroupSizeMaxOld = 0x32,\n\tdbiDownloadPathOld = 0x33,\n\tdbiAutoDownloadOld = 0x34,\n\tdbiSavedGifsLimitOld = 0x35,\n\tdbiShowingSavedGifsOld = 0x36,\n\tdbiAutoPlayOld = 0x37,\n\tdbiAdaptiveForWideOld = 0x38,\n\tdbiHiddenPinnedMessagesOld = 0x39,\n\tdbiRecentEmojiOld = 0x3a,\n\tdbiEmojiVariantsOld = 0x3b,\n\tdbiDialogsModeOld = 0x40,\n\tdbiModerateModeOld = 0x41,\n\tdbiVideoVolumeOld = 0x42,\n\tdbiStickersRecentLimitOld = 0x43,\n\tdbiNativeNotificationsOld = 0x44,\n\tdbiNotificationsCountOld = 0x45,\n\tdbiNotificationsCornerOld = 0x46,\n\tdbiThemeKeyOld = 0x47,\n\tdbiDialogsWidthRatioOld = 0x48,\n\tdbiUseExternalVideoPlayerOld = 0x49,\n\tdbiDcOptionsOld = 0x4a,\n\tdbiMtpAuthorization = 0x4b,\n\tdbiLastSeenWarningSeenOld = 0x4c,\n\tdbiSessionSettings = 0x4d,\n\tdbiLangPackKey = 0x4e,\n\tdbiConnectionTypeOld = 0x4f,\n\tdbiStickersFavedLimitOld = 0x50,\n\tdbiSuggestStickersByEmojiOld = 0x51,\n\tdbiSuggestEmojiOld = 0x52,\n\tdbiTxtDomainStringOldOld = 0x53,\n\tdbiThemeKey = 0x54,\n\tdbiTileBackground = 0x55,\n\tdbiCacheSettingsOld = 0x56,\n\tdbiPowerSaving = 0x57,\n\tdbiScalePercent = 0x58,\n\tdbiPlaybackSpeedOld = 0x59,\n\tdbiLanguagesKey = 0x5a,\n\tdbiCallSettingsOld = 0x5b,\n\tdbiCacheSettings = 0x5c,\n\tdbiTxtDomainStringOld = 0x5d,\n\tdbiApplicationSettings = 0x5e,\n\tdbiDialogsFiltersOld = 0x5f,\n\tdbiFallbackProductionConfig = 0x60,\n\tdbiBackgroundKey = 0x61,\n\tdbiEncryptedWithSalt = 333,\n\tdbiEncrypted = 444,\n\tdbiVersion = 666,\n}\n\n/**\n * Read settings block value based on block ID\n */\nexport function readSettingsBlock(\n\tversion: number,\n\tbuffer: Buffer,\n\toffset: number,\n\tblockId: SettingsBlocks,\n): { value: unknown; newOffset: number } {\n\tswitch (blockId) {\n\t\tcase SettingsBlocks.dbiAutoStart:\n\t\tcase SettingsBlocks.dbiStartMinimized:\n\t\tcase SettingsBlocks.dbiSendToMenu:\n\t\tcase SettingsBlocks.dbiSeenTrayTooltip:\n\t\tcase SettingsBlocks.dbiAutoUpdate: {\n\t\t\tconst value = readQtInt32(buffer, offset) === 1;\n\t\t\treturn { value, newOffset: offset + 4 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiSongVolumeOld: {\n\t\t\tconst value = readQtInt32(buffer, offset) / 1e6;\n\t\t\treturn { value, newOffset: offset + 4 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiLastUpdateCheck:\n\t\tcase SettingsBlocks.dbiScalePercent:\n\t\tcase SettingsBlocks.dbiPowerSaving: {\n\t\t\tconst value = readQtInt32(buffer, offset);\n\t\t\treturn { value, newOffset: offset + 4 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiFallbackProductionConfig:\n\t\tcase SettingsBlocks.dbiApplicationSettings: {\n\t\t\tconst { value, newOffset } = readQtByteArray(buffer, offset);\n\t\t\treturn { value, newOffset };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiDialogLastPath: {\n\t\t\tconst { value, newOffset } = readQtUtf8(buffer, offset);\n\t\t\treturn { value, newOffset };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiThemeKey: {\n\t\t\tconst day = readQtUint64(buffer, offset);\n\t\t\tconst night = readQtUint64(buffer, offset + 8);\n\t\t\tconst nightMode = readQtInt32(buffer, offset + 16) === 1;\n\t\t\treturn {\n\t\t\t\tvalue: { day, night, nightMode },\n\t\t\t\tnewOffset: offset + 20,\n\t\t\t};\n\t\t}\n\n\t\tcase SettingsBlocks.dbiBackgroundKey: {\n\t\t\tconst day = readQtUint64(buffer, offset);\n\t\t\tconst night = readQtUint64(buffer, offset + 8);\n\t\t\treturn {\n\t\t\t\tvalue: { day, night },\n\t\t\t\tnewOffset: offset + 16,\n\t\t\t};\n\t\t}\n\n\t\tcase SettingsBlocks.dbiTileBackground: {\n\t\t\tconst day = readQtInt32(buffer, offset);\n\t\t\tconst night = readQtInt32(buffer, offset + 4);\n\t\t\treturn {\n\t\t\t\tvalue: { day, night },\n\t\t\t\tnewOffset: offset + 8,\n\t\t\t};\n\t\t}\n\n\t\tcase SettingsBlocks.dbiLangPackKey: {\n\t\t\tconst value = readQtUint64(buffer, offset);\n\t\t\treturn { value, newOffset: offset + 8 };\n\t\t}\n\n\t\tcase SettingsBlocks.dbiMtpAuthorization: {\n\t\t\tconst { value, newOffset } = readQtByteArray(buffer, offset);\n\t\t\treturn { value, newOffset };\n\t\t}\n\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown block ID while reading settings: ${blockId}`);\n\t}\n}\n\n/**\n * Read all settings blocks from buffer\n */\nexport function readSettingsBlocks(version: number, buffer: Buffer): Map<SettingsBlocks, unknown> {\n\tconst blocks = new Map<SettingsBlocks, unknown>();\n\tlet offset = 0;\n\n\ttry {\n\t\twhile (offset < buffer.length) {\n\t\t\tconst blockId = readQtInt32(buffer, offset) as SettingsBlocks;\n\t\t\toffset += 4;\n\n\t\t\tconst { value, newOffset } = readSettingsBlock(version, buffer, offset, blockId);\n\t\t\toffset = newOffset;\n\n\t\t\tblocks.set(blockId, value);\n\t\t}\n\t} catch {\n\t\t// End of data\n\t}\n\n\treturn blocks;\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Storage decryption utilities.\n * Ported from telegram-tdata-decrypter storage.py\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { createLegacyLocalKey, createLocalKey, decryptLocal } from \"./crypto\";\nimport { readQtByteArray } from \"./qt\";\nimport type { RawTdfFile } from \"./tdf\";\n\n/**\n * Decrypt settings TDF file\n */\nexport function decryptSettingsTdf(settingsTdf: RawTdfFile): Buffer {\n\tconst encryptedData = settingsTdf.encryptedData;\n\n\tlet offset = 0;\n\tconst { value: salt, newOffset: offset1 } = readQtByteArray(encryptedData, offset);\n\toffset = offset1;\n\tconst { value: encryptedSettings, newOffset: _ } = readQtByteArray(encryptedData, offset);\n\n\t// Settings key is created with empty passcode\n\tconst settingsKey = createLegacyLocalKey(Buffer.alloc(0), salt);\n\n\treturn decryptLocal(encryptedSettings, settingsKey);\n}\n\n/**\n * Decrypt key data TDF file\n * Returns [localKey, infoDecrypted]\n */\nexport function decryptKeyDataTdf(passcode: Buffer, keyDataTdf: RawTdfFile): [Buffer, Buffer] {\n\tconst stream = keyDataTdf.encryptedData;\n\n\tlet offset = 0;\n\tconst { value: salt, newOffset: offset1 } = readQtByteArray(stream, offset);\n\toffset = offset1;\n\tconst { value: keyEncrypted, newOffset: offset2 } = readQtByteArray(stream, offset);\n\toffset = offset2;\n\tconst { value: infoEncrypted, newOffset: _ } = readQtByteArray(stream, offset);\n\n\t// Create passcode key\n\tconst passcodeKey = createLocalKey(passcode, salt);\n\n\t// Decrypt local key\n\tconst localKey = decryptLocal(keyEncrypted, passcodeKey);\n\n\t// Decrypt info\n\tconst infoDecrypted = decryptLocal(infoEncrypted, localKey);\n\n\treturn [localKey, infoDecrypted];\n}\n\n/**\n * Read key data accounts\n * Returns [indexes, mainAccount]\n */\nexport function readKeyDataAccounts(data: Buffer): [number[], number] {\n\tlet offset = 0;\n\tconst count = data.readInt32BE(offset);\n\toffset += 4;\n\n\tconst indexes: number[] = [];\n\tfor (let i = 0; i < count; i++) {\n\t\tconst index = data.readInt32BE(offset);\n\t\toffset += 4;\n\t\tindexes.push(index);\n\t}\n\n\tconst mainAccount = data.readInt32BE(offset);\n\n\treturn [indexes, mainAccount];\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * TDF (Telegram Desktop File) format parser.\n * Ported from telegram-tdata-decrypter tdf.py\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\n\nexport const TDF_MAGIC = Buffer.from(\"TDF$\", \"ascii\");\n\nexport class TdfParserError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"TdfParserError\";\n\t}\n}\n\nexport class WrongMagicTdfParserError extends TdfParserError {\n\tconstructor(message = \"Wrong magic. Not a TDF file?\") {\n\t\tsuper(message);\n\t\tthis.name = \"WrongMagicTdfParserError\";\n\t}\n}\n\nexport class WrongHashsumTdfParserError extends TdfParserError {\n\tconstructor(message = \"Wrong hashsum. Corrupted file?\") {\n\t\tsuper(message);\n\t\tthis.name = \"WrongHashsumTdfParserError\";\n\t}\n}\n\nexport interface RawTdfFile {\n\tversion: number;\n\tencryptedData: Buffer;\n\thashsum: Buffer;\n}\n\n/**\n * Parse raw TDF file from buffer\n */\nexport function parseRawTdf(data: Buffer): RawTdfFile {\n\t// Check magic\n\tif (data.subarray(0, 4).compare(TDF_MAGIC) !== 0) {\n\t\tthrow new WrongMagicTdfParserError();\n\t}\n\n\t// Read version (little-endian)\n\tconst version = data.readUInt32LE(4);\n\n\t// Extract encrypted data and hashsum\n\tconst encryptedData = data.subarray(8, data.length - 16);\n\tconst hashsum = data.subarray(data.length - 16);\n\n\t// Verify MD5 hashsum\n\tconst actualMd5 = crypto.createHash(\"md5\");\n\tactualMd5.update(encryptedData);\n\n\tconst lengthBuffer = Buffer.allocUnsafe(4);\n\tlengthBuffer.writeUInt32LE(encryptedData.length, 0);\n\tactualMd5.update(lengthBuffer);\n\n\tconst versionBuffer = Buffer.allocUnsafe(4);\n\tversionBuffer.writeUInt32LE(version, 0);\n\tactualMd5.update(versionBuffer);\n\n\tactualMd5.update(TDF_MAGIC);\n\n\tconst actualMd5Digest = actualMd5.digest();\n\n\tif (actualMd5Digest.compare(hashsum) !== 0) {\n\t\tthrow new WrongHashsumTdfParserError();\n\t}\n\n\treturn {\n\t\tversion,\n\t\tencryptedData,\n\t\thashsum,\n\t};\n}\n\n/**\n * Read TDF file from disk\n * Tries both filepath + 's' and filepath\n */\nexport function readTdfFile(filepath: string): RawTdfFile {\n\tconst candidates = [`${filepath}s`, filepath];\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst data = fs.readFileSync(candidate);\n\t\t\treturn parseRawTdf(data);\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error(`TDF file not found: ${filepath}`);\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Main tdata decrypter.\n * Ported from telegram-tdata-decrypter decrypter.py\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as crypto from \"node:crypto\";\nimport * as path from \"node:path\";\nimport { decryptLocal } from \"./crypto\";\nimport { readQtByteArray, readQtInt32, readQtUint64 } from \"./qt\";\nimport { readSettingsBlocks } from \"./settings\";\nimport { decryptKeyDataTdf, readKeyDataAccounts } from \"./storage\";\nimport { readTdfFile } from \"./tdf\";\n\n/**\n * Convert file key to string representation\n * Reverses each byte's hex pair (e.g., D8 -> 8D)\n */\nfunction fileKeyToStr(fileKey: Buffer): string {\n\tlet result = \"\";\n\tfor (const b of fileKey) {\n\t\tconst hex = b.toString(16).toUpperCase();\n\t\tconst padded = hex.length === 1 ? `0${hex}` : hex;\n\t\t// Reverse the 2-character hex string\n\t\tresult += padded[1] + padded[0];\n\t}\n\treturn result;\n}\n\n/**\n * Compute data name key from dataname string\n */\nfunction computeDataNameKey(dataName: string): string {\n\tconst fileKey = crypto.createHash(\"md5\").update(dataName, \"utf8\").digest().subarray(0, 8);\n\treturn fileKeyToStr(fileKey);\n}\n\n/**\n * Compose account name with index\n */\nfunction composeAccountName(dataName: string, index: number): string {\n\tif (index > 0) {\n\t\treturn `${dataName}#${index + 1}`;\n\t}\n\treturn dataName;\n}\n\n/**\n * MTP authorization data\n */\nexport interface MtpData {\n\tuserId: number;\n\tcurrentDcId: number;\n\tkeys: Map<number, Buffer>;\n\tkeysToDestroy: Map<number, Buffer>;\n}\n\n/**\n * Read MTP authorization from buffer\n */\nfunction readMtpAuthorization(buffer: Buffer): MtpData {\n\tlet offset = 0;\n\n\tconst legacyUserId = readQtInt32(buffer, offset);\n\tconst legacyMainDcId = readQtInt32(buffer, offset + 4);\n\toffset += 8;\n\n\tlet userId: number;\n\tlet mainDcId: number;\n\n\tif (legacyUserId === -1 && legacyMainDcId === -1) {\n\t\tuserId = Number(readQtUint64(buffer, offset));\n\t\toffset += 8;\n\t\tmainDcId = readQtInt32(buffer, offset);\n\t\toffset += 4;\n\t} else {\n\t\tuserId = legacyUserId;\n\t\tmainDcId = legacyMainDcId;\n\t}\n\n\t// Read keys\n\tconst count = readQtInt32(buffer, offset);\n\toffset += 4;\n\n\tconst keys = new Map<number, Buffer>();\n\tfor (let i = 0; i < count; i++) {\n\t\tconst dcId = readQtInt32(buffer, offset);\n\t\toffset += 4;\n\t\tconst key = Buffer.from(buffer.subarray(offset, offset + 256));\n\t\toffset += 256;\n\t\tkeys.set(dcId, key);\n\t}\n\n\t// Read keys to destroy\n\tconst destroyCount = readQtInt32(buffer, offset);\n\toffset += 4;\n\n\tconst keysToDestroy = new Map<number, Buffer>();\n\tfor (let i = 0; i < destroyCount; i++) {\n\t\tconst dcId = readQtInt32(buffer, offset);\n\t\toffset += 4;\n\t\tconst key = Buffer.from(buffer.subarray(offset, offset + 256));\n\t\toffset += 256;\n\t\tkeysToDestroy.set(dcId, key);\n\t}\n\n\treturn {\n\t\tuserId,\n\t\tcurrentDcId: mainDcId,\n\t\tkeys,\n\t\tkeysToDestroy,\n\t};\n}\n\n/**\n * Parsed account data\n */\nexport interface ParsedAccount {\n\tindex: number;\n\tmtpData: MtpData;\n}\n\n/**\n * Account reader class\n */\nclass AccountReader {\n\tprivate basePath: string;\n\tprivate index: number;\n\tprivate accountName: string;\n\tprivate dataNameKey: string;\n\n\tconstructor(basePath: string, index: number, dataName: string) {\n\t\tthis.basePath = basePath;\n\t\tthis.index = index;\n\t\tthis.accountName = composeAccountName(dataName, index);\n\t\tthis.dataNameKey = computeDataNameKey(this.accountName);\n\t}\n\n\t/**\n\t * Read account data using local key\n\t */\n\tread(localKey: Buffer): ParsedAccount {\n\t\tconst mtpData = this.readMtpData(localKey);\n\t\treturn {\n\t\t\tindex: this.index,\n\t\t\tmtpData,\n\t\t};\n\t}\n\n\t/**\n\t * Read MTP data\n\t */\n\treadMtpData(localKey: Buffer): MtpData {\n\t\tconst mtpDataFilePath = path.join(this.basePath, this.dataNameKey);\n\n\t\t// Read TDF file\n\t\tconst tdfFile = readTdfFile(mtpDataFilePath);\n\n\t\t// Read encrypted data\n\t\tconst offset = 0;\n\t\tconst { value: encryptedData, newOffset: _ } = readQtByteArray(\n\t\t\tBuffer.from(tdfFile.encryptedData),\n\t\t\toffset,\n\t\t);\n\n\t\t// Decrypt\n\t\tconst decrypted = decryptLocal(encryptedData, localKey);\n\n\t\t// Read settings blocks\n\t\tconst blocks = readSettingsBlocks(tdfFile.version, decrypted);\n\n\t\t// Get MTP authorization block\n\t\tconst mtpAuth = blocks.get(0x4b); // dbiMtpAuthorization\n\t\tif (!mtpAuth || !(mtpAuth instanceof Buffer)) {\n\t\t\tthrow new Error(\"MTP authorization not found\");\n\t\t}\n\n\t\treturn readMtpAuthorization(mtpAuth);\n\t}\n}\n\n/**\n * Parsed tdata result\n */\nexport interface ParsedTdata {\n\tsettings: Map<number, unknown>;\n\taccounts: Map<number, ParsedAccount>;\n}\n\n/**\n * Tdata Reader class\n */\nexport class TdataReader {\n\tprivate basePath: string;\n\tprivate dataName: string;\n\n\tstatic readonly DEFAULT_DATANAME = \"data\";\n\n\tconstructor(basePath: string, dataName?: string) {\n\t\tthis.basePath = basePath;\n\t\tthis.dataName = dataName ?? TdataReader.DEFAULT_DATANAME;\n\t}\n\n\t/**\n\t * Read tdata directory\n\t */\n\tread(passcode?: string): ParsedTdata {\n\t\t// Read settings\n\t\tconst settings = this.readSettings();\n\n\t\t// Read key data\n\t\tconst [localKey, accountIndexes] = this.readKeyData(passcode ?? \"\");\n\n\t\t// Read accounts\n\t\tconst accounts = new Map<number, ParsedAccount>();\n\t\tfor (const accountIndex of accountIndexes) {\n\t\t\tconst reader = new AccountReader(this.basePath, accountIndex, this.dataName);\n\t\t\tconst account = reader.read(localKey);\n\t\t\taccounts.set(accountIndex, account);\n\t\t}\n\n\t\treturn { settings, accounts };\n\t}\n\n\t/**\n\t * Read key data\n\t */\n\treadKeyData(passcode: string): [Buffer, number[]] {\n\t\tconst keyDataName = `key_${this.dataName}`;\n\t\tconst keyDataPath = path.join(this.basePath, keyDataName);\n\n\t\tconst keyDataTdf = readTdfFile(keyDataPath);\n\t\tconst [localKey, infoDecrypted] = decryptKeyDataTdf(Buffer.from(passcode), keyDataTdf);\n\t\tconst [accountIndexes, _] = readKeyDataAccounts(infoDecrypted);\n\n\t\treturn [localKey, accountIndexes];\n\t}\n\n\t/**\n\t * Read settings\n\t */\n\treadSettings(): Map<number, unknown> {\n\t\tconst settingsPath = path.join(this.basePath, \"settings\");\n\t\tconst settingsTdf = readTdfFile(settingsPath);\n\n\t\tconst decrypted = settingsTdf.encryptedData;\n\n\t\treturn readSettingsBlocks(settingsTdf.version, decrypted);\n\t}\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Pure TypeScript implementation of Telegram Desktop tdata decryption.\n * Ported from telegram-tdata-decrypter Python library.\n *\n * This module provides functionality to extract auth keys from\n * Telegram Desktop's tdata folder without requiring Python.\n */\n\nexport { TdataReader } from \"./decrypter\";\nexport type { MtpData, ParsedAccount, ParsedTdata } from \"./decrypter\";\n\nexport { readTdfFile, parseRawTdf, TDF_MAGIC } from \"./tdf\";\nexport type { RawTdfFile } from \"./tdf\";\n\nexport {\n\tcreateLocalKey,\n\tcreateLegacyLocalKey,\n\tdecryptLocal,\n\taesDecryptLocal,\n\tprepareAesOldMtp,\n} from \"./crypto\";\n\nexport {\n\treadQtInt32,\n\treadQtUint32,\n\treadQtInt64,\n\treadQtUint64,\n\treadQtByteArray,\n\treadQtUtf8,\n\treadBytes,\n\treadQtInteger,\n} from \"./qt\";\n\nexport type { ReadResult } from \"./qt\";\n\nexport {\n\tdecryptSettingsTdf,\n\tdecryptKeyDataTdf,\n\treadKeyDataAccounts,\n} from \"./storage\";\n\nexport {\n\treadSettingsBlocks,\n\treadSettingsBlock,\n\tSettingsBlocks,\n} from \"./settings\";\n\n// Re-export errors\nexport {\n\tTdfParserError,\n\tWrongMagicTdfParserError,\n\tWrongHashsumTdfParserError,\n} from \"./tdf\";\n\nexport { CryptoException } from \"./crypto\";\n\n/**\n * Extract auth key from tdata directory\n * @param tdataPath Path to tdata directory\n * @returns Auth key data\n */\nexport async function extractAuthKey(tdataPath: string): Promise<{\n\tsuccess: boolean;\n\tuserId?: number;\n\tdcId?: number;\n\tauthKey?: string;\n\terror?: string;\n}> {\n\ttry {\n\t\tconst { TdataReader } = await import(\"./decrypter\");\n\n\t\t// Normalize path\n\t\tlet path = tdataPath;\n\t\tif (!path.endsWith(\"tdata\")) {\n\t\t\tconst tdataDir = require(\"node:path\").join(tdataPath, \"tdata\");\n\t\t\tif (require(\"node:fs\").existsSync(tdataDir)) {\n\t\t\t\tpath = tdataDir;\n\t\t\t}\n\t\t}\n\n\t\tconst reader = new TdataReader(path);\n\t\tconst result = reader.read();\n\n\t\tif (!result.accounts || result.accounts.size === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"No accounts found in tdata. Please make sure you're logged into Telegram Desktop.\",\n\t\t\t};\n\t\t}\n\n\t\t// Get first account\n\t\tconst firstAccount = result.accounts.values().next().value;\n\t\tif (!firstAccount) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"No accounts found in tdata.\",\n\t\t\t};\n\t\t}\n\n\t\tconst { mtpData } = firstAccount;\n\t\tconst authKeyBytes = mtpData.keys.get(mtpData.currentDcId);\n\n\t\tif (!authKeyBytes) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `No auth key found for DC ${mtpData.currentDcId}`,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tuserId: mtpData.userId,\n\t\t\tdcId: mtpData.currentDcId,\n\t\t\tauthKey: authKeyBytes.toString(\"hex\"),\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t};\n\t}\n}\n","// Copyright 2026 OpenContext Team. All rights reserved.\n//\n// Use of this source code is governed by a license that can be\n// found in the LICENSE file in the root of this source tree.\n\n/**\n * Telegram Desktop tdata to GramJS StringSession converter\n *\n * Now uses pure TypeScript implementation (tdata-decrypter)\n * instead of Python telegram-tdata-decrypter library.\n *\n * No external Python dependencies required!\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { AuthKey } from \"telegram/crypto/AuthKey.js\";\nimport { StringSession } from \"telegram/sessions/index.js\";\nimport { TdataReader } from \"./tdata-decrypter/index\";\n\n// Get the directory name of the current module (ESM equivalent of __dirname)\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// DC server addresses\nfunction getServerAddress(dcId: number): string {\n\tconst addresses: Record<number, string> = {\n\t\t1: \"149.154.175.53\",\n\t\t2: \"149.154.167.51\",\n\t\t3: \"149.154.175.100\",\n\t\t4: \"149.154.167.92\",\n\t\t5: \"149.154.171.5\",\n\t};\n\treturn addresses[dcId] || \"149.154.175.53\";\n}\n\n/**\n * Extract auth key from tdata using pure TypeScript implementation\n */\nfunction extractAuthKey(tdataPath: string): {\n\tuserId: number;\n\tdcId: number;\n\tauthKey: Buffer;\n} {\n\tconsole.log(\"[TdataConverter] Using pure JS implementation to extract auth key...\");\n\n\ttry {\n\t\tconst reader = new TdataReader(tdataPath);\n\t\tconst result = reader.read();\n\n\t\tif (!result.accounts || result.accounts.size === 0) {\n\t\t\tthrow new Error(\"No accounts found in tdata. Please make sure you're logged into Telegram Desktop.\");\n\t\t}\n\n\t\t// Get first account\n\t\tconst firstAccount = result.accounts.values().next().value;\n\t\tif (!firstAccount) {\n\t\t\tthrow new Error(\"No accounts found in tdata.\");\n\t\t}\n\n\t\tconst { mtpData } = firstAccount;\n\t\tconst authKeyBytes = mtpData.keys.get(mtpData.currentDcId);\n\n\t\tif (!authKeyBytes) {\n\t\t\tthrow new Error(`No auth key found for DC ${mtpData.currentDcId}`);\n\t\t}\n\n\t\tconsole.log(\"[TdataConverter] Pure JS implementation extracted:\", {\n\t\t\tuserId: mtpData.userId,\n\t\t\tdcId: mtpData.currentDcId,\n\t\t\tauthKeyLength: authKeyBytes.length,\n\t\t});\n\n\t\treturn {\n\t\t\tuserId: mtpData.userId,\n\t\t\tdcId: mtpData.currentDcId,\n\t\t\tauthKey: authKeyBytes,\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof Error) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new Error(\"Failed to extract auth key from tdata\");\n\t}\n}\n\n/**\n * Normalize tdata path\n */\nfunction normalizeTdataPath(inputPath: string): string {\n\tif (inputPath.endsWith(\"tdata\")) {\n\t\treturn inputPath;\n\t}\n\n\tconst tdataSubdir = path.join(inputPath, \"tdata\");\n\tif (fs.existsSync(tdataSubdir) && fs.statSync(tdataSubdir).isDirectory()) {\n\t\treturn tdataSubdir;\n\t}\n\n\treturn inputPath;\n}\n\n/**\n * Main conversion function: Convert tdata to StringSession\n */\nexport async function convertTdataToStringSession(tdataPath: string): Promise<string> {\n\tconst normalizedPath = normalizeTdataPath(tdataPath);\n\tconsole.log(\"[TdataConverter] Starting conversion from:\", tdataPath);\n\tconsole.log(\"[TdataConverter] Normalized path:\", normalizedPath);\n\n\tif (!fs.existsSync(normalizedPath)) {\n\t\tthrow new Error(`tdata directory not found: ${normalizedPath}`);\n\t}\n\n\ttry {\n\t\t// Use pure JS implementation to extract auth key\n\t\tconst { userId, dcId, authKey } = extractAuthKey(normalizedPath);\n\n\t\tconsole.log(\"[TdataConverter] Creating GramJS StringSession...\");\n\n\t\t// Create GramJS StringSession\n\t\tconst mainAuthKey = new AuthKey();\n\t\tawait mainAuthKey.setKey(authKey);\n\n\t\tconst session = new StringSession(\"\");\n\t\tsession.setDC(dcId, getServerAddress(dcId), 443);\n\t\tsession.setAuthKey(mainAuthKey);\n\n\t\tconst sessionString = session.save();\n\t\tconsole.log(\"[TdataConverter] Conversion successful!\");\n\n\t\treturn sessionString;\n\t} catch (error) {\n\t\tconsole.error(\"[TdataConverter] Conversion error:\", error);\n\n\t\tif (error instanceof Error) {\n\t\t\tconst errorMessage = error.message;\n\n\t\t\t// No accounts found\n\t\t\tif (\n\t\t\t\terrorMessage.includes(\"No accounts found\") ||\n\t\t\t\terrorMessage.includes(\"logged into Telegram Desktop\")\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"No active session found in Telegram Desktop.\\n\\n\" +\n\t\t\t\t\t\t\"Please make sure:\\n\" +\n\t\t\t\t\t\t\"• You're logged into Telegram Desktop\\n\" +\n\t\t\t\t\t\t\"• You've logged in at least once before\\n\" +\n\t\t\t\t\t\t\"• You're using the official Telegram Desktop from desktop.telegram.org\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Generic error with original message\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to read Telegram Desktop session: ${errorMessage}\\n\\nSuggestions:\\n1. Make sure Telegram Desktop is closed\\n2. Verify you're using the official Telegram Desktop from desktop.telegram.org\\n3. Try using the QR code or phone number login method instead`,\n\t\t\t);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t\"Failed to read Telegram Desktop session: Unknown error\\n\\n\" +\n\t\t\t\t\"Please try:\\n\" +\n\t\t\t\t\"1. Closing Telegram Desktop completely\\n\" +\n\t\t\t\t\"2. Using the QR code or phone number login method instead\",\n\t\t);\n\t}\n}\n\n/**\n * Validate if a directory contains valid Telegram Desktop tdata\n */\nexport function validateTdataDirectory(tdataPath: string): {\n\tvalid: boolean;\n\terror?: string;\n} {\n\ttry {\n\t\tif (!fs.existsSync(tdataPath)) {\n\t\t\treturn { valid: false, error: \"Directory does not exist\" };\n\t\t}\n\n\t\tif (!fs.statSync(tdataPath).isDirectory()) {\n\t\t\treturn { valid: false, error: \"Path is not a directory\" };\n\t\t}\n\n\t\tconst normalizedPath = normalizeTdataPath(tdataPath);\n\t\tconst keyDataPath = path.join(normalizedPath, \"key_datas\");\n\n\t\tif (!fs.existsSync(keyDataPath)) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\terror: `key_datas file missing.\\n\\nChecked path: ${normalizedPath}\\n\\nThis usually means:\\n1. Telegram Desktop has never been logged in on this machine\\n2. You're using the macOS App Store version (not supported)\\n3. The tdata path is incorrect`,\n\t\t\t};\n\t\t}\n\n\t\treturn { valid: true };\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t};\n\t}\n}\n\n/**\n * Extract basic account info from tdata\n */\nexport interface TdataAccountInfo {\n\tuserId: number;\n\tdcId: number;\n}\n\nexport function extractAccountInfo(tdataPath: string): TdataAccountInfo | null {\n\ttry {\n\t\tconst normalizedPath = normalizeTdataPath(tdataPath);\n\n\t\t// Use pure JS implementation to extract account info\n\t\tconst { userId, dcId } = extractAuthKey(normalizedPath);\n\n\t\treturn {\n\t\t\tuserId,\n\t\t\tdcId,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[TdataConverter] Failed to extract account info:\", error);\n\t\treturn null;\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@melandlabs/integrations-telegram",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
"big-integer": "^1.6.52",
|
|
40
40
|
"markdown-it": "^14.1.1",
|
|
41
41
|
"telegram": "^2.26.22",
|
|
42
|
-
"@melandlabs/
|
|
43
|
-
"@melandlabs/
|
|
44
|
-
"@melandlabs/integrations-channels": "0.1.
|
|
45
|
-
"@melandlabs/shared": "0.1.
|
|
42
|
+
"@melandlabs/ai": "0.1.3",
|
|
43
|
+
"@melandlabs/integrations": "0.1.3",
|
|
44
|
+
"@melandlabs/integrations-channels": "0.1.3",
|
|
45
|
+
"@melandlabs/shared": "0.1.3"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"typescript": "^5.6.3",
|
|
49
49
|
"vitest": "^4.0.6",
|
|
50
|
-
"@melandlabs/config": "0.1.
|
|
50
|
+
"@melandlabs/config": "0.1.3"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"build": "tsup",
|