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
|
- **Multiple accounts** in one client
|
||||||
- Set your display name and profile picture
|
- Set your display name and profile picture
|
||||||
- Import/export **E2E** key files
|
- Import/export **E2E** key files
|
||||||
- Inspect, rename and manually verify your sessions
|
- Inspect, rename, manually verify and sign out one or multiple sessions
|
||||||
|
|
||||||
### Rooms
|
### Rooms
|
||||||
|
|
||||||
|
|
1
TODO.md
1
TODO.md
|
@ -185,7 +185,6 @@
|
||||||
- E2E
|
- E2E
|
||||||
- List and verify other users's devices
|
- List and verify other users's devices
|
||||||
- SAS verification
|
- SAS verification
|
||||||
- Delete devices (do that in key verification popup instead of blacklisting)
|
|
||||||
- Request room keys from own other devices
|
- Request room keys from own other devices
|
||||||
- Auto-trust accounts within the same client
|
- Auto-trust accounts within the same client
|
||||||
- Provide help when undecryptable messages occur, including:
|
- Provide help when undecryptable messages occur, including:
|
||||||
|
|
|
@ -33,6 +33,12 @@ class MatrixError(Exception):
|
||||||
return cls(response.transport_response.status, response.status_code)
|
return cls(response.transport_response.status, response.status_code)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MatrixUnauthorized(MatrixError):
|
||||||
|
http_code: int = 401
|
||||||
|
m_code: str = "M_UNAUTHORIZED"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MatrixForbidden(MatrixError):
|
class MatrixForbidden(MatrixError):
|
||||||
http_code: int = 403
|
http_code: int = 403
|
||||||
|
|
|
@ -34,8 +34,8 @@ from nio.crypto import async_generator_from_data
|
||||||
from . import __app_name__, __display_name__, utils
|
from . import __app_name__, __display_name__, utils
|
||||||
from .errors import (
|
from .errors import (
|
||||||
BadMimeType, InvalidUserId, InvalidUserInContext, MatrixBadGateway,
|
BadMimeType, InvalidUserId, InvalidUserInContext, MatrixBadGateway,
|
||||||
MatrixError, MatrixNotFound, MatrixTooLarge, UneededThumbnail,
|
MatrixError, MatrixNotFound, MatrixTooLarge, MatrixUnauthorized,
|
||||||
UserFromOtherServerDisallowed,
|
UneededThumbnail, UserFromOtherServerDisallowed,
|
||||||
)
|
)
|
||||||
from .html_markdown import HTML_PROCESSOR as HTML
|
from .html_markdown import HTML_PROCESSOR as HTML
|
||||||
from .media_cache import Media, Thumbnail
|
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])
|
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
|
# Functions to register/modify data into models
|
||||||
|
|
||||||
async def update_account_unread_counts(self) -> None:
|
async def update_account_unread_counts(self) -> None:
|
||||||
|
|
|
@ -53,16 +53,32 @@ HColumnPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteDevices(...indice) {
|
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)
|
deviceIds.push(deviceList.model.get(i).id)
|
||||||
|
}
|
||||||
|
|
||||||
utils.makePopup(
|
utils.makePopup(
|
||||||
"Popups/AuthentificationPopup.qml",
|
"Popups/DeleteDevicesPopup.qml",
|
||||||
{
|
{
|
||||||
userId: page.userId,
|
userId: page.userId,
|
||||||
deviceIds,
|
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