Implement session sign out (password auth only)
This commit is contained in:
parent
8a3d9affaa
commit
b47d4d981f
|
@ -32,7 +32,7 @@ Written in Qt/QML + Python with [nio](https://github.com/poljar/matrix-nio),
|
|||
- **Multiple accounts** in one client
|
||||
- Set your display name and profile picture
|
||||
- Import/export **E2E** key files
|
||||
- Inspect, rename and manually verify your sessions
|
||||
- Inspect, rename, manually verify and sign out one or multiple sessions
|
||||
|
||||
### Rooms
|
||||
|
||||
|
|
1
TODO.md
1
TODO.md
|
@ -185,7 +185,6 @@
|
|||
- E2E
|
||||
- List and verify other users's devices
|
||||
- SAS verification
|
||||
- Delete devices (do that in key verification popup instead of blacklisting)
|
||||
- Request room keys from own other devices
|
||||
- Auto-trust accounts within the same client
|
||||
- Provide help when undecryptable messages occur, including:
|
||||
|
|
|
@ -33,6 +33,12 @@ class MatrixError(Exception):
|
|||
return cls(response.transport_response.status, response.status_code)
|
||||
|
||||
|
||||
@dataclass
|
||||
class MatrixUnauthorized(MatrixError):
|
||||
http_code: int = 401
|
||||
m_code: str = "M_UNAUTHORIZED"
|
||||
|
||||
|
||||
@dataclass
|
||||
class MatrixForbidden(MatrixError):
|
||||
http_code: int = 403
|
||||
|
|
|
@ -34,8 +34,8 @@ from nio.crypto import async_generator_from_data
|
|||
from . import __app_name__, __display_name__, utils
|
||||
from .errors import (
|
||||
BadMimeType, InvalidUserId, InvalidUserInContext, MatrixBadGateway,
|
||||
MatrixError, MatrixNotFound, MatrixTooLarge, UneededThumbnail,
|
||||
UserFromOtherServerDisallowed,
|
||||
MatrixError, MatrixNotFound, MatrixTooLarge, MatrixUnauthorized,
|
||||
UneededThumbnail, UserFromOtherServerDisallowed,
|
||||
)
|
||||
from .html_markdown import HTML_PROCESSOR as HTML
|
||||
from .media_cache import Media, Thumbnail
|
||||
|
@ -1347,6 +1347,23 @@ class MatrixClient(nio.AsyncClient):
|
|||
self.blacklist_device(self.olm.device_store[user_id][device_id])
|
||||
|
||||
|
||||
async def delete_devices_with_password(
|
||||
self, device_ids: List[str], password: str,
|
||||
) -> None:
|
||||
"""Delete devices, authentifying using the account's password."""
|
||||
|
||||
auth = {
|
||||
"type": "m.login.password",
|
||||
"user": self.user_id,
|
||||
"password": password,
|
||||
}
|
||||
|
||||
resp = await super().delete_devices(device_ids, auth)
|
||||
|
||||
if isinstance(resp, nio.DeleteDevicesAuthResponse):
|
||||
raise MatrixUnauthorized()
|
||||
|
||||
|
||||
# Functions to register/modify data into models
|
||||
|
||||
async def update_account_unread_counts(self) -> None:
|
||||
|
|
|
@ -53,16 +53,32 @@ HColumnPage {
|
|||
}
|
||||
|
||||
function deleteDevices(...indice) {
|
||||
const deviceIds = []
|
||||
if (indice.length === 1 && indice[0] === 0) {
|
||||
utils.makePopup("Popups/SignOutPopup.qml", { userId: page.userId })
|
||||
return
|
||||
}
|
||||
|
||||
for (const i of indice.sort())
|
||||
const deviceIds = []
|
||||
let deleteOwnDevice = false
|
||||
|
||||
for (const i of indice.sort()) {
|
||||
i === 0 ?
|
||||
deleteOwnDevice = true :
|
||||
deviceIds.push(deviceList.model.get(i).id)
|
||||
}
|
||||
|
||||
utils.makePopup(
|
||||
"Popups/AuthentificationPopup.qml",
|
||||
"Popups/DeleteDevicesPopup.qml",
|
||||
{
|
||||
userId: page.userId,
|
||||
deviceIds,
|
||||
deletedCallback: () => {
|
||||
deleteOwnDevice ?
|
||||
utils.makePopup(
|
||||
"Popups/SignOutPopup.qml", { userId: page.userId },
|
||||
) :
|
||||
page.loadDevices()
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import "../Base"
|
||||
import "../Base/ButtonLayout"
|
||||
|
||||
HFlickableColumnPopup {
|
||||
id: popup
|
||||
|
||||
|
||||
property string userId
|
||||
property string deviceIds
|
||||
|
||||
|
||||
page.footer: ButtonLayout {
|
||||
CancelButton {
|
||||
id: cancelButton
|
||||
onClicked: popup.close()
|
||||
}
|
||||
}
|
||||
|
||||
onOpened: cancelButton.forceActiveFocus()
|
||||
|
||||
SummaryLabel { text: qsTr("Not implemented yet") }
|
||||
}
|
40
src/gui/Popups/DeleteDevicesPopup.qml
Normal file
40
src/gui/Popups/DeleteDevicesPopup.qml
Normal file
|
@ -0,0 +1,40 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import "../Base"
|
||||
import "../Base/ButtonLayout"
|
||||
|
||||
PasswordPopup {
|
||||
id: popup
|
||||
|
||||
|
||||
property string userId
|
||||
property var deviceIds // array
|
||||
property var deletedCallback: null
|
||||
|
||||
|
||||
function verifyPassword(pass, callback) {
|
||||
py.callClientCoro(
|
||||
userId,
|
||||
"delete_devices_with_password",
|
||||
[deviceIds, pass],
|
||||
() => callback(true),
|
||||
(type, args) => {
|
||||
callback(
|
||||
type === "MatrixUnauthorized" ?
|
||||
false :
|
||||
qsTr("Unknown error: %1 - %2").arg(type).arg(args)
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
summary.text:
|
||||
qsTr("Enter your account's password to continue:")
|
||||
|
||||
|
||||
validateButton.text: qsTr("Sign out")
|
||||
validateButton.icon.name: "sign-out"
|
||||
|
||||
onClosed: if (acceptedPassword && deletedCallback) deletedCallback()
|
||||
}
|
Loading…
Reference in New Issue
Block a user