Page MenuHomePhorge

D206.1737349172.diff
No OneTemporary

Size
12 KB
Referenced Files
None
Subscribers
None

D206.1737349172.diff

diff --git a/src/contents/ui/LoginPage.qml b/src/contents/ui/LoginPage.qml
--- a/src/contents/ui/LoginPage.qml
+++ b/src/contents/ui/LoginPage.qml
@@ -52,48 +52,60 @@
}
visible: sessions.length > 0
}
- Label {
- text: l10n.get('login-page-userid-prompt')
- }
- TextField {
- id: userIdField
- Layout.fillWidth: true
- placeholderText: l10n.get('login-page-userid-input-placeholder')
- }
- Label {
- text: l10n.get('login-page-password-prompt')
- }
- Kirigami.PasswordField {
- id: passwordField
- Layout.fillWidth: true
-// onAccepted: // check if passwordField.text is valid
- }
- RowLayout {
- Layout.fillWidth: true
- property var loginButton: Button {
- id: loginButton
- text: l10n.get('login-page-login-button')
+ Kirigami.FormLayout {
+ TextField {
+ id: userIdField
+ objectName: 'userIdField'
Layout.fillWidth: true
- onClicked: {
- console.log('Trying to login...')
- if (isSwitchingAccount) {
- matrixSdk.startNewSession();
- }
- matrixSdk.login(userIdField.text, passwordField.text)
- console.log('Login job sent')
- }
+ placeholderText: l10n.get('login-page-userid-input-placeholder')
+ Kirigami.FormData.label: l10n.get('login-page-userid-prompt')
}
- property var closeButton: Button {
- id: closeButton
- text: l10n.get('login-page-close-button')
+
+ Kirigami.PasswordField {
+ id: passwordField
+ objectName: 'passwordField'
Layout.fillWidth: true
- onClicked: {
- pageStack.removePage(loginPage);
- }
+ Kirigami.FormData.label: l10n.get('login-page-password-prompt')
+ }
+
+ TextField {
+ id: serverUrlField
+ objectName: 'serverUrlField'
+ Layout.fillWidth: true
+ placeholderText: l10n.get('login-page-server-url-placeholder')
+ Kirigami.FormData.label: l10n.get('login-page-server-url-prompt')
}
- data: isSwitchingAccount ? [closeButton, loginButton] : [loginButton]
+ RowLayout {
+ Layout.fillWidth: true
+
+ property var loginButton: Button {
+ id: loginButton
+ objectName: 'loginButton'
+ text: l10n.get('login-page-login-button')
+ Layout.fillWidth: true
+ onClicked: {
+ console.log('Trying to login...')
+ if (isSwitchingAccount) {
+ matrixSdk.startNewSession();
+ }
+ matrixSdk.login(userIdField.text, passwordField.text, serverUrlField.text);
+ console.log('Login job sent')
+ }
+ }
+
+ property var closeButton: Button {
+ id: closeButton
+ text: l10n.get('login-page-close-button')
+ Layout.fillWidth: true
+ onClicked: {
+ pageStack.removePage(loginPage);
+ }
+ }
+
+ data: isSwitchingAccount ? [closeButton, loginButton] : [loginButton]
+ }
}
}
}
diff --git a/src/contents/ui/Main.qml b/src/contents/ui/Main.qml
--- a/src/contents/ui/Main.qml
+++ b/src/contents/ui/Main.qml
@@ -33,7 +33,7 @@
}
onDiscoverFailed: {
console.log("Discover Failed");
- showPassiveNotification(l10n.get('login-page-discover-failed-prompt', { errorCode, errorMsg }));
+ showPassiveNotification(l10n.get('login-page-discover-failed-enter-prompt', { errorCode, errorMsg }));
}
onSessionChanged: {
console.log('session changed');
diff --git a/src/l10n/cmn-Hans/100-ui.ftl b/src/l10n/cmn-Hans/100-ui.ftl
--- a/src/l10n/cmn-Hans/100-ui.ftl
+++ b/src/l10n/cmn-Hans/100-ui.ftl
@@ -52,7 +52,9 @@
login-page-alternative-password-login-prompt = 或者用用户 id 和密码启动新会话:
login-page-restore-session-button = 恢复会话
login-page-request-failed-prompt = 登录失败。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
-login-page-discover-failed-prompt = 不能检测此用户所在的服务器,或者服务器不可用。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
+login-page-discover-failed-enter-prompt = 不能检测此用户所在的服务器,或者服务器不可用。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。请手动输入服务器链接。
+login-page-server-url-placeholder = 例如: https://example.org
+login-page-server-url-prompt = 服务器链接(可选):
session-load-failure-not-found = 找不到会话 { $sessionName }。
session-load-failure-format-unknown = 会话 { $sessionName } 包含不支持的格式。是由未来版本的 { -kt-app-name } 保存的吗?
diff --git a/src/l10n/en/100-ui.ftl b/src/l10n/en/100-ui.ftl
--- a/src/l10n/en/100-ui.ftl
+++ b/src/l10n/en/100-ui.ftl
@@ -52,7 +52,9 @@
login-page-alternative-password-login-prompt = Or start a new session with user id and password:
login-page-restore-session-button = Restore session
login-page-request-failed-prompt = Login failed. Error code: { $errorCode }. Error message: { $errorMsg }.
-login-page-discover-failed-prompt = Unable to detect the server this user is on, or the server is unavailable. Error code: { $errorCode }. Error message: { $errorMsg }.
+login-page-discover-failed-enter-prompt = Unable to detect the server this user is on, or the server is unavailable. Error code: { $errorCode }. Error message: { $errorMsg }. Please enter the server url manually.
+login-page-server-url-placeholder = E.g.: https://example.org
+login-page-server-url-prompt = Server url (optional):
session-load-failure-not-found = The session { $sessionName } is not found.
session-load-failure-format-unknown = The session { $sessionName } contains an unsupported format. Is it saved using a future version of { -kt-app-name }?
diff --git a/src/matrix-sdk.hpp b/src/matrix-sdk.hpp
--- a/src/matrix-sdk.hpp
+++ b/src/matrix-sdk.hpp
@@ -103,6 +103,8 @@
// Replaces the store with another one
void emplace(std::optional<Kazv::SdkModel> model, std::unique_ptr<KazvSessionLockGuard> lockGuard);
+ static std::string validateHomeserverUrl(const QString &url);
+
Q_SIGNALS:
void trigger(Kazv::KazvEvent e);
@@ -117,7 +119,7 @@
void sessionChanged();
public Q_SLOTS:
- void login(const QString &userId, const QString &password);
+ void login(const QString &userId, const QString &password, const QString &homeserverUrl);
void logout();
/**
diff --git a/src/matrix-sdk.cpp b/src/matrix-sdk.cpp
--- a/src/matrix-sdk.cpp
+++ b/src/matrix-sdk.cpp
@@ -50,6 +50,8 @@
using namespace Qt::Literals::StringLiterals;
using namespace Kazv;
+static const std::string clientName = "kazv";
+
// Sdk with qt event loop, identity transform and no enhancers
using SdkT =
decltype(makeSdk(
@@ -374,33 +376,66 @@
return new MatrixDeviceList(m_d->clientOnSecondaryRoot.devicesOfUser(userId.toStdString()));
}
-void MatrixSdk::login(const QString &userId, const QString &password)
+std::string MatrixSdk::validateHomeserverUrl(const QString &url)
{
- m_d->clientOnSecondaryRoot
- .autoDiscover(userId.toStdString())
- .then([
- this,
- client=m_d->clientOnSecondaryRoot.toEventLoop(),
- userId,
- password
- ](auto res) {
- if (!res.success()) {
- // FIXME use real error codes and msgs when available in libkazv
- Q_EMIT this->discoverFailed(u""_s, u""_s);
- return res;
- }
+ if (url.isEmpty()) {
+ return std::string();
+ }
- auto serverUrl = res.dataStr("homeserverUrl");
+ auto u = QUrl::fromUserInput(url);
+ if (!u.isValid()) {
+ return std::string();
+ }
- client.passwordLogin(
- serverUrl,
- userId.toStdString(),
- password.toStdString(),
- "kazv"
- );
+ if (u.scheme() == u"http"_s) {
+ qCInfo(kazvLog) << "url" << u << "is http. Force switching to https.";
+ u.setScheme(u"https"_s);
+ } else if (u.scheme() != u"https"_s) {
+ qCWarning(kazvLog) << "url" << u << "is not http/https.";
+ return std::string();
+ }
+
+ return u.toString().toStdString();
+}
+
+void MatrixSdk::login(const QString &userId, const QString &password, const QString &homeserverUrl)
+{
+ auto loginFunc = [userId, password](const Client &client, const std::string &serverUrl) {
+ client.passwordLogin(
+ serverUrl,
+ userId.toStdString(),
+ password.toStdString(),
+ clientName
+ );
+ };
+
+ auto validated = validateHomeserverUrl(homeserverUrl);
+ if (!validated.empty()) {
+ loginFunc(m_d->clientOnSecondaryRoot, validated);
+ } else {
+ m_d->clientOnSecondaryRoot
+ .autoDiscover(userId.toStdString())
+ .then([
+ this,
+ client=m_d->clientOnSecondaryRoot.toEventLoop(),
+ userId,
+ password,
+ loginFunc
+ ](auto res) {
+ if (!res.success()) {
+ // FIXME use real error codes and msgs when available in libkazv
+ Q_EMIT this->discoverFailed(u""_s, u""_s);
+ return res;
+ }
+
+ auto serverUrl = res.dataStr("homeserverUrl");
+
+ loginFunc(client, serverUrl);
+
+ return res;
+ });
+ }
- return res;
- });
m_d->runIoContext();
}
void MatrixSdk::logout()
diff --git a/src/tests/matrix-sdk-test.cpp b/src/tests/matrix-sdk-test.cpp
--- a/src/tests/matrix-sdk-test.cpp
+++ b/src/tests/matrix-sdk-test.cpp
@@ -29,6 +29,7 @@
private Q_SLOTS:
void testDevicesOfUser();
void testSetDeviceTrustLevel();
+ void testValidateHomeserverUrl();
};
void MatrixSdkTest::testDevicesOfUser()
@@ -68,6 +69,19 @@
QTRY_VERIFY(dev->trustLevel() == u"verified"_s); // wait for the change to propagate to this thread
}
+void MatrixSdkTest::testValidateHomeserverUrl()
+{
+ auto v = [](const QString &u) {
+ return QString::fromStdString(MatrixSdk::validateHomeserverUrl(u));
+ };
+
+ QCOMPARE(v(u"example.com"_s), u"https://example.com"_s);
+ QCOMPARE(v(u"to"_s), u"https://to"_s);
+ QVERIFY(v(u""_s).isEmpty());
+ QVERIFY(v(u"/usr/libexec"_s).isEmpty());
+ QCOMPARE(v(u"ea.pl"_s), u"https://ea.pl"_s);
+}
+
QTEST_MAIN(MatrixSdkTest)
#include "matrix-sdk-test.moc"
diff --git a/src/tests/quick-tests/test-helpers/MatrixSdkMock.qml b/src/tests/quick-tests/test-helpers/MatrixSdkMock.qml
--- a/src/tests/quick-tests/test-helpers/MatrixSdkMock.qml
+++ b/src/tests/quick-tests/test-helpers/MatrixSdkMock.qml
@@ -25,6 +25,13 @@
])
property var joinRoom: mockHelper.promise()
property var sendAccountData: mockHelper.promise()
+ property var login: mockHelper.noop()
+
+ property var sessions: []
+
+ function allSessions() {
+ return sessions;
+ }
function mxcUriToHttp (uri) {
console.log('mxcUriToHttp');
diff --git a/src/tests/quick-tests/tst_LoginPage.qml b/src/tests/quick-tests/tst_LoginPage.qml
new file mode 100644
--- /dev/null
+++ b/src/tests/quick-tests/tst_LoginPage.qml
@@ -0,0 +1,44 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2024 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import QtQuick
+import QtTest
+import '../../contents/ui' as Kazv
+import 'test-helpers' as QmlHelpers
+
+QmlHelpers.TestItem {
+ id: item
+
+ Kazv.LoginPage {
+ id: loginPage
+ }
+
+ TestCase {
+ id: loginPageTest
+ name: 'LoginPageTest'
+ when: windowShown
+
+ function init() {
+ item.mockHelper.clearAll();
+ findChild(loginPage, 'userIdField').text = '@foo:example.org';
+ findChild(loginPage, 'passwordField').text = 'somepassword';
+ }
+
+ function test_discover() {
+ findChild(loginPage, 'serverUrlField').text = '';
+ mouseClick(findChild(loginPage, 'loginButton'));
+ compare(item.matrixSdk.login.calledTimes(), 1);
+ compare(item.matrixSdk.login.lastArgs()[2], '');
+ }
+
+ function test_noDiscover() {
+ findChild(loginPage, 'serverUrlField').text = 'https://mxs.example.org';
+ mouseClick(findChild(loginPage, 'loginButton'));
+ compare(item.matrixSdk.login.calledTimes(), 1);
+ compare(item.matrixSdk.login.lastArgs()[2], 'https://mxs.example.org');
+ }
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 19, 8:59 PM (16 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55595
Default Alt Text
D206.1737349172.diff (12 KB)

Event Timeline