tgsnake
Version:
Telegram MTProto framework for nodejs.
163 lines (162 loc) • 7.48 kB
JavaScript
;
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;