UNPKG

tgsnake

Version:

Telegram MTProto framework for nodejs.

163 lines (162 loc) 7.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BrowserSession = void 0; const platform_node_js_1 = require("../platform.node.js"); const Logger_js_1 = require("../Context/Logger.js"); const SnakeSession_js_1 = require("./SnakeSession.js"); class BrowserSession extends platform_node_js_1.Storages.BaseSession { _name; constructor(name) { super(); this._name = name; } async load() { const sessionName = `${this._name}.session`; if (localStorage.getItem(sessionName) !== null) { const start = Math.floor(Date.now() / 1000); const bytes = platform_node_js_1.Buffer.from(localStorage.getItem(sessionName), 'base64'); Logger_js_1.Logger.debug(`Session have a ${bytes.length} bytes`); this._dcId = bytes.readUInt8(0); Logger_js_1.Logger.debug(`Found dcId: ${this._dcId}.`); this._apiId = bytes.readUInt32LE(1); Logger_js_1.Logger.debug(`Found apiId: ${this._apiId}.`); this._testMode = bytes.readUInt8(5) ? true : false; Logger_js_1.Logger.debug(`Found testMode: ${this._testMode}.`); this._authKey = bytes.subarray(6, 262); Logger_js_1.Logger.debug(`Found authKey: ${this._authKey.length} bytes.`); this._userId = BigInt(`0x${bytes.subarray(262, 270).toString('hex')}`); Logger_js_1.Logger.debug(`Found userId: ${this._userId}.`); this._isBot = bytes.readUInt8(270) ? true : false; Logger_js_1.Logger.debug(`Found isBot: ${this._isBot}.`); Logger_js_1.Logger.debug(`Done parsing string session (${Math.floor(Date.now() / 1000) - start}s)`); } const [peers, secretChats] = await this._loadCache(); for (const peer of peers) { this._peers.set(peer[0], peer); } for (let secretChat of secretChats) { this._secretChats.set(secretChat.id, secretChat); } } async save() { const sessionName = `${this._name}.session`; const cacheName = `${this._name}.cache`; if (localStorage.getItem(sessionName) !== null) { localStorage.setItem(sessionName, platform_node_js_1.Helpers.base64urlTobase64(await this.exportString())); Logger_js_1.Logger.info(`Session saved to: "localStorage:${sessionName}".`); } localStorage.setItem(cacheName, (await this._makeCache()).toString('base64')); Logger_js_1.Logger.info(`Cache saved to: "localStorage:${cacheName}".`); } async _loadCache() { const peer = []; const cacheName = `${this._name}.cache`; let e2e = []; if (localStorage.getItem(cacheName) !== null) { const buffer = platform_node_js_1.Buffer.from(localStorage.getItem(cacheName), 'base64'); if (buffer[0] === 2) { Logger_js_1.Logger.info(`Load cache version: 2`); const bytes = new platform_node_js_1.Raws.BytesIO(buffer.subarray(1)); const cacheLength = await platform_node_js_1.Raws.Primitive.Int.read(bytes); const cacheBytes = new platform_node_js_1.Raws.BytesIO(await bytes.read(cacheLength)); const peerLength = await platform_node_js_1.Raws.Primitive.Int.read(cacheBytes); const E2ELength = await platform_node_js_1.Raws.Primitive.Int.read(bytes); if (E2ELength) { e2e = await this._loadE2E(await bytes.read(E2ELength)); } for (let i = 0; i < peerLength; i++) { const count = await platform_node_js_1.Raws.Primitive.Int.read(cacheBytes); peer.push(await (0, SnakeSession_js_1.buildPeerFromBytes)(cacheBytes.read(count))); } } else { Logger_js_1.Logger.info(`Load cache version: 1`); const bytes = new platform_node_js_1.Raws.BytesIO(buffer); const length = await platform_node_js_1.Raws.Primitive.Int.read(bytes); for (let i = 0; i < length; i++) { let count = await platform_node_js_1.Raws.Primitive.Int.read(bytes); peer.push(await (0, SnakeSession_js_1.buildPeerFromBytes)(bytes.read(count))); } } } return [ peer, e2e, ]; } async _loadE2E(bytes) { const secretChat = []; if (bytes[0] === 1) { const b = new platform_node_js_1.Raws.BytesIO(bytes.slice(1)); const length = await platform_node_js_1.Raws.Primitive.Int.read(b); for (let i = 0; i < length; i++) { const count = await platform_node_js_1.Raws.Primitive.Int.read(b); secretChat.push(await (0, SnakeSession_js_1.buildSecretChatFromBytes)(b.read(count))); } } return secretChat; } async _makeCache() { let count = 0; const bytes = new platform_node_js_1.Raws.BytesIO(); for (const [, value] of this._peers) { count += 1; const content = await (0, SnakeSession_js_1.buildBytesFromPeer)(value); bytes.write(platform_node_js_1.Buffer.concat([platform_node_js_1.Raws.Primitive.Int.write(content.length), content])); } let e2e = platform_node_js_1.Buffer.alloc(0); if (this._secretChats.size) { e2e = await this._makeE2E(); } const cache = platform_node_js_1.Buffer.concat([platform_node_js_1.Raws.Primitive.Int.write(count), bytes.buffer]); return platform_node_js_1.Buffer.concat([ platform_node_js_1.Buffer.from([2]), platform_node_js_1.Raws.Primitive.Int.write(cache.length), cache, platform_node_js_1.Raws.Primitive.Int.write(e2e.length), e2e, ]); } async _makeE2E() { let count = 0; const bytes = new platform_node_js_1.Raws.BytesIO(); for (const [, value] of this._secretChats) { count += 1; const content = await (0, SnakeSession_js_1.buildBytesFromSecretChat)(value); bytes.write(platform_node_js_1.Buffer.concat([platform_node_js_1.Raws.Primitive.Int.write(content.length), content])); } return platform_node_js_1.Buffer.concat([platform_node_js_1.Buffer.from([1]), platform_node_js_1.Raws.Primitive.Int.write(count), bytes.buffer]); } [Symbol.for('nodejs.util.inspect.custom')]() { const toPrint = { _: this.constructor.name, }; for (const key in this) { if (this.hasOwnProperty(key)) { const value = this[key]; if (!key.startsWith('_')) { toPrint[key] = value; } } } return toPrint; } toJSON() { const toPrint = { _: this.constructor.name, }; for (const key in this) { if (this.hasOwnProperty(key)) { const value = this[key]; if (!key.startsWith('_')) { toPrint[key] = typeof value === 'bigint' ? String(value) : value; } } } return toPrint; } toString() { return `[constructor of ${this.constructor.name}] ${JSON.stringify(this, null, 2)}`; } } exports.BrowserSession = BrowserSession;