summaryrefslogtreecommitdiffstats
path: root/src/LoginPage.h
blob: 90515263d09fbcff349654f9c1e8ce9a351cce8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QObject>
#include <QQmlEngine>
#include <QVariantList>

#include <mtx/responses/login.hpp>

struct SSOProvider
{
    Q_GADGET
    Q_PROPERTY(QString avatarUrl READ avatarUrl CONSTANT)
    Q_PROPERTY(QString name READ name CONSTANT)
    Q_PROPERTY(QString id READ id CONSTANT)

public:
    [[nodiscard]] QString avatarUrl() const { return avatarUrl_; }
    [[nodiscard]] QString name() const { return name_.toHtmlEscaped(); }
    [[nodiscard]] QString id() const { return id_; }

    QString avatarUrl_;
    QString name_;
    QString id_;
};

class LoginPage : public QObject
{
    Q_OBJECT
    QML_NAMED_ELEMENT(Login)

    Q_PROPERTY(QString mxid READ mxid WRITE setMxid NOTIFY matrixIdChanged)
    Q_PROPERTY(QString homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)

    Q_PROPERTY(QString mxidError READ mxidError NOTIFY mxidErrorChanged)
    Q_PROPERTY(QString error READ error NOTIFY errorOccurred)
    Q_PROPERTY(bool lookingUpHs READ lookingUpHs NOTIFY lookingUpHsChanged)
    Q_PROPERTY(bool homeserverValid READ homeserverValid NOTIFY lookingUpHsChanged)
    Q_PROPERTY(bool loggingIn READ loggingIn NOTIFY loggingInChanged)
    Q_PROPERTY(bool passwordSupported READ passwordSupported NOTIFY versionLookedUp)
    Q_PROPERTY(bool ssoSupported READ ssoSupported NOTIFY versionLookedUp)
    Q_PROPERTY(bool homeserverNeeded READ homeserverNeeded NOTIFY versionLookedUp)

    Q_PROPERTY(QVariantList identityProviders READ identityProviders NOTIFY versionLookedUp)

public:
    enum class LoginMethod
    {
        Password,
        SSO,
    };
    Q_ENUM(LoginMethod)

    LoginPage(QObject *parent = nullptr);

    Q_INVOKABLE QString initialDeviceName() const
    {
        return QString::fromStdString(initialDeviceName_());
    }

    bool lookingUpHs() const { return lookingUpHs_; }
    bool loggingIn() const { return loggingIn_; }
    bool passwordSupported() const { return passwordSupported_; }
    bool ssoSupported() const { return ssoSupported_; }
    bool homeserverNeeded() const { return homeserverNeeded_; }
    bool homeserverValid() const { return homeserverValid_; }
    QVariantList identityProviders() const { return identityProviders_; }

    QString homeserver() { return homeserver_; }
    QString mxid() { return mxid_; }

    QString error() { return error_; }
    QString mxidError() { return mxidError_; }

    void setHomeserver(const QString &hs);
    void setMxid(QString id)
    {
        if (id != mxid_) {
            mxid_ = id;
            emit matrixIdChanged();
            onMatrixIdEntered();
        }
    }

    static std::string initialDeviceName_()
    {
#if defined(Q_OS_MAC)
        return "Nheko on macOS";
#elif defined(Q_OS_LINUX)
        return "Nheko on Linux";
#elif defined(Q_OS_WIN)
        return "Nheko on Windows";
#elif defined(Q_OS_FREEBSD)
        return "Nheko on FreeBSD";
#elif defined(Q_OS_OPENBSD)
        return "Nheko on OpenBSD";
#else
        return "Nheko";
#endif
    }

signals:
    void loggingInChanged();
    void errorOccurred();

    //! Used to trigger the corresponding slot outside of the main thread.
    void versionErrorCb(const QString &err);
    void versionOkCb(bool passwordSupported, bool ssoSupported, QVariantList identityProviders);

    void loginOk(const mtx::responses::Login &res);

    void onServerAddressEntered();

    void matrixIdChanged();
    void homeserverChanged();

    void mxidErrorChanged();
    void lookingUpHsChanged();
    void versionLookedUp();
    void versionLookupFinished();

public slots:
    // Displays errors produced during the login.
    void showError(const QString &msg);

    // Callback for the login button.
    void onLoginButtonClicked(LoginMethod loginMethod,
                              const QString &userid,
                              const QString &password,
                              const QString &deviceName);

    // Callback for errors produced during server probing
    void versionError(const QString &error_message);
    // Callback for successful server probing
    void versionOk(bool passwordSupported, bool ssoSupported, QVariantList identityProviders);

private:
    void checkHomeserverVersion();
    void onMatrixIdEntered();
    void clearErrors()
    {
        error_.clear();
        mxidError_.clear();
        emit errorOccurred();
        emit mxidErrorChanged();
    }

    QString inferredServerAddress_;

    QString mxid_;
    QString homeserver_;

    QString mxidError_;
    QString error_;

    QVariantList identityProviders_;

    bool passwordSupported_ = true;
    bool ssoSupported_      = false;

    bool lookingUpHs_      = false;
    bool loggingIn_        = false;
    bool homeserverNeeded_ = false;
    bool homeserverValid_  = false;
};