diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 5b3dd794..84513c29 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -15,7 +15,7 @@ import { import { MemoryStorage } from '@mtcute/core/src/storage/memory.js' import { tdFileId } from '@mtcute/file-id' -import { AuthState, getAuthState, isSelfPeer } from './methods/auth/_state.js' +import { AuthState, getAuthState, isSelfPeer, setupAuthState } from './methods/auth/_state.js' import { checkPassword } from './methods/auth/check-password.js' import { getPasswordHint } from './methods/auth/get-password-hint.js' import { logOut } from './methods/auth/log-out.js' @@ -533,7 +533,14 @@ export interface TelegramClient extends BaseTelegramClient { // eslint-disable-next-line @typescript-eslint/no-explicit-any on(name: string, handler: (...args: any[]) => void): this - + /** + * Get auth state for the given client, containing + * information about the current user. + * + * Auth state must first be initialized with {@link setupAuthState}. + * **Available**: ✅ both users and bots + * + */ getAuthState(): AuthState /** * Check if the given peer/input peer is referring to the current user @@ -5266,6 +5273,8 @@ export class TelegramClient extends BaseTelegramClient { }, }), }) + } else { + setupAuthState(this) } } } diff --git a/packages/client/src/methods/_init.ts b/packages/client/src/methods/_init.ts index 0116084d..f45e70a6 100644 --- a/packages/client/src/methods/_init.ts +++ b/packages/client/src/methods/_init.ts @@ -10,6 +10,8 @@ import { Conversation } from '../types/conversation.js' // @copy import { _defaultStorageFactory } from '../utils/platform/storage.js' // @copy +import { setupAuthState } from './auth/_state.js' +// @copy import { enableUpdatesProcessing, makeParsedUpdateHandler, @@ -107,5 +109,7 @@ function _initializeClient(this: TelegramClient, opts: TelegramClientOptions) { }, }), }) + } else { + setupAuthState(this) } } diff --git a/packages/client/src/methods/auth/_state.ts b/packages/client/src/methods/auth/_state.ts index 5472aeda..bdd0f595 100644 --- a/packages/client/src/methods/auth/_state.ts +++ b/packages/client/src/methods/auth/_state.ts @@ -1,5 +1,5 @@ /* eslint-disable no-inner-declarations */ -import { BaseTelegramClient, MtUnsupportedError, tl } from '@mtcute/core' +import { BaseTelegramClient, MtArgumentError, MtUnsupportedError, tl } from '@mtcute/core' import { assertTypeIs } from '@mtcute/core/utils.js' import { User } from '../../types/peers/user.js' @@ -18,53 +18,73 @@ export interface AuthState { selfChanged?: boolean } +/** + * Initialize auth state for the given client. + * + * Allows {@link getAuthState} to be used and is required for some methods. + * @noemit + */ +export function setupAuthState(client: BaseTelegramClient): void { + // eslint-disable-next-line + let state: AuthState = (client as any)[STATE_SYMBOL] + if (state) return + + // init + // eslint-disable-next-line @typescript-eslint/no-explicit-any + state = (client as any)[STATE_SYMBOL] = { + userId: null, + isBot: false, + selfUsername: null, + } + + client.log.prefix = '[USER N/A] ' + + function onBeforeConnect() { + Promise.resolve(client.storage.getSelf()) + .then((self) => { + if (!self) return + + state.userId = self.userId + state.isBot = self.isBot + client.log.prefix = `[USER ${self.userId}] ` + }) + .catch((err) => client._emitError(err)) + } + + async function onBeforeStorageSave() { + if (state.selfChanged) { + await client.storage.setSelf( + state.userId ? + { + userId: state.userId, + isBot: state.isBot, + } : + null, + ) + state.selfChanged = false + } + } + + client.on('before_connect', onBeforeConnect) + client.beforeStorageSave(onBeforeStorageSave) + client.on('before_stop', () => { + client.off('before_connect', onBeforeConnect) + client.offBeforeStorageSave(onBeforeStorageSave) + }) +} + +/** + * Get auth state for the given client, containing + * information about the current user. + * + * Auth state must first be initialized with {@link setupAuthState}. + */ export function getAuthState(client: BaseTelegramClient): AuthState { // eslint-disable-next-line let state: AuthState = (client as any)[STATE_SYMBOL] if (!state) { - // init - // eslint-disable-next-line @typescript-eslint/no-explicit-any - state = (client as any)[STATE_SYMBOL] = { - userId: null, - isBot: false, - selfUsername: null, - } - - client.log.prefix = '[USER N/A] ' - - function onBeforeConnect() { - Promise.resolve(client.storage.getSelf()) - .then((self) => { - if (!self) return - - state.userId = self.userId - state.isBot = self.isBot - client.log.prefix = `[USER ${self.userId}] ` - }) - .catch((err) => client._emitError(err)) - } - - async function onBeforeStorageSave() { - if (state.selfChanged) { - await client.storage.setSelf( - state.userId ? - { - userId: state.userId, - isBot: state.isBot, - } : - null, - ) - state.selfChanged = false - } - } - - client.on('before_connect', onBeforeConnect) - client.beforeStorageSave(onBeforeStorageSave) - client.on('before_stop', () => { - client.off('before_connect', onBeforeConnect) - client.offBeforeStorageSave(onBeforeStorageSave) - }) + throw new MtArgumentError('Auth state is not initialized, use setupAuthState()') } return state diff --git a/packages/client/src/methods/updates/manager.ts b/packages/client/src/methods/updates/manager.ts index 75f01904..96cc99e2 100644 --- a/packages/client/src/methods/updates/manager.ts +++ b/packages/client/src/methods/updates/manager.ts @@ -6,7 +6,7 @@ import { PeersIndex } from '../../types/index.js' import { isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/peer-utils.js' import { RpsMeter } from '../../utils/rps-meter.js' import { createDummyUpdatesContainer } from '../../utils/updates-utils.js' -import { getAuthState } from '../auth/_state.js' +import { getAuthState, setupAuthState } from '../auth/_state.js' import { _getChannelsBatched, _getUsersBatched } from '../chats/batched-queries.js' import { resolvePeer } from '../users/resolve-peer.js' import { createUpdatesState, PendingUpdate, toPendingUpdate, UpdatesManagerParams, UpdatesState } from './types.js' @@ -84,6 +84,8 @@ export function getCurrentRpsProcessing(client: BaseTelegramClient): number { export function enableUpdatesProcessing(client: BaseTelegramClient, params: UpdatesManagerParams): void { if (getState(client)) return + setupAuthState(client) + if (client.network.params.disableUpdates) { throw new MtArgumentError('Updates must be enabled to use updates manager') }