aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml159
-rw-r--r--CMakeLists.txt2
-rw-r--r--CONTRIBUTING.md9
-rw-r--r--README.md16
-rw-r--r--lib/accountregistry.h25
-rw-r--r--lib/avatar.cpp8
-rw-r--r--lib/connection.cpp78
-rw-r--r--lib/connection.h5
-rw-r--r--lib/room.cpp4
-rw-r--r--libquotient.pri3
10 files changed, 145 insertions, 164 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 172c027f..f03af94b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,47 +14,65 @@ concurrency: ci-${{ github.ref }}
jobs:
CI:
runs-on: ${{ matrix.os }}
- continue-on-error: false
+ continue-on-error: ${{ matrix.qt-version != '5.15.2' }} # Qt 6 will fail for now
strategy:
fail-fast: false
max-parallel: 1
matrix:
os: [ ubuntu-20.04, macos-10.15 ]
- compiler: [ Clang ] # GCC builds are added individually below
- qt-version: [ '5.12.12' ]
+ qt-version: [ '6.3.1', '5.15.2' ]
+ compiler: [ LLVM ]
# Not using binary values here, to make the job captions more readable
e2ee: [ '', e2ee ]
update-api: [ '', update-api ]
- sonar: [ '' ]
+ static-analysis: [ '' ]
platform: [ '' ]
qt-arch: [ '' ]
exclude:
- - os: windows-2019
- e2ee: e2ee # Not supported by the current CI script
+ - qt-version: '6.3.1'
+ update-api: update-api # Generated code is not specific to Qt version
+ - os: ubuntu-20.04
+ e2ee: e2ee # Will be re-added with static analysis below
+ # TODO: Enable E2EE on Windows and macOS
- os: macos-10.15
- e2ee: e2ee # Missing OpenSSL
+ e2ee: e2ee
include:
+ - os: windows-2019
+ qt-version: '5.15.2'
+ compiler: MSVC
+ platform: x64
+ qt-arch: win64_msvc2019_64
+ - os: ubuntu-20.04
+ qt-version: '5.15.2'
+ compiler: LLVM
+ e2ee: e2ee
+ static-analysis: codeql
- os: ubuntu-latest
+ qt-version: '5.15.2'
compiler: GCC
- qt-version: '5.12.12'
e2ee: e2ee
- sonar: sonar
+ static-analysis: sonar
- os: ubuntu-20.04
+ qt-version: '5.15.2'
compiler: GCC
- qt-version: '5.12.12'
e2ee: e2ee
update-api: update-api
+ - os: ubuntu-20.04
+ qt-version: '5.15.2'
+ compiler: LLVM
+ update-api: update-api
- os: windows-2019
+ qt-version: '6.3.1'
compiler: MSVC
+ # e2ee: e2ee # TODO
platform: x64
- qt-version: '5.12.12'
- qt-arch: win64_msvc2017_64
+ qt-arch: win64_msvc2019_64
- os: windows-2019
+ qt-version: '5.15.2'
compiler: MSVC
- platform: x64
- qt-version: '5.12.12'
- qt-arch: win64_msvc2017_64
update-api: update-api
+ platform: x64
+ qt-arch: win64_msvc2019_64
env:
SONAR_SERVER_URL: 'https://sonarcloud.io'
@@ -64,44 +82,14 @@ jobs:
with:
fetch-depth: 0
- - name: Cache Qt
- id: cache-qt
- uses: actions/cache@v2
- with:
- path: ${{ runner.workspace }}/Qt
- key: ${{ runner.os }}${{ matrix.platform }}-Qt${{ matrix.qt-version }}-cache
-
- - name: Install Qt
- uses: jurplel/install-qt-action@v2.11.1
- with:
- version: ${{ matrix.qt-version }}
- arch: ${{ matrix.qt-arch }}
- cached: ${{ steps.cache-qt.outputs.cache-hit }}
-
- - name: Install Ninja (macOS/Windows)
- if: ${{ !startsWith(matrix.os, 'ubuntu') }}
- uses: seanmiddleditch/gha-setup-ninja@v3
-
- - name: Install Ninja and Valgrind (Linux)
- if: startsWith(matrix.os, 'ubuntu')
- run: |
- sudo apt-get -qq install ninja-build valgrind
- echo "VALGRIND=valgrind --tool=memcheck --leak-check=yes --gen-suppressions=all --suppressions=$GITHUB_WORKSPACE/quotest/.valgrind.supp" >>$GITHUB_ENV
-
- name: Setup build environment
run: |
- if [ "${{ matrix.compiler }}" == "GCC" ]; then
- CXX_VERSION_POSTFIX='-10'
- echo "CC=gcc$CXX_VERSION_POSTFIX" >>$GITHUB_ENV
- echo "CXX=g++$CXX_VERSION_POSTFIX" >>$GITHUB_ENV
- elif [[ '${{ matrix.compiler }}' == 'Clang' ]]; then
- if [[ '${{ runner.os }}' == 'Linux' ]]; then
- CXX_VERSION_POSTFIX='-11'
- # Do CodeQL analysis on one of Linux branches
- echo "CODEQL_ANALYSIS=true" >>$GITHUB_ENV
- fi
- echo "CC=clang$CXX_VERSION_POSTFIX" >>$GITHUB_ENV
- echo "CXX=clang++$CXX_VERSION_POSTFIX" >>$GITHUB_ENV
+ if [ '${{ matrix.compiler }}' == 'GCC' ]; then
+ echo "CC=gcc-10" >>$GITHUB_ENV
+ echo "CXX=g++-10" >>$GITHUB_ENV
+ elif [[ '${{ runner.os }}' != 'Windows' ]]; then
+ echo "CC=clang" >>$GITHUB_ENV
+ echo "CXX=clang++" >>$GITHUB_ENV
fi
if grep -q 'refs/tags' <<<'${{ github.ref }}'; then
VERSION="$(git describe --tags)"
@@ -110,20 +98,19 @@ jobs:
else
VERSION="$(git describe --all --contains)-ci${{ github.run_number }}-$(git rev-parse --short HEAD)"
fi
- echo "QUOTEST_ORIGIN=$VERSION @ ${{ runner.os }}/${{ matrix.compiler }}" >>$GITHUB_ENV
- # Build libQuotient as a shared library across platforms but also
- # check the static configuration somewhere
+ echo "QUOTEST_ORIGIN=$VERSION @ ${{ runner.os }}/Qt-${{ matrix.qt-version }}/${{ matrix.compiler }}" >>$GITHUB_ENV
+
CMAKE_ARGS="-G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DBUILD_SHARED_LIBS=${{ runner.os == 'Linux' }} \
-DCMAKE_INSTALL_PREFIX=~/.local \
-DCMAKE_PREFIX_PATH=~/.local \
- -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON"
+ -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
+ -DBUILD_WITH_QT6=${{ startsWith(matrix.qt-version, '6') }}"
- if [ -n "${{ matrix.sonar }}" ]; then
+ if [ '${{ matrix.static-analysis }}' == 'sonar' ]; then
mkdir -p $HOME/.sonar
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CXX_FLAGS=--coverage"
- echo "COV=gcov$CXX_VERSION_POSTFIX" >>$GITHUB_ENV
fi
echo "CMAKE_ARGS=$CMAKE_ARGS" >>$GITHUB_ENV
@@ -137,14 +124,42 @@ jobs:
cmake -E make_directory ${{ runner.workspace }}/build
echo "BUILD_PATH=${{ runner.workspace }}/build/libQuotient" >>$GITHUB_ENV
- - name: Setup MSVC environment
+ - name: Cache Qt
+ id: cache-qt
+ uses: actions/cache@v2
+ with:
+ path: ${{ runner.workspace }}/Qt
+ key: ${{ runner.os }}${{ matrix.platform }}-Qt${{ matrix.qt-version }}-cache
+
+ - name: Install Qt
+ uses: jurplel/install-qt-action@v2.14.0
+ with:
+ version: ${{ matrix.qt-version }}
+ arch: ${{ matrix.qt-arch }}
+ cached: ${{ steps.cache-qt.outputs.cache-hit }}
+
+ - name: Install Ninja (macOS/Windows)
+ if: ${{ !startsWith(matrix.os, 'ubuntu') }}
+ uses: seanmiddleditch/gha-setup-ninja@v3
+
+ - name: Install dependencies (Linux)
+ if: startsWith(matrix.os, 'ubuntu')
+ run: |
+ if [ -n "${{ matrix.e2ee }}" ]; then
+ EXTRA_DEPS="libssl-dev libolm-dev"
+ echo "QUOTEST_ORIGIN=$QUOTEST_ORIGIN with E2EE" >>$GITHUB_ENV
+ fi
+ sudo apt-get -qq install ninja-build valgrind $EXTRA_DEPS
+ echo "VALGRIND=valgrind --tool=memcheck --leak-check=yes --gen-suppressions=all --suppressions=$GITHUB_WORKSPACE/quotest/.valgrind.supp" >>$GITHUB_ENV
+
+ - name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
if: matrix.compiler == 'MSVC'
with:
arch: ${{ matrix.platform }}
- name: Download and set up Sonar Cloud tools
- if: matrix.sonar != ''
+ if: matrix.static-analysis == 'sonar'
env:
SONAR_SCANNER_VERSION: 4.6.2.2472
run: |
@@ -157,20 +172,6 @@ jobs:
unzip -o sonar-scanner-cli*.zip
popd
- - name: Install OpenSSL
- if: ${{ contains(matrix.os, 'ubuntu') && matrix.e2ee }}
- run: |
- sudo apt-get install libssl-dev
-
- - name: Build and install olm
- if: matrix.e2ee
- working-directory: ${{ runner.workspace }}
- run: |
- git clone https://gitlab.matrix.org/matrix-org/olm.git
- cmake -S olm -B build/olm $CMAKE_ARGS
- cmake --build build/olm --target install
- echo "QUOTEST_ORIGIN=$QUOTEST_ORIGIN with E2EE" >>$GITHUB_ENV
-
- name: Build and install QtKeychain
run: |
cd ..
@@ -191,8 +192,8 @@ jobs:
echo "QUOTEST_ORIGIN=$QUOTEST_ORIGIN with API files regeneration" >>$GITHUB_ENV
- name: Initialize CodeQL tools
- if: env.CODEQL_ANALYSIS
- uses: github/codeql-action/init@v1
+ if: matrix.static-analysis == 'codeql'
+ uses: github/codeql-action/init@v2
with:
languages: cpp
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -234,18 +235,18 @@ jobs:
timeout-minutes: 4 # quotest is supposed to finish within 3 minutes, actually
- name: Perform CodeQL analysis
- if: env.CODEQL_ANALYSIS
- uses: github/codeql-action/analyze@v1
+ if: matrix.static-analysis == 'codeql'
+ uses: github/codeql-action/analyze@v2
- name: Run sonar-scanner
- if: matrix.sonar != ''
+ if: matrix.static-analysis == 'sonar'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
mkdir .coverage && pushd .coverage
find $BUILD_PATH -name '*.gcda' -print0 \
- | xargs -0 $COV -s $GITHUB_WORKSPACE -pr
+ | xargs -0 gcov -s $GITHUB_WORKSPACE -pr
# Coverage of the test source code is not tracked, as it is always 100%
# (if not, some tests failed and broke the build at an earlier stage)
rm -f quotest* autotests*
diff --git a/CMakeLists.txt b/CMakeLists.txt
index efdd5bb6..048d3b07 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,7 +77,7 @@ option(BUILD_WITH_QT6 "Build Quotient with Qt 6 (EXPERIMENTAL)" OFF)
if (BUILD_WITH_QT6)
set(QtMinVersion "6.0")
else()
- set(QtMinVersion "5.12")
+ set(QtMinVersion "5.15")
set(QtExtraModules "Multimedia") # See #483
endif()
string(REGEX REPLACE "^(.).*" "Qt\\1" Qt ${QtMinVersion}) # makes "Qt5" or "Qt6"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bc65abf3..7a5ee079 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -154,14 +154,7 @@ just don't bankrupt us with it. Refactoring is welcome.
### Code style and formatting
-As of Quotient 0.7, the C++ standard for newly written code is C++20 with a few
-restrictions, notably:
-* enumerators and slots cannot have `[[attributes]]` because moc from Qt 5.12
- chokes on them - this will be lifted when we move on to Qt 5.13 for the oldest
- supported version, in the meantime use `Q_DECL_DEPRECATED` and similar Qt
- macros - they expand to nothing when the code is passed to moc.
-* explicit lists in lambda captures are preferred over `[=]`; note that C++20
- deprecates implicit `this` capture in `[=]`.
+As of Quotient 0.7, the C++ standard for newly written code is C++20.
The code style is defined by `.clang-format`, and in general, all C++ files
should follow it. Files with minor deviations from the defined style are still
diff --git a/README.md b/README.md
index e42cb488..2deaa28b 100644
--- a/README.md
+++ b/README.md
@@ -26,19 +26,17 @@ If you find what looks like a security issue, please use instructions
in SECURITY.md.
## Getting and using libQuotient
-Depending on your platform, the library can come as a separate package.
-Recent releases of Debian and openSUSE, e.g., already have the package
-(under the old name). If your Linux repo doesn't provide binary package
-(either libqmatrixclient - older - or libquotient - newer), or you're
-on Windows or macOS, your best bet is to build the library from the source
-and bundle it with your application.
+Depending on your platform, the library can be obtained from a package
+management system. Recent releases of Debian and openSUSE, e.g., already have
+it. Alternatively, just build the library from the source and bundle it with
+your application, as described below.
### Pre-requisites
- A recent Linux, macOS or Windows system (desktop versions are known to work;
mobile operating systems where Qt is available might work too)
- - Recent enough Linux examples: Debian Bullseye; Fedora 33; openSUSE Leap 15.3;
- Ubuntu Focal Fossa.
-- Qt 5 (either Open Source or Commercial), 5.12 or higher
+ - Recent enough Linux examples: Debian Bullseye; Fedora 35;
+ openSUSE Leap 15.4; Ubuntu 22.04 LTS.
+- Qt 5 (either Open Source or Commercial), 5.15 or higher
- CMake 3.16 or newer (from your package management system or
[the official website](https://cmake.org/download/))
- A C++ toolchain with that supports at least some subset of C++20:
diff --git a/lib/accountregistry.h b/lib/accountregistry.h
index 38cfe6c6..9560688e 100644
--- a/lib/accountregistry.h
+++ b/lib/accountregistry.h
@@ -31,8 +31,9 @@ class QUOTIENT_API AccountRegistry : public QAbstractListModel,
/// Can be used to inform the user or to show a login screen if size() == 0 and no accounts are loaded
Q_PROPERTY(QStringList accountsLoading READ accountsLoading NOTIFY accountsLoadingChanged)
public:
- using const_iterator = QVector::const_iterator;
- using const_reference = QVector::const_reference;
+ using vector_t = QVector<Connection*>;
+ using const_iterator = vector_t::const_iterator;
+ using const_reference = vector_t::const_reference;
enum EventRoles {
AccountRole = Qt::UserRole + 1,
@@ -42,24 +43,24 @@ public:
[[deprecated("Use Accounts variable instead")]] //
static AccountRegistry& instance();
- // Expose most of QVector's const-API but only provide add() and drop()
+ // Expose most of vector_t's const-API but only provide add() and drop()
// for changing it. In theory other changing operations could be supported
// too; but then boilerplate begin/end*() calls has to be tucked into each
// and this class gives no guarantees on the order of entries, so why care.
- const QVector<Connection*>& accounts() const { return *this; }
+ const vector_t& accounts() const { return *this; }
void add(Connection* a);
void drop(Connection* a);
- const_iterator begin() const { return QVector::begin(); }
- const_iterator end() const { return QVector::end(); }
- const_reference front() const { return QVector::front(); }
- const_reference back() const { return QVector::back(); }
+ const_iterator begin() const { return vector_t::begin(); }
+ const_iterator end() const { return vector_t::end(); }
+ const_reference front() const { return vector_t::front(); }
+ const_reference back() const { return vector_t::back(); }
bool isLoggedIn(const QString& userId) const;
Connection* get(const QString& userId);
- using QVector::isEmpty, QVector::empty;
- using QVector::size, QVector::count, QVector::capacity;
- using QVector::cbegin, QVector::cend, QVector::contains;
+ using vector_t::isEmpty, vector_t::empty;
+ using vector_t::size, vector_t::count, vector_t::capacity;
+ using vector_t::cbegin, vector_t::cend, vector_t::contains;
// QAbstractItemModel interface implementation
@@ -88,4 +89,4 @@ private:
inline QUOTIENT_API AccountRegistry Accounts {};
inline AccountRegistry& AccountRegistry::instance() { return Accounts; }
-}
+} // namespace Quotient
diff --git a/lib/avatar.cpp b/lib/avatar.cpp
index 9304a3de..13de99bf 100644
--- a/lib/avatar.cpp
+++ b/lib/avatar.cpp
@@ -39,7 +39,7 @@ public:
// The below are related to image caching, hence mutable
mutable QImage _originalImage;
- mutable std::vector<QPair<QSize, QImage>> _scaledImages;
+ mutable std::vector<std::pair<QSize, QImage>> _scaledImages;
mutable QSize _requestedSize;
mutable enum { Unknown, Cache, Network, Banned } _imageSource = Unknown;
mutable QPointer<MediaThumbnailJob> _thumbnailRequest = nullptr;
@@ -124,9 +124,9 @@ QImage Avatar::Private::get(Connection* connection, QSize size,
});
}
- for (const auto& p : _scaledImages)
- if (p.first == size)
- return p.second;
+ for (const auto& [scaledSize, scaledImage] : _scaledImages)
+ if (scaledSize == size)
+ return scaledImage;
auto result = _originalImage.isNull()
? QImage()
: _originalImage.scaled(size, Qt::KeepAspectRatio,
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 101bef89..c390cc05 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -92,7 +92,7 @@ public:
// state is Invited. The spec mandates to keep Invited room state
// separately; specifically, we should keep objects for Invite and
// Leave state of the same room if the two happen to co-exist.
- QHash<QPair<QString, bool>, Room*> roomMap;
+ QHash<std::pair<QString, bool>, Room*> roomMap;
/// Mapping from serverparts to alias/room id mappings,
/// as of the last sync
QHash<QString, QString> roomAliasMap;
@@ -381,10 +381,9 @@ public:
const QString& device) const;
QString edKeyForUserDevice(const QString& userId,
const QString& device) const;
- std::unique_ptr<EncryptedEvent> makeEventForSessionKey(
- const QString& roomId, const QString& targetUserId,
- const QString& targetDeviceId, const QByteArray& sessionId,
- const QByteArray& sessionKey) const;
+ QJsonObject encryptSessionKeyEvent(QJsonObject payloadJson,
+ const QString& targetUserId,
+ const QString& targetDeviceId) const;
#endif
void saveAccessTokenToKeychain() const
@@ -1365,17 +1364,10 @@ ForgetRoomJob* Connection::forgetRoom(const QString& id)
}
SendToDeviceJob* Connection::sendToDevices(
- const QString& eventType, const UsersToDevicesToEvents& eventsMap)
+ const QString& eventType, const UsersToDevicesToContent& contents)
{
- QHash<QString, QHash<QString, QJsonObject>> json;
- json.reserve(int(eventsMap.size()));
- for (const auto& [userId, devicesToEvents] : eventsMap) {
- auto& jsonUser = json[userId];
- for (const auto& [deviceId, event] : devicesToEvents)
- jsonUser.insert(deviceId, event->contentJson());
- }
return callApi<SendToDeviceJob>(BackgroundRequest, eventType,
- generateTxnId(), json);
+ generateTxnId(), contents);
}
SendMessageJob* Connection::sendMessage(const QString& roomId,
@@ -1715,7 +1707,7 @@ Room* Connection::provideRoom(const QString& id, Omittable<JoinState> joinState)
Q_ASSERT_X(!id.isEmpty(), __FUNCTION__, "Empty room id");
// If joinState is empty, all joinState == comparisons below are false.
- const auto roomKey = qMakePair(id, joinState == JoinState::Invite);
+ const std::pair roomKey { id, joinState == JoinState::Invite };
auto* room = d->roomMap.value(roomKey, nullptr);
if (room) {
// Leave is a special case because in transition (5a) (see the .h file)
@@ -2354,30 +2346,15 @@ bool Connection::Private::createOlmSession(const QString& targetUserId,
return true;
}
-std::unique_ptr<EncryptedEvent> Connection::Private::makeEventForSessionKey(
- const QString& roomId, const QString& targetUserId,
- const QString& targetDeviceId, const QByteArray& sessionId,
- const QByteArray& sessionKey) const
+QJsonObject Connection::Private::encryptSessionKeyEvent(
+ QJsonObject payloadJson, const QString& targetUserId,
+ const QString& targetDeviceId) const
{
- // Noisy but nice for debugging
- // qDebug(E2EE) << "Creating the payload for" << data->userId() << device <<
- // sessionId << sessionKey.toHex();
- const auto event = makeEvent<RoomKeyEvent>("m.megolm.v1.aes-sha2", roomId,
- sessionId, sessionKey,
- data->userId());
- auto payloadJson = event->fullJson();
payloadJson.insert("recipient"_ls, targetUserId);
- payloadJson.insert(SenderKeyL, data->userId());
payloadJson.insert("recipient_keys"_ls,
QJsonObject { { Ed25519Key,
edKeyForUserDevice(targetUserId,
targetDeviceId) } });
- payloadJson.insert("keys"_ls,
- QJsonObject {
- { Ed25519Key,
- QString(olmAccount->identityKeys().ed25519) } });
- payloadJson.insert("sender_device"_ls, data->deviceId());
-
const auto [type, cipherText] = olmEncryptMessage(
targetUserId, targetDeviceId,
QJsonDocument(payloadJson).toJson(QJsonDocument::Compact));
@@ -2387,8 +2364,8 @@ std::unique_ptr<EncryptedEvent> Connection::Private::makeEventForSessionKey(
{ "body"_ls, QString(cipherText) } } }
};
- return makeEvent<EncryptedEvent>(encrypted,
- olmAccount->identityKeys().curve25519);
+ return EncryptedEvent(encrypted, olmAccount->identityKeys().curve25519)
+ .contentJson();
}
void Connection::sendSessionKeyToDevices(
@@ -2409,11 +2386,21 @@ void Connection::sendSessionKeyToDevices(
if (hash.isEmpty())
return;
+ auto keyEventJson = RoomKeyEvent(MegolmV1AesSha2AlgoKey, roomId, sessionId,
+ sessionKey, userId())
+ .fullJson();
+ keyEventJson.insert(SenderKeyL, userId());
+ keyEventJson.insert("sender_device"_ls, deviceId());
+ keyEventJson.insert(
+ "keys"_ls,
+ QJsonObject {
+ { Ed25519Key, QString(olmAccount()->identityKeys().ed25519) } });
+
auto job = callApi<ClaimKeysJob>(hash);
- connect(job, &BaseJob::success, this, [job, this, roomId, sessionId, sessionKey, devices, index] {
- UsersToDevicesToEvents usersToDevicesToEvents;
- const auto oneTimeKeys = job->oneTimeKeys();
- for (const auto& [targetUserId, targetDeviceId] :
+ connect(job, &BaseJob::success, this, [job, this, roomId, sessionId, keyEventJson, devices, index] {
+ QHash<QString, QHash<QString, QJsonObject>> usersToDevicesToContent;
+ for (const auto oneTimeKeys = job->oneTimeKeys();
+ const auto& [targetUserId, targetDeviceId] :
asKeyValueRange(devices)) {
if (!hasOlmSession(targetUserId, targetDeviceId)
&& !d->createOlmSession(
@@ -2421,12 +2408,15 @@ void Connection::sendSessionKeyToDevices(
oneTimeKeys[targetUserId][targetDeviceId]))
continue;
- usersToDevicesToEvents[targetUserId][targetDeviceId] =
- d->makeEventForSessionKey(roomId, targetUserId, targetDeviceId,
- sessionId, sessionKey);
+ // Noisy but nice for debugging
+// qDebug(E2EE) << "Creating the payload for" << targetUserId
+// << targetDeviceId << sessionId << sessionKey.toHex();
+ usersToDevicesToContent[targetUserId][targetDeviceId] =
+ d->encryptSessionKeyEvent(keyEventJson, targetUserId,
+ targetDeviceId);
}
- if (!usersToDevicesToEvents.empty()) {
- sendToDevices(EncryptedEvent::TypeId, usersToDevicesToEvents);
+ if (!usersToDevicesToContent.empty()) {
+ sendToDevices(EncryptedEvent::TypeId, usersToDevicesToContent);
QVector<std::tuple<QString, QString, QString>> receivedDevices;
receivedDevices.reserve(devices.size());
for (const auto& [user, device] : asKeyValueRange(devices))
diff --git a/lib/connection.h b/lib/connection.h
index 5b806350..b8246ecb 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -133,8 +133,7 @@ class QUOTIENT_API Connection : public QObject {
Q_PROPERTY(bool canChangePassword READ canChangePassword NOTIFY capabilitiesLoaded)
public:
- using UsersToDevicesToEvents =
- UnorderedMap<QString, UnorderedMap<QString, EventPtr>>;
+ using UsersToDevicesToContent = QHash<QString, QHash<QString, QJsonObject>>;
enum RoomVisibility {
PublishRoom,
@@ -689,7 +688,7 @@ public Q_SLOTS:
ForgetRoomJob* forgetRoom(const QString& id);
SendToDeviceJob* sendToDevices(const QString& eventType,
- const UsersToDevicesToEvents& eventsMap);
+ const UsersToDevicesToContent& contents);
/** \deprecated This method is experimental and may be removed any time */
SendMessageJob* sendMessage(const QString& roomId, const RoomEvent& event);
diff --git a/lib/room.cpp b/lib/room.cpp
index 284d19df..f692c354 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -118,7 +118,7 @@ public:
// A map from evtId to a map of relation type to a vector of event
// pointers. Not using QMultiHash, because we want to quickly return
// a number of relations for a given event without enumerating them.
- QHash<QPair<QString, QString>, RelatedEvents> relations;
+ QHash<std::pair<QString, QString>, RelatedEvents> relations;
QString displayname;
Avatar avatar;
QHash<QString, Notification> notifications;
@@ -2687,7 +2687,7 @@ bool Room::Private::processRedaction(const RedactionEvent& redaction)
}
if (const auto* reaction = eventCast<ReactionEvent>(oldEvent)) {
const auto& targetEvtId = reaction->relation().eventId;
- const QPair lookupKey { targetEvtId, EventRelation::AnnotationType };
+ const std::pair lookupKey { targetEvtId, EventRelation::AnnotationType };
if (relations.contains(lookupKey)) {
relations[lookupKey].removeOne(reaction);
emit q->updatedEvent(targetEvtId);
diff --git a/libquotient.pri b/libquotient.pri
index 677f60d3..1b4bd9c0 100644
--- a/libquotient.pri
+++ b/libquotient.pri
@@ -1,8 +1,7 @@
QT += network multimedia
QT -= gui
-# TODO: Having moved to Qt 5.12, replace c++1z with c++17 below
-CONFIG *= c++1z warn_on rtti_off create_prl object_parallel_to_source
+CONFIG *= c++20 warn_on rtti_off create_prl object_parallel_to_source
win32-msvc* {
# Quotient code base does not play well with NMake inference rules