106 lines
3.0 KiB
JavaScript
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;
|