Correctly handle account with invalid access token
Show a popup saying the session was signed out and cleanup the models data, instead of spamming the users with never-ending errors.
This commit is contained in:
parent
3c9895b0b2
commit
7b6478f514
1
TODO.md
1
TODO.md
|
@ -2,7 +2,6 @@
|
|||
|
||||
- Fix right margin of own `<image url>\n<image url>` messages
|
||||
|
||||
- handle invalid access token
|
||||
- If an account is gone from the user's config, discard UI state last page
|
||||
- filter > enter > room list is always scrolled to top
|
||||
- ctrl+j/k when scrolled up
|
||||
|
|
|
@ -18,7 +18,7 @@ from appdirs import AppDirs
|
|||
import nio
|
||||
|
||||
from . import __app_name__
|
||||
from .errors import MatrixError
|
||||
from .errors import MatrixError, MatrixInvalidAccessToken
|
||||
from .matrix_client import MatrixClient
|
||||
from .media_cache import MediaCache
|
||||
from .models import SyncId
|
||||
|
@ -305,6 +305,11 @@ class Backend:
|
|||
client = self.clients.pop(user_id, None)
|
||||
|
||||
if client:
|
||||
try:
|
||||
await client.logout()
|
||||
except MatrixInvalidAccessToken:
|
||||
pass
|
||||
|
||||
self.models["accounts"].pop(user_id, None)
|
||||
self.models["matching_accounts"].pop(user_id, None)
|
||||
self.models[user_id, "uploads"].clear()
|
||||
|
@ -317,8 +322,6 @@ class Backend:
|
|||
|
||||
self.models[user_id, "rooms"].clear()
|
||||
|
||||
await client.logout()
|
||||
|
||||
await self.saved_accounts.delete(user_id)
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,12 @@ class MatrixError(Exception):
|
|||
return cls(response.transport_response.status, response.status_code)
|
||||
|
||||
|
||||
@dataclass
|
||||
class MatrixInvalidAccessToken(MatrixError):
|
||||
http_code: int = 401
|
||||
m_code: str = "M_UNKNOWN_TOKEN"
|
||||
|
||||
|
||||
@dataclass
|
||||
class MatrixUnauthorized(MatrixError):
|
||||
http_code: int = 401
|
||||
|
|
|
@ -36,8 +36,9 @@ from nio.crypto import async_generator_from_data
|
|||
from . import __app_name__, __display_name__, utils
|
||||
from .errors import (
|
||||
BadMimeType, InvalidUserId, InvalidUserInContext, MatrixBadGateway,
|
||||
MatrixError, MatrixForbidden, MatrixNotFound, MatrixTooLarge,
|
||||
MatrixUnauthorized, UneededThumbnail, UserFromOtherServerDisallowed,
|
||||
MatrixError, MatrixForbidden, MatrixInvalidAccessToken, MatrixNotFound,
|
||||
MatrixTooLarge, MatrixUnauthorized, UneededThumbnail,
|
||||
UserFromOtherServerDisallowed,
|
||||
)
|
||||
from .html_markdown import HTML_PROCESSOR as HTML
|
||||
from .media_cache import Media, Thumbnail
|
||||
|
@ -47,7 +48,9 @@ from .models.items import (
|
|||
from .models.model_store import ModelStore
|
||||
from .nio_callbacks import NioCallbacks
|
||||
from .presence import Presence
|
||||
from .pyotherside_events import AlertRequested, LoopException
|
||||
from .pyotherside_events import (
|
||||
AlertRequested, InvalidAccessToken, LoopException,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .backend import Backend
|
||||
|
@ -201,6 +204,8 @@ class MatrixClient(nio.AsyncClient):
|
|||
# {room_id: event}
|
||||
self.power_level_events: Dict[str, nio.PowerLevelsEvent] = {}
|
||||
|
||||
self.invalid_disconnecting: bool = False
|
||||
|
||||
self.nio_callbacks = NioCallbacks(self)
|
||||
|
||||
|
||||
|
@ -236,7 +241,15 @@ class MatrixClient(nio.AsyncClient):
|
|||
response = await super()._send(*args, **kwargs)
|
||||
|
||||
if isinstance(response, nio.ErrorResponse):
|
||||
raise MatrixError.from_nio(response)
|
||||
try:
|
||||
raise MatrixError.from_nio(response)
|
||||
except MatrixInvalidAccessToken:
|
||||
if not self.invalid_disconnecting:
|
||||
self.invalid_disconnecting = True
|
||||
InvalidAccessToken(self.user_id)
|
||||
await self.backend.logout_client(self.user_id)
|
||||
|
||||
raise
|
||||
|
||||
return response
|
||||
|
||||
|
|
|
@ -98,3 +98,10 @@ class DevicesUpdated(PyOtherSideEvent):
|
|||
"""Indicate changes in devices for us or users we share a room with."""
|
||||
|
||||
our_user_id: str = field()
|
||||
|
||||
|
||||
@dataclass
|
||||
class InvalidAccessToken(PyOtherSideEvent):
|
||||
"""Indicate one of our account's access token is invalid or revoked."""
|
||||
|
||||
user_id: str = field()
|
||||
|
|
46
src/gui/Popups/InvalidAccessTokenPopup.qml
Normal file
46
src/gui/Popups/InvalidAccessTokenPopup.qml
Normal file
|
@ -0,0 +1,46 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import "../Base"
|
||||
import "../Base/Buttons"
|
||||
|
||||
HFlickableColumnPopup {
|
||||
id: popup
|
||||
|
||||
property string userId
|
||||
|
||||
signal signBackInRequest()
|
||||
|
||||
page.footer: AutoDirectionLayout {
|
||||
ApplyButton {
|
||||
id: signBackButton
|
||||
text: qsTr("Sign back in")
|
||||
icon.name: "sign-back-in"
|
||||
onClicked: {
|
||||
const page = "Pages/AddAccount/AddAccount.qml"
|
||||
window.mainUI.pageLoader.show(page)
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
|
||||
CancelButton {
|
||||
text: qsTr("Close")
|
||||
onClicked: popup.close()
|
||||
}
|
||||
}
|
||||
|
||||
SummaryLabel {
|
||||
text: qsTr("Signed out from %1").arg(coloredNameHtml("", userId))
|
||||
textFormat: SummaryLabel.StyledText
|
||||
}
|
||||
|
||||
DetailsLabel {
|
||||
text: qsTr(
|
||||
"You have been disconnected from another session, " +
|
||||
"by the server for security reasons, or the access token in " +
|
||||
"your configuration file is invalid."
|
||||
)
|
||||
}
|
||||
|
||||
onOpened: signBackButton.forceActiveFocus()
|
||||
}
|
|
@ -94,4 +94,8 @@ QtObject {
|
|||
function onDevicesUpdated(forAccount) {
|
||||
deviceUpdateSignal(forAccount)
|
||||
}
|
||||
|
||||
function onInvalidAccessToken(userId) {
|
||||
window.makePopup("Popups/InvalidAccessTokenPopup.qml", {userId})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,7 @@ import QtQuick 2.12
|
|||
|
||||
QtObject {
|
||||
readonly property var pendingCoroutines: ({})
|
||||
readonly property var hideErrorTypes: new Set(["gaierror", "SSLError"])
|
||||
readonly property var hideErrorTypes: new Set([
|
||||
"gaierror", "SSLError", "MatrixInvalidAccessToken",
|
||||
])
|
||||
}
|
||||
|
|
3
src/icons/thin/sign-back-in.svg
Normal file
3
src/icons/thin/sign-back-in.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m16 2c3.309 0 6 2.691 6 6s-2.691 6-6 6-6-2.691-6-6 2.691-6 6-6zm0-2c-4.418 0-8 3.582-8 8s3.582 8 8 8 8-3.582 8-8-3.582-8-8-8zm-5.405 16.4-1.472 1.6h-3.123v2h-2v2h-2v-2.179l5.903-5.976c-.404-.559-.754-1.158-1.038-1.795l-6.865 6.95v5h6v-2h2v-2h2l2.451-2.663c-.655-.249-1.276-.562-1.856-.937zm7.405-11.4c.551 0 1 .449 1 1s-.449 1-1 1-1-.449-1-1 .449-1 1-1zm0-1c-1.104 0-2 .896-2 2s.896 2 2 2 2-.896 2-2-.896-2-2-2z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 519 B |
Loading…
Reference in New Issue
Block a user