fix: properly handle peers without access hash
This commit is contained in:
parent
89fd8e8ef0
commit
7d10e65ecc
2 changed files with 84 additions and 30 deletions
|
@ -7,7 +7,7 @@ import {
|
|||
} from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MtNotFoundError } from '../../types'
|
||||
import { InputPeerLike, MtNotFoundError, MtTypeAssertionError } from "../../types";
|
||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
|
@ -83,35 +83,58 @@ export async function resolvePeer(
|
|||
const id = res.peer.userId
|
||||
|
||||
const found = res.users.find((it) => it.id === id)
|
||||
if (found && found._ === 'user')
|
||||
if (found && found._ === 'user') {
|
||||
if (!found.accessHash) {
|
||||
// no access hash, we can't use it
|
||||
// this may happen when bot resolves a username
|
||||
// of a user who hasn't started a conversation with it
|
||||
throw new MtNotFoundError(
|
||||
`Peer (user) with username ${peerId} was found, but it has no access hash`
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
_: 'inputPeerUser',
|
||||
userId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
accessHash: found.accessHash,
|
||||
}
|
||||
} else {
|
||||
const id =
|
||||
res.peer._ === 'peerChannel'
|
||||
? res.peer.channelId
|
||||
: res.peer.chatId
|
||||
|
||||
}
|
||||
} else if (res.peer._ === 'peerChannel') {
|
||||
const id = res.peer.channelId
|
||||
const found = res.chats.find((it) => it.id === id)
|
||||
if (found)
|
||||
switch (found._) {
|
||||
case 'channel':
|
||||
case 'channelForbidden':
|
||||
|
||||
if (found) {
|
||||
if (!(found._ === 'channel' || found._ === 'channelForbidden')) {
|
||||
// chats can't have usernames
|
||||
// furthermore, our id is a channel id, so it must be a channel
|
||||
// this should never happen, unless Telegram goes crazy
|
||||
throw new MtTypeAssertionError(
|
||||
'contacts.resolveUsername#chats',
|
||||
'channel',
|
||||
found._
|
||||
)
|
||||
}
|
||||
|
||||
if (!found.accessHash) {
|
||||
// shouldn't happen? but just in case
|
||||
throw new MtNotFoundError(
|
||||
`Peer (channel) with username ${peerId} was found, but it has no access hash`
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
_: 'inputPeerChannel',
|
||||
channelId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
}
|
||||
case 'chat':
|
||||
case 'chatForbidden':
|
||||
return {
|
||||
_: 'inputPeerChat',
|
||||
chatId: found.id,
|
||||
accessHash: found.accessHash,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// chats can't have usernames
|
||||
throw new MtTypeAssertionError(
|
||||
'contacts.resolveUsername',
|
||||
'user or channel',
|
||||
res.peer._
|
||||
)
|
||||
}
|
||||
|
||||
throw new MtNotFoundError(
|
||||
|
@ -137,11 +160,19 @@ export async function resolvePeer(
|
|||
})
|
||||
|
||||
const found = res.find((it) => it.id === peerId)
|
||||
if (found && found._ === 'user')
|
||||
if (found && found._ === 'user') {
|
||||
if (!found.accessHash) {
|
||||
// shouldn't happen? but just in case
|
||||
throw new MtNotFoundError(
|
||||
`Peer (user) with username ${peerId} was found, but it has no access hash`
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
_: 'inputPeerUser',
|
||||
userId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
accessHash: found.accessHash,
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
|
@ -185,11 +216,19 @@ export async function resolvePeer(
|
|||
if (
|
||||
found &&
|
||||
(found._ === 'channel' || found._ === 'channelForbidden')
|
||||
) {
|
||||
if (!found.accessHash) {
|
||||
// shouldn't happen? but just in case
|
||||
throw new MtNotFoundError(
|
||||
`Peer (channel) with username ${peerId} was found, but it has no access hash`
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
_: 'inputPeerChannel',
|
||||
channelId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
accessHash: found.accessHash ?? Long.ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
|
|
|
@ -889,9 +889,17 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
|
||||
switch (peer._) {
|
||||
case 'user':
|
||||
if (!peer.accessHash) {
|
||||
this.log.warn(
|
||||
'received user without access hash: %j',
|
||||
peer
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
parsedPeers.push({
|
||||
id: peer.id,
|
||||
accessHash: peer.accessHash!,
|
||||
accessHash: peer.accessHash,
|
||||
username: peer.username?.toLowerCase(),
|
||||
phone: peer.phone,
|
||||
type: 'user',
|
||||
|
@ -909,9 +917,16 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
break
|
||||
case 'channel':
|
||||
case 'channelForbidden':
|
||||
if (!peer.accessHash) {
|
||||
this.log.warn(
|
||||
'received user without access hash: %j',
|
||||
peer
|
||||
)
|
||||
continue
|
||||
}
|
||||
parsedPeers.push({
|
||||
id: toggleChannelIdMark(peer.id),
|
||||
accessHash: peer.accessHash!,
|
||||
accessHash: peer.accessHash,
|
||||
username:
|
||||
peer._ === 'channel'
|
||||
? peer.username?.toLowerCase()
|
||||
|
|
Loading…
Reference in a new issue