TelegramPWA/src/lib/gramjs/sessions/StringSession.js
2022-05-06 17:56:12 +01:00

106 lines
3.0 KiB
JavaScript

const MemorySession = require('./Memory');
const AuthKey = require('../crypto/AuthKey');
const BinaryReader = require('../extensions/BinaryReader');
const CURRENT_VERSION = '1';
class StringSession extends MemorySession {
/**
* This session file can be easily saved and loaded as a string. According
* to the initial design, it contains only the data that is necessary for
* successful connection and authentication, so takeout ID is not stored.
* It is thought to be used where you don't want to create any on-disk
* files but would still like to be able to save and load existing sessions
* by other means.
* You can use custom `encode` and `decode` functions, if present:
* `encode` definition must be ``function encode(value: Buffer) -> string:``.
* `decode` definition must be ``function decode(value: string) -> Buffer:``.
* @param session {string|null}
*/
constructor(session = undefined) {
super();
if (session) {
if (session[0] !== CURRENT_VERSION) {
throw new Error('Not a valid string');
}
session = session.slice(1);
const r = StringSession.decode(session);
const reader = new BinaryReader(r);
this._dcId = reader.read(1)
.readUInt8(0);
const serverAddressLen = reader.read(2)
.readInt16BE(0);
this._serverAddress = String(reader.read(serverAddressLen));
this._port = reader.read(2)
.readInt16BE(0);
this._key = reader.read(-1);
}
}
/**
* @param x {Buffer}
* @returns {string}
*/
static encode(x) {
return x.toString('base64');
}
/**
* @param x {string}
* @returns {Buffer}
*/
static decode(x) {
return Buffer.from(x, 'base64');
}
async load() {
if (this._key) {
this._authKey = new AuthKey();
await this._authKey.setKey(this._key);
}
}
save() {
if (!this.authKey) {
return '';
}
const dcBuffer = Buffer.from([this.dcId]);
const addressBuffer = Buffer.from(this.serverAddress);
const addressLengthBuffer = Buffer.alloc(2);
addressLengthBuffer.writeInt16BE(addressBuffer.length, 0);
const portBuffer = Buffer.alloc(2);
portBuffer.writeInt16BE(this.port, 0);
return CURRENT_VERSION + StringSession.encode(Buffer.concat([
dcBuffer,
addressLengthBuffer,
addressBuffer,
portBuffer,
this.authKey.getKey(),
]));
}
getAuthKey(dcId) {
if (dcId && dcId !== this.dcId) {
// Not supported.
return undefined;
}
return this.authKey;
}
setAuthKey(authKey, dcId) {
if (dcId && dcId !== this.dcId) {
// Not supported.
return;
}
this.authKey = authKey;
}
}
module.exports = StringSession;