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'
|
} from '@mtcute/core'
|
||||||
|
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { InputPeerLike, MtNotFoundError } from '../../types'
|
import { InputPeerLike, MtNotFoundError, MtTypeAssertionError } from "../../types";
|
||||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||||
import { assertTypeIs } from '../../utils/type-assertion'
|
import { assertTypeIs } from '../../utils/type-assertion'
|
||||||
|
|
||||||
|
@ -83,35 +83,58 @@ export async function resolvePeer(
|
||||||
const id = res.peer.userId
|
const id = res.peer.userId
|
||||||
|
|
||||||
const found = res.users.find((it) => it.id === id)
|
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 {
|
return {
|
||||||
_: 'inputPeerUser',
|
_: 'inputPeerUser',
|
||||||
userId: found.id,
|
userId: found.id,
|
||||||
accessHash: found.accessHash!,
|
accessHash: found.accessHash,
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
const id =
|
} else if (res.peer._ === 'peerChannel') {
|
||||||
res.peer._ === 'peerChannel'
|
const id = res.peer.channelId
|
||||||
? res.peer.channelId
|
|
||||||
: res.peer.chatId
|
|
||||||
|
|
||||||
const found = res.chats.find((it) => it.id === id)
|
const found = res.chats.find((it) => it.id === id)
|
||||||
if (found)
|
|
||||||
switch (found._) {
|
if (found) {
|
||||||
case 'channel':
|
if (!(found._ === 'channel' || found._ === 'channelForbidden')) {
|
||||||
case '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 {
|
return {
|
||||||
_: 'inputPeerChannel',
|
_: 'inputPeerChannel',
|
||||||
channelId: found.id,
|
channelId: found.id,
|
||||||
accessHash: found.accessHash!,
|
accessHash: found.accessHash,
|
||||||
}
|
|
||||||
case 'chat':
|
|
||||||
case 'chatForbidden':
|
|
||||||
return {
|
|
||||||
_: 'inputPeerChat',
|
|
||||||
chatId: found.id,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// chats can't have usernames
|
||||||
|
throw new MtTypeAssertionError(
|
||||||
|
'contacts.resolveUsername',
|
||||||
|
'user or channel',
|
||||||
|
res.peer._
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MtNotFoundError(
|
throw new MtNotFoundError(
|
||||||
|
@ -137,11 +160,19 @@ export async function resolvePeer(
|
||||||
})
|
})
|
||||||
|
|
||||||
const found = res.find((it) => it.id === peerId)
|
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 {
|
return {
|
||||||
_: 'inputPeerUser',
|
_: 'inputPeerUser',
|
||||||
userId: found.id,
|
userId: found.id,
|
||||||
accessHash: found.accessHash!,
|
accessHash: found.accessHash,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
@ -185,11 +216,19 @@ export async function resolvePeer(
|
||||||
if (
|
if (
|
||||||
found &&
|
found &&
|
||||||
(found._ === 'channel' || found._ === 'channelForbidden')
|
(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 {
|
return {
|
||||||
_: 'inputPeerChannel',
|
_: 'inputPeerChannel',
|
||||||
channelId: found.id,
|
channelId: found.id,
|
||||||
accessHash: found.accessHash!,
|
accessHash: found.accessHash ?? Long.ZERO,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
|
@ -889,9 +889,17 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
|
|
||||||
switch (peer._) {
|
switch (peer._) {
|
||||||
case 'user':
|
case 'user':
|
||||||
|
if (!peer.accessHash) {
|
||||||
|
this.log.warn(
|
||||||
|
'received user without access hash: %j',
|
||||||
|
peer
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
parsedPeers.push({
|
parsedPeers.push({
|
||||||
id: peer.id,
|
id: peer.id,
|
||||||
accessHash: peer.accessHash!,
|
accessHash: peer.accessHash,
|
||||||
username: peer.username?.toLowerCase(),
|
username: peer.username?.toLowerCase(),
|
||||||
phone: peer.phone,
|
phone: peer.phone,
|
||||||
type: 'user',
|
type: 'user',
|
||||||
|
@ -909,9 +917,16 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
break
|
break
|
||||||
case 'channel':
|
case 'channel':
|
||||||
case 'channelForbidden':
|
case 'channelForbidden':
|
||||||
|
if (!peer.accessHash) {
|
||||||
|
this.log.warn(
|
||||||
|
'received user without access hash: %j',
|
||||||
|
peer
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
parsedPeers.push({
|
parsedPeers.push({
|
||||||
id: toggleChannelIdMark(peer.id),
|
id: toggleChannelIdMark(peer.id),
|
||||||
accessHash: peer.accessHash!,
|
accessHash: peer.accessHash,
|
||||||
username:
|
username:
|
||||||
peer._ === 'channel'
|
peer._ === 'channel'
|
||||||
? peer.username?.toLowerCase()
|
? peer.username?.toLowerCase()
|
||||||
|
|
Loading…
Reference in a new issue