refactor: exported string session parsing/serialization to a module
This commit is contained in:
parent
8adb79511f
commit
416b3d9ef9
3 changed files with 107 additions and 56 deletions
|
@ -38,6 +38,7 @@ import { ITelegramStorage, MemoryStorage } from './storage'
|
||||||
|
|
||||||
import defaultReaderMap from '@mtcute/tl/binary/reader'
|
import defaultReaderMap from '@mtcute/tl/binary/reader'
|
||||||
import defaultWriterMap from '@mtcute/tl/binary/writer'
|
import defaultWriterMap from '@mtcute/tl/binary/writer'
|
||||||
|
import { readStringSession, writeStringSession } from "./utils/string-session";
|
||||||
|
|
||||||
export namespace BaseTelegramClient {
|
export namespace BaseTelegramClient {
|
||||||
export interface Options {
|
export interface Options {
|
||||||
|
@ -444,41 +445,23 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
)
|
)
|
||||||
|
|
||||||
if ((this._importForce || !this.primaryConnection.getAuthKey()) && this._importFrom) {
|
if ((this._importForce || !this.primaryConnection.getAuthKey()) && this._importFrom) {
|
||||||
const buf = parseUrlSafeBase64(this._importFrom)
|
const data = readStringSession(this._readerMap, this._importFrom)
|
||||||
if (buf[0] !== 1)
|
|
||||||
throw new Error(`Invalid session string (version = ${buf[0]})`)
|
|
||||||
|
|
||||||
const reader = new TlBinaryReader(this._readerMap, buf, 1)
|
if (data.testMode !== !this._testMode) {
|
||||||
|
|
||||||
const flags = reader.int()
|
|
||||||
const hasSelf = flags & 1
|
|
||||||
|
|
||||||
if (!(flags & 2) !== !this._testMode) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'This session string is not for the current backend'
|
'This session string is not for the current backend'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const primaryDc = reader.object()
|
this._primaryDc = this.primaryConnection.params.dc = data.primaryDc
|
||||||
if (primaryDc._ !== 'dcOption') {
|
await this.storage.setDefaultDc(data.primaryDc)
|
||||||
throw new Error(
|
|
||||||
`Invalid session string (dc._ = ${primaryDc._})`
|
if (data.self) {
|
||||||
)
|
await this.storage.setSelf(data.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._primaryDc = this.primaryConnection.params.dc = primaryDc
|
await this.primaryConnection.setupKeys(data.authKey)
|
||||||
await this.storage.setDefaultDc(primaryDc)
|
await this.storage.setAuthKeyFor(data.primaryDc.id, data.authKey)
|
||||||
|
|
||||||
if (hasSelf) {
|
|
||||||
const selfId = reader.int53()
|
|
||||||
const selfBot = reader.boolean()
|
|
||||||
|
|
||||||
await this.storage.setSelf({ userId: selfId, isBot: selfBot })
|
|
||||||
}
|
|
||||||
|
|
||||||
const key = reader.bytes()
|
|
||||||
await this.primaryConnection.setupKeys(key)
|
|
||||||
await this.storage.setAuthKeyFor(primaryDc.id, key)
|
|
||||||
|
|
||||||
await this._saveStorage(true)
|
await this._saveStorage(true)
|
||||||
}
|
}
|
||||||
|
@ -968,35 +951,13 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
if (!this.primaryConnection.getAuthKey())
|
if (!this.primaryConnection.getAuthKey())
|
||||||
throw new Error('Auth key is not generated yet')
|
throw new Error('Auth key is not generated yet')
|
||||||
|
|
||||||
const writer = TlBinaryWriter.alloc(this._writerMap, 512)
|
return writeStringSession(this._writerMap, {
|
||||||
|
version: 1,
|
||||||
const self = await this.storage.getSelf()
|
self: await this.storage.getSelf(),
|
||||||
|
testMode: this._testMode,
|
||||||
const version = 1
|
primaryDc: this._primaryDc,
|
||||||
let flags = 0
|
authKey: this.primaryConnection.getAuthKey()!,
|
||||||
|
})
|
||||||
if (self) {
|
|
||||||
flags |= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._testMode) {
|
|
||||||
flags |= 2
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.buffer[0] = version
|
|
||||||
writer.pos += 1
|
|
||||||
|
|
||||||
writer.int(flags)
|
|
||||||
writer.object(this._primaryDc)
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
writer.int53(self.userId)
|
|
||||||
writer.boolean(self.isBot)
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.bytes(this.primaryConnection.getAuthKey()!)
|
|
||||||
|
|
||||||
return encodeUrlSafeBase64(writer.result())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,3 +19,4 @@ export * from './misc-utils'
|
||||||
export * from './peer-utils'
|
export * from './peer-utils'
|
||||||
export * from './sorted-array'
|
export * from './sorted-array'
|
||||||
export * from './tl-json'
|
export * from './tl-json'
|
||||||
|
export * from './string-session'
|
||||||
|
|
89
packages/core/src/utils/string-session.ts
Normal file
89
packages/core/src/utils/string-session.ts
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { TlBinaryReader, TlBinaryWriter, TlReaderMap, TlWriterMap } from "@mtcute/tl-runtime/dist";
|
||||||
|
import { encodeUrlSafeBase64, parseUrlSafeBase64 } from "./buffer-utils";
|
||||||
|
import { ITelegramStorage } from '../storage'
|
||||||
|
|
||||||
|
export interface StringSessionData {
|
||||||
|
version: number
|
||||||
|
testMode: boolean
|
||||||
|
primaryDc: tl.TypeDcOption
|
||||||
|
self?: ITelegramStorage.SelfInfo | null
|
||||||
|
authKey: Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writeStringSession(
|
||||||
|
writerMap: TlWriterMap,
|
||||||
|
data: StringSessionData
|
||||||
|
): string {
|
||||||
|
const writer = TlBinaryWriter.alloc(writerMap, 512)
|
||||||
|
|
||||||
|
const version = data.version
|
||||||
|
if (version !== 1) {
|
||||||
|
throw new Error(`Unsupported string session version: ${version}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let flags = 0
|
||||||
|
|
||||||
|
if (data.self) {
|
||||||
|
flags |= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.testMode) {
|
||||||
|
flags |= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.buffer[0] = version
|
||||||
|
writer.pos += 1
|
||||||
|
|
||||||
|
writer.int(flags)
|
||||||
|
writer.object(data.primaryDc)
|
||||||
|
|
||||||
|
if (data.self) {
|
||||||
|
writer.int53(data.self.userId)
|
||||||
|
writer.boolean(data.self.isBot)
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.bytes(data.authKey)
|
||||||
|
|
||||||
|
return encodeUrlSafeBase64(writer.result())
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readStringSession(readerMap: TlReaderMap, data: string): StringSessionData {
|
||||||
|
const buf = parseUrlSafeBase64(data)
|
||||||
|
if (buf[0] !== 1)
|
||||||
|
throw new Error(`Invalid session string (version = ${buf[0]})`)
|
||||||
|
|
||||||
|
const reader = new TlBinaryReader(readerMap, buf, 1)
|
||||||
|
|
||||||
|
const flags = reader.int()
|
||||||
|
const hasSelf = flags & 1
|
||||||
|
const testMode = !!(flags & 2)
|
||||||
|
|
||||||
|
const primaryDc = reader.object()
|
||||||
|
if (primaryDc._ !== 'dcOption') {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid session string (dc._ = ${primaryDc._})`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let self: ITelegramStorage.SelfInfo | null = null
|
||||||
|
if (hasSelf) {
|
||||||
|
const selfId = reader.int53()
|
||||||
|
const selfBot = reader.boolean()
|
||||||
|
|
||||||
|
self = {
|
||||||
|
userId: selfId,
|
||||||
|
isBot: selfBot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = reader.bytes()
|
||||||
|
|
||||||
|
return {
|
||||||
|
version: 1,
|
||||||
|
testMode,
|
||||||
|
primaryDc,
|
||||||
|
self,
|
||||||
|
authKey: key,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue