diff --git a/packages/convert/src/gramjs/convert.test.ts b/packages/convert/src/gramjs/convert.test.ts index 0555957d..e61e60e8 100644 --- a/packages/convert/src/gramjs/convert.test.ts +++ b/packages/convert/src/gramjs/convert.test.ts @@ -23,15 +23,16 @@ describe('gramjs/convert', () => { ipAddress: '149.154.167.40', ipv6: false, port: 443, + testMode: true, }, media: { id: 2, ipAddress: '149.154.167.40', ipv6: false, port: 443, + testMode: true, }, }, - testMode: true, version: 3, }) }) diff --git a/packages/convert/src/mtkruto/convert.test.ts b/packages/convert/src/mtkruto/convert.test.ts index 5c63474c..eb26e27a 100644 --- a/packages/convert/src/mtkruto/convert.test.ts +++ b/packages/convert/src/mtkruto/convert.test.ts @@ -22,14 +22,15 @@ describe('mtkruto/convert', () => { id: 2, ipAddress: '149.154.167.40', port: 443, + testMode: true, }, media: { id: 2, ipAddress: '149.154.167.40', port: 443, + testMode: true, }, }, - testMode: true, version: 3, }) }) diff --git a/packages/convert/src/pyrogram/convert.test.ts b/packages/convert/src/pyrogram/convert.test.ts index 9c36d62d..cc3f1ef6 100644 --- a/packages/convert/src/pyrogram/convert.test.ts +++ b/packages/convert/src/pyrogram/convert.test.ts @@ -22,11 +22,13 @@ describe('pyrogram/convert', () => { id: 2, ipAddress: '149.154.167.40', port: 443, + testMode: true, }, media: { id: 2, ipAddress: '149.154.167.40', port: 443, + testMode: true, }, }, self: { @@ -35,7 +37,6 @@ describe('pyrogram/convert', () => { userId: 5000801609, usernames: [], }, - testMode: true, version: 3, }) }) diff --git a/packages/convert/src/telethon/convert.test.ts b/packages/convert/src/telethon/convert.test.ts index caa57bd1..10997fd7 100644 --- a/packages/convert/src/telethon/convert.test.ts +++ b/packages/convert/src/telethon/convert.test.ts @@ -23,15 +23,16 @@ describe('telethon/convert', () => { ipAddress: '149.154.167.40', ipv6: false, port: 80, + testMode: true, }, media: { id: 2, ipAddress: '149.154.167.40', ipv6: false, port: 80, + testMode: true, }, }, - testMode: true, version: 3, }) }) diff --git a/packages/convert/src/telethon/parse.test.ts b/packages/convert/src/telethon/parse.test.ts index dd525c8e..22e6f3fc 100644 --- a/packages/convert/src/telethon/parse.test.ts +++ b/packages/convert/src/telethon/parse.test.ts @@ -28,7 +28,7 @@ describe('telethon/parse', () => { it('should correctly parse ipv6 sessions', () => { expect(parseTelethonSession(TELETHON_TEST_SESSION_V6)).toEqual({ dcId: 1, - ipAddress: '2001:0b28:f23d:f001:0000:0000:0000:000e', + ipAddress: '2001:b28:f23d:f001::e', port: 443, ipv6: true, authKey: hex.decode( diff --git a/packages/core/src/highlevel/utils/inline-utils.ts b/packages/core/src/highlevel/utils/inline-utils.ts index fb57f448..22c3f960 100644 --- a/packages/core/src/highlevel/utils/inline-utils.ts +++ b/packages/core/src/highlevel/utils/inline-utils.ts @@ -1,7 +1,7 @@ import type { tl } from '@mtcute/tl' import { TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime' +import { base64 } from '@fuman/utils' -import { getPlatform } from '../../platform.js' import { assertNever } from '../../types/utils.js' /** @@ -10,7 +10,7 @@ import { assertNever } from '../../types/utils.js' * @param id Inline message ID */ export function parseInlineMessageId(id: string): tl.TypeInputBotInlineMessageID { - const buf = getPlatform().base64Decode(id, true) + const buf = base64.decode(id, true) const reader = TlBinaryReader.manual(buf) if (buf.length === 20) { @@ -57,7 +57,7 @@ export function encodeInlineMessageId(id: tl.TypeInputBotInlineMessageID): strin assertNever(id) } - return getPlatform().base64Encode(writer.result(), true) + return base64.encode(writer.result(), true) } export function normalizeInlineId(id: string | tl.TypeInputBotInlineMessageID): tl.TypeInputBotInlineMessageID { diff --git a/packages/core/src/highlevel/utils/inspectable.ts b/packages/core/src/highlevel/utils/inspectable.ts index 6a16e294..d2cbeb41 100644 --- a/packages/core/src/highlevel/utils/inspectable.ts +++ b/packages/core/src/highlevel/utils/inspectable.ts @@ -2,8 +2,7 @@ /* eslint-disable ts/no-unsafe-call,ts/no-unsafe-argument */ import Long from 'long' - -import { getPlatform } from '../../platform.js' +import { base64 } from '@fuman/utils' const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom') @@ -57,7 +56,7 @@ export function makeInspectable( if (val && typeof val === 'object') { if (val instanceof Uint8Array) { - val = getPlatform().base64Encode(val) + val = base64.encode(val) } else if (Long.isLong(val)) { val = val.toString() } else if (typeof val.toJSON === 'function') { diff --git a/packages/core/src/highlevel/utils/string-session.test.ts b/packages/core/src/highlevel/utils/string-session.test.ts index e96dec5c..710e13b5 100644 --- a/packages/core/src/highlevel/utils/string-session.test.ts +++ b/packages/core/src/highlevel/utils/string-session.test.ts @@ -17,6 +17,16 @@ const stubDcs = { mediaOnly: true, }, } +const stubDcsTest = { + main: { + ...stubDcs.main, + testMode: true, + }, + media: { + ...stubDcs.media, + testMode: true, + }, +} const stubDcsBasic = { main: { id: 2, @@ -24,6 +34,7 @@ const stubDcsBasic = { ipv6: false, mediaOnly: false, port: 443, + testMode: false, }, media: { id: 2, @@ -31,6 +42,17 @@ const stubDcsBasic = { ipv6: false, mediaOnly: true, port: 443, + testMode: false, + }, +} +const stubDcsBasicTest = { + main: { + ...stubDcsBasic.main, + testMode: true, + }, + media: { + ...stubDcsBasic.media, + testMode: true, }, } const stubDcsSameMedia = { @@ -47,24 +69,22 @@ describe('writeStringSession', () => { expect( writeStringSession({ version: 3, - testMode: false, primaryDcs: stubDcsBasic, authKey: stubAuthKey, }), ).toMatchInlineSnapshot( - '"AwQAAAAXAQIADjE0OS4xNTQuMTY3LjUwALsBAAAXAQICDzE0OS4xNTQuMTY3LjIyMrsBAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', + '"AwQAAAAXAgIADjE0OS4xNTQuMTY3LjUwALsBAAAXAgICDzE0OS4xNTQuMTY3LjIyMrsBAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', ) }) it('should write production string session without user with same dc for media', () => { expect( writeStringSession({ version: 3, - testMode: false, primaryDcs: stubDcsBasicSameMedia, authKey: stubAuthKey, }), ).toMatchInlineSnapshot( - '"AwAAAAAXAQIADjE0OS4xNTQuMTY3LjUwALsBAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', + '"AwAAAAAXAgIADjE0OS4xNTQuMTY3LjUwALsBAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', ) }) @@ -72,7 +92,6 @@ describe('writeStringSession', () => { expect( writeStringSession({ version: 3, - testMode: false, primaryDcs: stubDcsBasic, authKey: stubAuthKey, self: { @@ -83,7 +102,7 @@ describe('writeStringSession', () => { }, }), ).toMatchInlineSnapshot( - '"AwUAAAAXAQIADjE0OS4xNTQuMTY3LjUwALsBAAAXAQICDzE0OS4xNTQuMTY3LjIyMrsBAAA5MAAAAAAAADeXebwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', + '"AwUAAAAXAgIADjE0OS4xNTQuMTY3LjUwALsBAAAXAgICDzE0OS4xNTQuMTY3LjIyMrsBAAA5MAAAAAAAADeXebwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', ) }) @@ -91,8 +110,7 @@ describe('writeStringSession', () => { expect( writeStringSession({ version: 3, - testMode: true, - primaryDcs: stubDcsBasic, + primaryDcs: stubDcsBasicTest, authKey: stubAuthKey, self: { userId: 12345, @@ -102,7 +120,7 @@ describe('writeStringSession', () => { }, }), ).toMatchInlineSnapshot( - '"AwcAAAAXAQIADjE0OS4xNTQuMTY3LjUwALsBAAAXAQICDzE0OS4xNTQuMTY3LjIyMrsBAAA5MAAAAAAAADeXebwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', + '"AwUAAAAXAgIEDjE0OS4xNTQuMTY3LjUwALsBAAAXAgIGDzE0OS4xNTQuMTY3LjIyMrsBAAA5MAAAAAAAADeXebwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"', ) }) }) @@ -116,7 +134,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 3, - testMode: false, primaryDcs: stubDcsBasic, authKey: stubAuthKey, self: null, @@ -130,7 +147,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 3, - testMode: false, primaryDcs: stubDcsBasicSameMedia, authKey: stubAuthKey, self: null, @@ -144,7 +160,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 3, - testMode: false, primaryDcs: stubDcsBasic, authKey: stubAuthKey, self: { @@ -163,8 +178,7 @@ describe('readStringSession', () => { ), ).toEqual({ version: 3, - testMode: true, - primaryDcs: stubDcsBasic, + primaryDcs: stubDcsBasicTest, authKey: stubAuthKey, self: { userId: 12345, @@ -184,7 +198,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 2, - testMode: false, primaryDcs: stubDcs, authKey: stubAuthKey, self: null, @@ -198,7 +211,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 2, - testMode: false, primaryDcs: stubDcsSameMedia, authKey: stubAuthKey, self: null, @@ -212,7 +224,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 2, - testMode: false, primaryDcs: stubDcs, authKey: stubAuthKey, self: { @@ -231,8 +242,7 @@ describe('readStringSession', () => { ), ).toEqual({ version: 2, - testMode: true, - primaryDcs: stubDcs, + primaryDcs: stubDcsTest, authKey: stubAuthKey, self: { userId: 12345, @@ -252,7 +262,6 @@ describe('readStringSession', () => { ), ).toEqual({ version: 1, - testMode: false, // v1 didn't have separate media dc primaryDcs: stubDcsSameMedia, authKey: stubAuthKey, diff --git a/packages/core/src/highlevel/utils/string-session.ts b/packages/core/src/highlevel/utils/string-session.ts index c1fc1415..8bec69a2 100644 --- a/packages/core/src/highlevel/utils/string-session.ts +++ b/packages/core/src/highlevel/utils/string-session.ts @@ -1,6 +1,6 @@ import { TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime' +import { base64 } from '@fuman/utils' -import { getPlatform } from '../../platform.js' import { MtArgumentError } from '../../types/index.js' import type { BasicDcOption, DcOptions } from '../../utils/dcs.js' import { parseBasicDcOption, serializeBasicDcOption } from '../../utils/dcs.js' @@ -74,11 +74,11 @@ export function writeStringSession(data: StringSessionData): string { writer.bytes(data.authKey) - return getPlatform().base64Encode(writer.result(), true) + return base64.encode(writer.result(), true) } export function readStringSession(data: string): StringSessionData { - const buf = getPlatform().base64Decode(data, true) + const buf = base64.decode(data, true) const version = buf[0] diff --git a/packages/core/src/network/transports/intermediate.test.ts b/packages/core/src/network/transports/intermediate.test.ts index d5b79814..4ef9924c 100644 --- a/packages/core/src/network/transports/intermediate.test.ts +++ b/packages/core/src/network/transports/intermediate.test.ts @@ -1,109 +1,87 @@ // todo: fix test -// import { describe, expect, it } from 'vitest' -// import { defaultTestCryptoProvider, useFakeMathRandom } from '@mtcute/test' +import { describe, expect, it } from 'vitest' +import { defaultTestCryptoProvider, useFakeMathRandom } from '@mtcute/test' +import { hex } from '@fuman/utils' +import { Bytes, write } from '@fuman/io' -// import { IntermediatePacketCodec, PaddedIntermediatePacketCodec, TransportError } from '../../index.js' -// import { getPlatform } from '../../platform.js' +import { IntermediatePacketCodec, PaddedIntermediatePacketCodec } from './intermediate' +import { TransportError } from './abstract' -// const p = getPlatform() +describe('IntermediatePacketCodec', () => { + it('should return correct tag', () => { + expect(hex.encode(new IntermediatePacketCodec().tag())).eq('eeeeeeee') + }) -// describe('IntermediatePacketCodec', () => { -// it('should return correct tag', () => { -// expect(p.hexEncode(new IntermediatePacketCodec().tag())).eq('eeeeeeee') -// }) + it('should correctly parse immediate framing', async () => { + const codec = new IntermediatePacketCodec() + expect(codec.decode(Bytes.from(hex.decode('050000000501020304')), false)).eql(new Uint8Array([5, 1, 2, 3, 4])) + }) -// it('should correctly parse immediate framing', () => -// new Promise((done) => { -// const codec = new IntermediatePacketCodec() -// codec.on('packet', (data: Uint8Array) => { -// expect([...data]).eql([5, 1, 2, 3, 4]) -// done() -// }) -// codec.feed(p.hexDecode('050000000501020304')) -// })) + it('should correctly parse incomplete framing', () => { + const codec = new IntermediatePacketCodec() + const buf = Bytes.alloc() -// it('should correctly parse incomplete framing', () => -// new Promise((done) => { -// const codec = new IntermediatePacketCodec() -// codec.on('packet', (data: Uint8Array) => { -// expect([...data]).eql([5, 1, 2, 3, 4]) -// done() -// }) -// codec.feed(p.hexDecode('050000000501')) -// codec.feed(p.hexDecode('020304')) -// })) + write.bytes(buf, hex.decode('050000000501')) + expect(codec.decode(buf, false)).toEqual(null) -// it('should correctly parse multiple streamed packets', () => -// new Promise((done) => { -// const codec = new IntermediatePacketCodec() + write.bytes(buf, hex.decode('020304')) + expect(codec.decode(buf, false)).eql(new Uint8Array([5, 1, 2, 3, 4])) + expect(codec.decode(buf, false)).toEqual(null) + }) -// let number = 0 + it('should correctly parse multiple streamed packets', () => { + const codec = new IntermediatePacketCodec() + const buf = Bytes.alloc() -// codec.on('packet', (data: Uint8Array) => { -// if (number === 0) { -// expect([...data]).eql([5, 1, 2, 3, 4]) -// number = 1 -// } else { -// expect([...data]).eql([3, 1, 2, 3, 1]) -// done() -// } -// }) -// codec.feed(p.hexDecode('050000000501')) -// codec.feed(p.hexDecode('020304050000')) -// codec.feed(p.hexDecode('000301020301')) -// })) + write.bytes(buf, hex.decode('050000000501')) + expect(codec.decode(buf, false)).toEqual(null) + write.bytes(buf, hex.decode('020304050000')) + expect(codec.decode(buf, false)).eql(new Uint8Array([5, 1, 2, 3, 4])) + expect(codec.decode(buf, false)).eql(null) -// it('should correctly parse transport errors', () => -// new Promise((done) => { -// const codec = new IntermediatePacketCodec() + write.bytes(buf, hex.decode('000301020301')) + expect(codec.decode(buf, false)).eql(new Uint8Array([3, 1, 2, 3, 1])) + expect(codec.decode(buf, false)).toEqual(null) + }) -// codec.on('error', (err: TransportError) => { -// expect(err).to.have.instanceOf(TransportError) -// expect(err.code).eq(404) -// done() -// }) + it('should correctly parse transport errors', () => { + const codec = new IntermediatePacketCodec() + const buf = Bytes.alloc() -// codec.feed(p.hexDecode('040000006cfeffff')) -// })) + write.bytes(buf, hex.decode('040000006cfeffff')) + expect(() => codec.decode(buf, false)).toThrow(new TransportError(404)) + }) -// it('should reset when called reset()', () => -// new Promise((done) => { -// const codec = new IntermediatePacketCodec() + it('should correctly frame packets', () => { + const data = hex.decode('6cfeffff') + const buf = Bytes.alloc() -// codec.on('packet', (data: Uint8Array) => { -// expect([...data]).eql([1, 2, 3, 4, 5]) -// done() -// }) + new IntermediatePacketCodec().encode(data, buf) -// codec.feed(p.hexDecode('ff0000001234567812345678')) -// codec.reset() -// codec.feed(p.hexDecode('050000000102030405')) -// })) + expect(hex.encode(buf.result())).toEqual('040000006cfeffff') + }) +}) -// it('should correctly frame packets', () => { -// const data = p.hexDecode('6cfeffff') +describe('PaddedIntermediatePacketCodec', () => { + useFakeMathRandom() -// expect(p.hexEncode(new IntermediatePacketCodec().encode(data))).toEqual('040000006cfeffff') -// }) -// }) + const create = async () => { + const codec = new PaddedIntermediatePacketCodec() + codec.setup!(await defaultTestCryptoProvider()) -// describe('PaddedIntermediatePacketCodec', () => { -// useFakeMathRandom() + return codec + } -// const create = async () => { -// const codec = new PaddedIntermediatePacketCodec() -// codec.setup!(await defaultTestCryptoProvider()) + it('should return correct tag', async () => { + expect(hex.encode((await create()).tag())).eq('dddddddd') + }) -// return codec -// } + it('should correctly frame packets', async () => { + const data = hex.decode('6cfeffff') + const buf = Bytes.alloc() -// it('should return correct tag', async () => { -// expect(p.hexEncode((await create()).tag())).eq('dddddddd') -// }) + ;(await create()).encode(data, buf) -// it('should correctly frame packets', async () => { -// const data = p.hexDecode('6cfeffff') - -// expect(p.hexEncode((await create()).encode(data))).toEqual('0a0000006cfeffff29afd26df40f') -// }) -// }) + expect(hex.encode(buf.result())).toEqual('0a0000006cfeffff29afd26df40f') + }) +}) diff --git a/packages/core/src/network/transports/intermediate.ts b/packages/core/src/network/transports/intermediate.ts index e59cb496..c60961cf 100644 --- a/packages/core/src/network/transports/intermediate.ts +++ b/packages/core/src/network/transports/intermediate.ts @@ -29,8 +29,8 @@ export class IntermediatePacketCodec implements IPacketCodec { if (length === 4) { // error - const code = read.uint32le(reader) - throw new TransportError(code) + const code = read.int32le(reader) + throw new TransportError(-code) } if (reader.available < length) { diff --git a/packages/core/src/utils/binary/asn1-parser.ts b/packages/core/src/utils/binary/asn1-parser.ts index 601ce728..702d0456 100644 --- a/packages/core/src/utils/binary/asn1-parser.ts +++ b/packages/core/src/utils/binary/asn1-parser.ts @@ -1,15 +1,13 @@ // all available libraries either suck or are extremely large for the use case, so i made my own~ -import { hex } from '@fuman/utils' - -import { getPlatform } from '../../platform.js' +import { base64, hex } from '@fuman/utils' /** * Parses a single PEM block to buffer. * In fact just strips begin/end tags and parses the rest as Base64 */ export function parsePemContents(pem: string): Uint8Array { - return getPlatform().base64Decode(pem.replace(/^-----(?:BEGIN|END)(?: RSA)? PUBLIC KEY-----$|\n/gm, '')) + return base64.decode(pem.replace(/^-----(?:BEGIN|END)(?: RSA)? PUBLIC KEY-----$|\n/gm, '')) } // based on https://git.coolaj86.com/coolaj86/asn1-parser.js/src/branch/master/asn1-parser.js diff --git a/packages/node/src/utils.ts b/packages/node/src/utils.ts index 70dd1c86..b084b27e 100644 --- a/packages/node/src/utils.ts +++ b/packages/node/src/utils.ts @@ -1,3 +1,2 @@ export * from './utils/crypto.js' -export * from './utils/stream-utils.js' export * from '@mtcute/core/utils.js'