forked from mirror/nheko
- Support for e2ee rooms - Implement categories & file logging - Let the user know when the app can't reach the server (#93) fixes #13 fixes #326remotes/origin/HEAD
commit
8704265978
@ -0,0 +1,37 @@ |
||||
{ |
||||
"files": [ |
||||
{ |
||||
"includePattern": "nheko-VERSION_NAME_VALUE.dmg", |
||||
"matrixParams": { |
||||
"override": 1 |
||||
}, |
||||
"uploadPattern": "VERSION_NAME_VALUE/nheko-VERSION_NAME_VALUE.dmg" |
||||
}, |
||||
{ |
||||
"includePattern": "nheko-VERSION_NAME_VALUE-x86_64.AppImage", |
||||
"matrixParams": { |
||||
"override": 1 |
||||
}, |
||||
"uploadPattern": "VERSION_NAME_VALUE/nheko-VERSION_NAME_VALUE-x86_64.AppImage" |
||||
} |
||||
], |
||||
"package": { |
||||
"desc": "Desktop client for the Matrix protocol", |
||||
"issue_tracker_url": "https://github.com/mujx/nheko/issues", |
||||
"licenses": [ |
||||
"GPL-3.0" |
||||
], |
||||
"name": "nheko", |
||||
"public_download_numbers": true, |
||||
"public_stats": true, |
||||
"repo": "matrix", |
||||
"subject": "mujx", |
||||
"vcs_url": "https://github.com/mujx/nheko", |
||||
"website_url": "https://github.com/mujx/nheko" |
||||
}, |
||||
"publish": true, |
||||
"version": { |
||||
"name": "VERSION_NAME_VALUE", |
||||
"vcs_tag": "VERSION_NAME_VALUE" |
||||
} |
||||
} |
@ -1,26 +0,0 @@ |
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ |
||||
-Wall \ |
||||
-Wextra \ |
||||
-Werror \ |
||||
-pipe \ |
||||
-Wno-unused-function \ |
||||
-pedantic \ |
||||
-Wunreachable-code") |
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") |
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) |
||||
|
||||
if (GCC_VERSION VERSION_GREATER 4.9) |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always" ) |
||||
endif() |
||||
endif() |
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always" ) |
||||
endif() |
||||
endif() |
||||
|
||||
if(NOT APPLE AND NOT MSVC) |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") |
||||
endif() |
@ -1,33 +0,0 @@ |
||||
include(ExternalProject) |
||||
|
||||
# |
||||
# Build matrix-structs. |
||||
# |
||||
|
||||
set(THIRD_PARTY_ROOT ${CMAKE_SOURCE_DIR}/.third-party) |
||||
set(MATRIX_STRUCTS_ROOT ${THIRD_PARTY_ROOT}/matrix_structs) |
||||
set(MATRIX_STRUCTS_INCLUDE_DIR ${MATRIX_STRUCTS_ROOT}/include) |
||||
set(MATRIX_STRUCTS_LIBRARY matrix_structs) |
||||
|
||||
link_directories(${MATRIX_STRUCTS_ROOT}) |
||||
|
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
MatrixStructs |
||||
|
||||
GIT_REPOSITORY https://github.com/mujx/matrix-structs |
||||
GIT_TAG 5e57c2385a79b6629d1998fec4a7c0baee23555e |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${MATRIX_STRUCTS_ROOT} |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_BUILD_TYPE=Release ${MATRIX_STRUCTS_ROOT} |
||||
${WINDOWS_FLAGS} |
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build ${MATRIX_STRUCTS_ROOT} --config Release |
||||
INSTALL_COMMAND "" |
||||
) |
@ -0,0 +1,82 @@ |
||||
cmake_minimum_required(VERSION 3.1) |
||||
project(NHEKO_DEPS) |
||||
|
||||
# Point CMake at any custom modules we may ship |
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") |
||||
|
||||
if(NOT CMAKE_BUILD_TYPE) |
||||
set(CMAKE_BUILD_TYPE Release) |
||||
endif() |
||||
|
||||
set(DEPS_INSTALL_DIR "${CMAKE_BINARY_DIR}/usr" |
||||
CACHE PATH "Dependencies install directory.") |
||||
set(DEPS_BIN_DIR "${DEPS_INSTALL_DIR}/bin" |
||||
CACHE PATH "Dependencies binary install directory.") |
||||
set(DEPS_LIB_DIR "${DEPS_INSTALL_DIR}/lib" |
||||
CACHE PATH "Dependencies library install directory.") |
||||
set(DEPS_BUILD_DIR "${CMAKE_BINARY_DIR}/build" |
||||
CACHE PATH "Dependencies build directory.") |
||||
set(DEPS_DOWNLOAD_DIR "${DEPS_BUILD_DIR}/downloads" |
||||
CACHE PATH "Dependencies download directory.") |
||||
|
||||
option(USE_BUNDLED "Use bundled dependencies." ON) |
||||
|
||||
option(USE_BUNDLED_BOOST "Use the bundled version of Boost." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_OLM "Use the bundled version of libolm." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_MATRIX_STRUCTS "Use the bundled version of matrix-structs." |
||||
${USE_BUNDLED}) |
||||
option(USE_BUNDLED_MATRIX_CLIENT "Use the bundled version of mtxclient." |
||||
${USE_BUNDLED}) |
||||
|
||||
include(ExternalProject) |
||||
|
||||
set(BOOST_URL |
||||
https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.bz2) |
||||
set(BOOST_SHA256 |
||||
5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9) |
||||
|
||||
set(MATRIX_STRUCTS_URL https://github.com/mujx/matrix-structs) |
||||
set(MATRIX_STRUCTS_TAG eeb7373729a1618e2b3838407863342b88b8a0de) |
||||
|
||||
set(MTXCLIENT_URL https://github.com/mujx/mtxclient) |
||||
set(MTXCLIENT_TAG 68188721e042ff5b47ea9a87aa97d3a9efbca989) |
||||
|
||||
set(OLM_URL https://git.matrix.org/git/olm.git) |
||||
set(OLM_TAG 4065c8e11a33ba41133a086ed3de4da94dcb6bae) |
||||
|
||||
set(SPDLOG_URL https://github.com/gabime/spdlog) |
||||
set(SPDLOG_TAG 560df2878ad308b27873b3cc5e810635d69cfad6) |
||||
|
||||
if(USE_BUNDLED_BOOST) |
||||
include(Boost) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_SPDLOG) |
||||
include(SpdLog) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_OLM) |
||||
include(Olm) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_MATRIX_STRUCTS) |
||||
include(MatrixStructs) |
||||
endif() |
||||
|
||||
if(WIN32) |
||||
if("${TARGET_ARCH}" STREQUAL "X86_64") |
||||
set(TARGET_ARCH x64) |
||||
elseif(TARGET_ARCH STREQUAL "X86") |
||||
set(TARGET_ARCH ia32) |
||||
endif() |
||||
endif() |
||||
|
||||
add_custom_target(third-party ALL |
||||
COMMAND ${CMAKE_COMMAND} -E touch .third-party |
||||
DEPENDS ${THIRD_PARTY_DEPS}) |
||||
|
||||
if(USE_BUNDLED_MATRIX_CLIENT) |
||||
include(MatrixClient) |
||||
add_dependencies(MatrixClient third-party) |
||||
endif() |
@ -0,0 +1,23 @@ |
||||
if(WIN32) |
||||
message(STATUS "Building Boost in Windows is not supported (skipping)") |
||||
return() |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
Boost |
||||
|
||||
URL ${BOOST_URL} |
||||
URL_HASH SHA256=${BOOST_SHA256} |
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/boost |
||||
DOWNLOAD_NO_PROGRESS 0 |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/boost |
||||
CONFIGURE_COMMAND ${DEPS_BUILD_DIR}/boost/bootstrap.sh |
||||
--with-libraries=random,thread,system,iostreams,atomic,chrono,date_time,regex |
||||
--prefix=${DEPS_INSTALL_DIR} |
||||
BUILD_COMMAND ${DEPS_BUILD_DIR}/boost/b2 -d0 variant=release link=static threading=multi --layout=system |
||||
INSTALL_COMMAND ${DEPS_BUILD_DIR}/boost/b2 -d0 install |
||||
) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS Boost) |
@ -0,0 +1,31 @@ |
||||
set(PLATFORM_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(PLATFORM_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
if(APPLE) |
||||
set(PLATFORM_FLAGS "-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
MatrixClient |
||||
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/mtxclient |
||||
GIT_REPOSITORY ${MTXCLIENT_URL} |
||||
GIT_TAG ${MTXCLIENT_TAG} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/mtxclient |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMAKE_BUILD_TYPE=Release |
||||
-DBUILD_LIB_TESTS=OFF |
||||
-DBUILD_LIB_EXAMPLES=OFF |
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} |
||||
${PLATFORM_FLAGS} |
||||
${DEPS_BUILD_DIR}/mtxclient |
||||
BUILD_COMMAND |
||||
${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR}/mtxclient --config Release) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS MatrixClient) |
@ -0,0 +1,25 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
MatrixStructs |
||||
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/matrix_structs |
||||
GIT_REPOSITORY ${MATRIX_STRUCTS_URL} |
||||
GIT_TAG ${MATRIX_STRUCTS_TAG} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/matrix_structs |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMAKE_BUILD_TYPE=Release |
||||
${DEPS_BUILD_DIR}/matrix_structs |
||||
${WINDOWS_FLAGS} |
||||
BUILD_COMMAND ${CMAKE_COMMAND} |
||||
--build ${DEPS_BUILD_DIR}/matrix_structs |
||||
--config Release) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS MatrixStructs) |
@ -0,0 +1,34 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
Olm |
||||
|
||||
GIT_REPOSITORY ${OLM_URL} |
||||
GIT_TAG ${OLM_TAG} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/olm |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy |
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/OlmCMakeLists.txt |
||||
${DEPS_BUILD_DIR}/olm/CMakeLists.txt |
||||
COMMAND ${CMAKE_COMMAND} -E copy |
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/OlmConfig.cmake.in |
||||
${DEPS_BUILD_DIR}/olm/cmake/OlmConfig.cmake.in |
||||
COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMAKE_BUILD_TYPE=Release |
||||
${DEPS_BUILD_DIR}/olm |
||||
${WINDOWS_FLAGS} |
||||
BUILD_COMMAND ${CMAKE_COMMAND} |
||||
--build ${DEPS_BUILD_DIR}/olm |
||||
--config Release |
||||
INSTALL_COMMAND ${CMAKE_COMMAND} |
||||
--build ${DEPS_BUILD_DIR}/olm |
||||
--config Release |
||||
--target install) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS Olm) |
@ -0,0 +1,107 @@ |
||||
cmake_minimum_required(VERSION 3.1) |
||||
|
||||
project(olm VERSION 2.2.2 LANGUAGES CXX C) |
||||
|
||||
add_definitions(-DOLMLIB_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}) |
||||
add_definitions(-DOLMLIB_VERSION_MINOR=${PROJECT_VERSION_MINOR}) |
||||
add_definitions(-DOLMLIB_VERSION_PATCH=${PROJECT_VERSION_PATCH}) |
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
||||
set(CMAKE_CXX_STANDARD 11) |
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) |
||||
set(CMAKE_C_STANDARD 99) |
||||
set(CMAKE_C_STANDARD_REQUIRED ON) |
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) |
||||
|
||||
if(NOT CMAKE_BUILD_TYPE) |
||||
set(CMAKE_BUILD_TYPE Release) |
||||
endif() |
||||
|
||||
add_library(olm |
||||
src/account.cpp |
||||
src/base64.cpp |
||||
src/cipher.cpp |
||||
src/crypto.cpp |
||||
src/memory.cpp |
||||
src/message.cpp |
||||
src/pickle.cpp |
||||
src/ratchet.cpp |
||||
src/session.cpp |
||||
src/utility.cpp |
||||
|
||||
src/ed25519.c |
||||
src/error.c |
||||
src/inbound_group_session.c |
||||
src/megolm.c |
||||
src/olm.cpp |
||||
src/outbound_group_session.c |
||||
src/pickle_encoding.c |
||||
|
||||
lib/crypto-algorithms/aes.c |
||||
lib/crypto-algorithms/sha256.c |
||||
lib/curve25519-donna/curve25519-donna.c) |
||||
add_library(Olm::Olm ALIAS olm) |
||||
|
||||
target_include_directories(olm |
||||
PUBLIC |
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> |
||||
$<INSTALL_INTERFACE:include> |
||||
PRIVATE |
||||
${CMAKE_CURRENT_SOURCE_DIR}/lib) |
||||
|
||||
set_target_properties(olm PROPERTIES |
||||
SOVERSION ${PROJECT_VERSION_MAJOR} |
||||
VERSION ${PROJECT_VERSION}) |
||||
|
||||
set_target_properties(olm PROPERTIES |
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} |
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} |
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) |
||||
|
||||
# |
||||
# Installation |
||||
# |
||||
include(GNUInstallDirs) |
||||
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Olm) |
||||
install(TARGETS olm |
||||
EXPORT olm-targets |
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} |
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) |
||||
|
||||
# The exported target will be named Olm. |
||||
set_target_properties(olm PROPERTIES EXPORT_NAME Olm) |
||||
install(FILES |
||||
${CMAKE_SOURCE_DIR}/include/olm/olm.h |
||||
${CMAKE_SOURCE_DIR}/include/olm/outbound_group_session.h |
||||
${CMAKE_SOURCE_DIR}/include/olm/inbound_group_session.h |
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/olm) |
||||
|
||||
# Export the targets to a script. |
||||
install(EXPORT olm-targets |
||||
FILE OlmTargets.cmake |
||||
NAMESPACE Olm:: |
||||
DESTINATION ${INSTALL_CONFIGDIR}) |
||||
|
||||
# Create a ConfigVersion.cmake file. |
||||
include(CMakePackageConfigHelpers) |
||||
write_basic_package_version_file( |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake |
||||
VERSION ${PROJECT_VERSION} |
||||
COMPATIBILITY SameMajorVersion) |
||||
|
||||
configure_package_config_file( |
||||
${CMAKE_CURRENT_LIST_DIR}/cmake/OlmConfig.cmake.in |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake |
||||
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}) |
||||
|
||||
#Install the config & configversion. |
||||
install(FILES |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake |
||||
DESTINATION ${INSTALL_CONFIGDIR}) |
||||
|
||||
# Register package in user's package registry |
||||
export(EXPORT olm-targets |
||||
FILE ${CMAKE_CURRENT_BINARY_DIR}/OlmTargets.cmake |
||||
NAMESPACE Olm::) |
||||
export(PACKAGE Olm) |
@ -0,0 +1,11 @@ |
||||
get_filename_component(Olm_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) |
||||
include(CMakeFindDependencyMacro) |
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${Olm_CMAKE_DIR}) |
||||
list(REMOVE_AT CMAKE_MODULE_PATH -1) |
||||
|
||||
if(NOT TARGET Olm::Olm) |
||||
include("${Olm_CMAKE_DIR}/OlmTargets.cmake") |
||||
endif() |
||||
|
||||
set(Olm_LIBRARIES Olm::Olm) |
@ -0,0 +1,22 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
SpdLog |
||||
|
||||
GIT_REPOSITORY ${SPDLOG_URL} |
||||
GIT_TAG ${SPDLOG_TAG} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/spdlog |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DSPDLOG_BUILD_EXAMPLES=0 |
||||
-DSPDLOG_BUILD_TESTING=0 |
||||
${DEPS_BUILD_DIR}/spdlog |
||||
${WINDOWS_FLAGS}) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS SpdLog) |
@ -0,0 +1,21 @@ |
||||
#pragma once |
||||
|
||||
#include <memory> |
||||
#include <spdlog/spdlog.h> |
||||
|
||||
namespace nhlog { |
||||
void |
||||
init(const std::string &file); |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
ui(); |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
net(); |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
db(); |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
crypto(); |
||||
} |
@ -1,287 +1,28 @@ |
||||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#pragma once |
||||
|
||||
#include <QFileInfo> |
||||
#include <QJsonDocument> |
||||
#include <QNetworkAccessManager> |
||||
#include <QNetworkReply> |
||||
#include <QNetworkRequest> |
||||
#include <QUrl> |
||||
#include <memory> |
||||
#include <mtx.hpp> |
||||
#include <mtx/errors.hpp> |
||||
|
||||
class DownloadMediaProxy : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
signals: |
||||
void imageDownloaded(const QPixmap &data); |
||||
void fileDownloaded(const QByteArray &data); |
||||
void avatarDownloaded(const QImage &img); |
||||
}; |
||||
#include <QMetaType> |
||||
|
||||
class StateEventProxy : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
signals: |
||||
void stateEventSent(); |
||||
void stateEventError(const QString &msg); |
||||
}; |
||||
#include <mtx/responses.hpp> |
||||
#include <mtxclient/http/client.hpp> |
||||
|
||||
Q_DECLARE_METATYPE(mtx::responses::Login) |
||||
Q_DECLARE_METATYPE(mtx::responses::Messages) |
||||
Q_DECLARE_METATYPE(mtx::responses::Notifications) |
||||
Q_DECLARE_METATYPE(mtx::responses::Rooms) |
||||
Q_DECLARE_METATYPE(mtx::responses::Sync) |
||||
Q_DECLARE_METATYPE(std::string) |
||||
Q_DECLARE_METATYPE(std::vector<std::string>) |
||||
|
||||
/*
|
||||
* MatrixClient provides the high level API to communicate with |
||||
* a Matrix homeserver. All the responses are returned through signals. |
||||
*/ |
||||
class MatrixClient : public QNetworkAccessManager |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
MatrixClient(QObject *parent = 0); |
||||
|
||||
// Client API.
|
||||
void initialSync() noexcept; |
||||
void sync() noexcept; |
||||
template<class EventBody, mtx::events::EventType EventT> |
||||
std::shared_ptr<StateEventProxy> sendStateEvent(const EventBody &body, |
||||
const QString &roomId, |
||||
const QString &stateKey = ""); |
||||
void sendRoomMessage(mtx::events::MessageType ty, |
||||
int txnId, |
||||
const QString &roomid, |
||||
const QString &msg, |
||||
const QString &mime, |
||||
uint64_t media_size, |
||||
const QString &url = "") noexcept; |
||||
void login(const QString &username, const QString &password) noexcept; |
||||
void registerUser(const QString &username, |
||||
const QString &password, |
||||
const QString &server, |
||||
const QString &session = "") noexcept; |
||||
void versions() noexcept; |
||||
void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url); |
||||
//! Download user's avatar.
|
||||
QSharedPointer<DownloadMediaProxy> fetchUserAvatar(const QUrl &avatarUrl); |
||||
void fetchCommunityAvatar(const QString &communityId, const QUrl &avatarUrl); |
||||
void fetchCommunityProfile(const QString &communityId); |
||||
void fetchCommunityRooms(const QString &communityId); |
||||
QSharedPointer<DownloadMediaProxy> downloadImage(const QUrl &url); |
||||
QSharedPointer<DownloadMediaProxy> downloadFile(const QUrl &url); |
||||
void messages(const QString &room_id, const QString &from_token, int limit = 30) noexcept; |
||||
void uploadImage(const QString &roomid, |
||||
const QString &filename, |
||||
const QSharedPointer<QIODevice> data); |
||||
void uploadFile(const QString &roomid, |
||||
const QString &filename, |
||||
const QSharedPointer<QIODevice> data); |
||||
void uploadAudio(const QString &roomid, |
||||
const QString &filename, |
||||
const QSharedPointer<QIODevice> data); |
||||
void uploadVideo(const QString &roomid, |
||||
const QString &filename, |
||||
const QSharedPointer<QIODevice> data); |
||||
void uploadFilter(const QString &filter) noexcept; |
||||
void joinRoom(const QString &roomIdOrAlias); |
||||
void leaveRoom(const QString &roomId); |
||||
void sendTypingNotification(const QString &roomid, int timeoutInMillis = 20000); |
||||
void removeTypingNotification(const QString &roomid); |
||||
void readEvent(const QString &room_id, const QString &event_id); |
||||
void redactEvent(const QString &room_id, const QString &event_id); |
||||
void inviteUser(const QString &room_id, const QString &user); |
||||
void createRoom(const mtx::requests::CreateRoom &request); |
||||
void getNotifications() noexcept; |
||||
|
||||
QUrl getHomeServer() { return server_; }; |
||||
int transactionId() { return txn_id_; }; |
||||
int incrementTransactionId() { return ++txn_id_; }; |
||||
|
||||
void reset() noexcept; |
||||
|
||||
public slots: |
||||
void getOwnProfile() noexcept; |
||||
void getOwnCommunities() noexcept; |
||||
void logout() noexcept; |
||||
|
||||
void setServer(const QString &server) |
||||
{ |
||||
server_ = QUrl(QString("%1://%2").arg(serverProtocol_).arg(server)); |
||||
}; |
||||
void setAccessToken(const QString &token) { token_ = token; }; |
||||
void setNextBatchToken(const QString &next_batch) { next_batch_ = next_batch; }; |
||||
|
||||
signals: |
||||
void loginError(const QString &error); |
||||
void registerError(const QString &error); |
||||
void registrationFlow(const QString &user, |
||||
const QString &pass, |
||||
const QString &server, |
||||
const QString &session); |
||||
void versionError(const QString &error); |
||||
|
||||
void loggedOut(); |
||||
void invitedUser(const QString &room_id, const QString &user); |
||||
void roomCreated(const QString &room_id); |
||||
|
||||
void loginSuccess(const QString &userid, const QString &homeserver, const QString &token); |
||||
void registerSuccess(const QString &userid, |
||||
const QString &homeserver, |
||||
const QString &token); |
||||
void versionSuccess(); |
||||
void uploadFailed(int statusCode, const QString &msg); |
||||
void imageUploaded(const QString &roomid, |
||||
const QString &filename, |
||||
const QString &url, |
||||
const QString &mime, |
||||
uint64_t size); |
||||
void fileUploaded(const QString &roomid, |
||||
const QString &filename, |
||||
const QString &url, |
||||
const QString &mime, |
||||
uint64_t size); |
||||
void audioUploaded(const QString &roomid, |
||||
const QString &filename, |
||||
const QString &url, |
||||
const QString &mime, |
||||
uint64_t size); |
||||
void videoUploaded(const QString &roomid, |
||||
const QString &filename, |
||||
const QString &url, |
||||
const QString &mime, |
||||
uint64_t size); |
||||
void roomAvatarRetrieved(const QString &roomid, |
||||
const QPixmap &img, |
||||
const QString &url, |
||||
const QByteArray &data); |
||||
void userAvatarRetrieved(const QString &userId, const QImage &img); |
||||
void communityAvatarRetrieved(const QString &communityId, const QPixmap &img); |
||||
void communityProfileRetrieved(const QString &communityId, const QJsonObject &profile); |
||||
void communityRoomsRetrieved(const QString &communityId, const QJsonObject &rooms); |
||||
|
||||
// Returned profile data for the user's account.
|
||||
void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name); |
||||
void getOwnCommunitiesResponse(const QList<QString> &own_communities); |
||||
void initialSyncCompleted(const mtx::responses::Sync &response); |
||||
void initialSyncFailed(int status_code = -1); |
||||
void syncCompleted(const mtx::responses::Sync &response); |
||||
void syncFailed(const QString &msg); |
||||
void joinFailed(const QString &msg); |
||||
void messageSent(const QString &event_id, const QString &roomid, int txn_id); |
||||
void messageSendFailed(const QString &roomid, int txn_id); |
||||
void emoteSent(const QString &event_id, const QString &roomid, int txn_id); |
||||
void messagesRetrieved(const QString &room_id, const mtx::responses::Messages &msgs); |
||||
void joinedRoom(const QString &room_id); |
||||
void leftRoom(const QString &room_id); |
||||
void roomCreationFailed(const QString &msg); |
||||
|
||||
void redactionFailed(const QString &error); |
||||
void redactionCompleted(const QString &room_id, const QString &event_id); |
||||
void invalidToken(); |
||||
void syncError(const QString &error); |
||||
void notificationsRetrieved(const mtx::responses::Notifications ¬ifications); |
||||
|
||||
private: |
||||
QNetworkReply *makeUploadRequest(QSharedPointer<QIODevice> iodev); |
||||
QJsonObject getUploadReply(QNetworkReply *reply); |
||||
void setupAuth(QNetworkRequest &req) |
||||
{ |
||||
req.setRawHeader("Authorization", QString("Bearer %1").arg(token_).toLocal8Bit()); |
||||
} |
||||
|
||||
// Client API prefix.
|
||||
QString clientApiUrl_; |
||||
|
||||
// Media API prefix.
|
||||
QString mediaApiUrl_; |
||||
|
||||
// The Matrix server used for communication.
|
||||
QUrl server_; |
||||
|
||||
// The access token used for authentication.
|
||||
QString token_; |
||||
|
||||
// Increasing transaction ID.
|
||||
int txn_id_; |
||||
namespace http { |
||||
namespace v2 { |
||||
mtx::http::Client * |
||||
client(); |
||||
|
||||
//! Token to be used for the next sync.
|
||||
QString next_batch_; |
||||
//! http or https (default).
|
||||
QString serverProtocol_; |
||||
//! Filter to be send as filter-param for (initial) /sync requests.
|
||||
QString filter_; |
||||
}; |
||||
bool |
||||
is_logged_in(); |
||||
} |
||||
|
||||
namespace http { |
||||
//! Initialize the http module
|
||||
void |
||||
init(); |
||||
|
||||
//! Retrieve the client instance.
|
||||
MatrixClient * |
||||
client(); |
||||
} |
||||
|
||||
template<class EventBody, mtx::events::EventType EventT> |
||||
std::shared_ptr<StateEventProxy> |
||||
MatrixClient::sendStateEvent(const EventBody &body, const QString &roomId, const QString &stateKey) |
||||
{ |
||||
QUrl endpoint(server_); |
||||
endpoint.setPath(clientApiUrl_ + QString("/rooms/%1/state/%2/%3") |
||||
.arg(roomId) |
||||
.arg(QString::fromStdString(to_string(EventT))) |
||||
.arg(stateKey)); |
||||
|
||||
QNetworkRequest request(QString(endpoint.toEncoded())); |
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); |
||||
setupAuth(request); |
||||
|
||||
auto proxy = std::shared_ptr<StateEventProxy>(new StateEventProxy, |
||||
[](StateEventProxy *p) { p->deleteLater(); }); |
||||
|
||||
auto serializedBody = nlohmann::json(body).dump(); |
||||
auto reply = put(request, QByteArray(serializedBody.data(), serializedBody.size())); |
||||
connect(reply, &QNetworkReply::finished, this, [reply, proxy]() { |
||||
reply->deleteLater(); |
||||
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); |
||||
auto data = reply->readAll(); |
||||
|
||||
if (status == 0 || status >= 400) { |
||||
try { |
||||
mtx::errors::Error res = nlohmann::json::parse(data); |
||||
emit proxy->stateEventError(QString::fromStdString(res.error)); |
||||
} catch (const std::exception &e) { |
||||
emit proxy->stateEventError(QString::fromStdString(e.what())); |
||||
} |
||||
|
||||
return; |
||||
} |
||||
|
||||
try { |
||||
mtx::responses::EventId res = nlohmann::json::parse(data); |
||||
emit proxy->stateEventSent(); |
||||
} catch (const std::exception &e) { |
||||
emit proxy->stateEventError(QString::fromStdString(e.what())); |
||||
} |
||||
}); |
||||
|
||||
return proxy; |
||||
} |
||||
|
@ -0,0 +1,78 @@ |
||||
#pragma once |
||||
|
||||
#include <boost/optional.hpp> |
||||
|
||||
#include <memory> |
||||
#include <mtx.hpp> |
||||
#include <mtxclient/crypto/client.hpp> |
||||
|
||||
constexpr auto OLM_ALGO = "m.olm.v1.curve25519-aes-sha2"; |
||||
|
||||
namespace olm { |
||||
|
||||
struct OlmCipherContent |
||||
{ |
||||
std::string body; |
||||
uint8_t type; |
||||
}; |
||||
|
||||
inline void |
||||
from_json(const nlohmann::json &obj, OlmCipherContent &msg) |
||||
{ |
||||
msg.body = obj.at("body"); |
||||
msg.type = obj.at("type"); |
||||
} |
||||
|
||||
struct OlmMessage |
||||
{ |
||||
std::string sender_key; |
||||
std::string sender; |
||||
|
||||
using RecipientKey = std::string; |
||||
std::map<RecipientKey, OlmCipherContent> ciphertext; |
||||
}; |
||||
|
||||
inline void |
||||
from_json(const nlohmann::json &obj, OlmMessage &msg) |
||||
{ |
||||
if (obj.at("type") != "m.room.encrypted") |
||||
throw std::invalid_argument("invalid type for olm message"); |
||||
|
||||
if (obj.at("content").at("algorithm") != OLM_ALGO) |
||||
throw std::invalid_argument("invalid algorithm for olm message"); |
||||
|
||||
msg.sender = obj.at("sender"); |
||||
msg.sender_key = obj.at("content").at("sender_key"); |
||||
msg.ciphertext = |
||||
obj.at("content").at("ciphertext").get<std::map<std::string, OlmCipherContent>>(); |
||||
} |
||||
|
||||
mtx::crypto::OlmClient * |
||||
client(); |
||||
|
||||
void |
||||
handle_to_device_messages(const std::vector<nlohmann::json> &msgs); |
||||
|
||||
boost::optional<json> |
||||
try_olm_decryption(const std::string &sender_key, const OlmCipherContent &content); |
||||
|
||||
void |
||||
handle_olm_message(const OlmMessage &msg); |
||||
|
||||
//! Establish a new inbound megolm session with the decrypted payload from olm.
|
||||
void |
||||
create_inbound_megolm_session(const std::string &sender, |
||||
const std::string &sender_key, |
||||
const nlohmann::json &payload); |
||||
|
||||
void |
||||
handle_pre_key_olm_message(const std::string &sender, |
||||
const std::string &sender_key, |
||||
const OlmCipherContent &content); |
||||
|
||||
mtx::events::msg::Encrypted |
||||
encrypt_group_message(const std::string &room_id, |
||||
const std::string &device_id, |
||||
const std::string &body); |
||||
|
||||
} // namespace olm
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,59 @@ |
||||
#include "Logging.hpp" |
||||
|
||||
#include <iostream> |
||||
#include <spdlog/sinks/file_sinks.h> |
||||
|
||||
namespace { |
||||
std::shared_ptr<spdlog::logger> db_logger = nullptr; |
||||
std::shared_ptr<spdlog::logger> net_logger = nullptr; |
||||
std::shared_ptr<spdlog::logger> crypto_logger = nullptr; |
||||
std::shared_ptr<spdlog::logger> ui_logger = nullptr; |
||||
|
||||
constexpr auto MAX_FILE_SIZE = 1024 * 1024 * 6; |
||||
constexpr auto MAX_LOG_FILES = 3; |
||||
} |
||||
|
||||
namespace nhlog { |
||||
void |
||||
init(const std::string &file_path) |
||||
{ |
||||
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>( |
||||
file_path, MAX_FILE_SIZE, MAX_LOG_FILES); |
||||
|
||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>(); |
||||
|
||||
std::vector<spdlog::sink_ptr> sinks; |
||||
sinks.push_back(file_sink); |
||||
sinks.push_back(console_sink); |
||||
|
||||
net_logger = std::make_shared<spdlog::logger>("net", std::begin(sinks), std::end(sinks)); |
||||
ui_logger = std::make_shared<spdlog::logger>("ui", std::begin(sinks), std::end(sinks)); |
||||
db_logger = std::make_shared<spdlog::logger>("db", std::begin(sinks), std::end(sinks)); |
||||
crypto_logger = |
||||
std::make_shared<spdlog::logger>("crypto", std::begin(sinks), std::end(sinks)); |
||||
} |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
ui() |
||||
{ |
||||
return ui_logger; |
||||
} |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
net() |
||||
{ |
||||
return net_logger; |
||||
} |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
db() |
||||
{ |
||||
return db_logger; |
||||
} |
||||
|
||||
std::shared_ptr<spdlog::logger> |
||||
crypto() |
||||
{ |
||||
return crypto_logger; |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,228 @@ |
||||
#include "Olm.hpp" |
||||
|
||||
#include "Cache.h" |
||||
#include "Logging.hpp" |
||||
|
||||
using namespace mtx::crypto; |
||||
|
||||
namespace { |
||||
auto client_ = std::make_unique<mtx::crypto::OlmClient>(); |
||||
} |
||||
|
||||
namespace olm { |
||||
|
||||
mtx::crypto::OlmClient * |
||||
client() |
||||
{ |
||||
return client_.get(); |
||||
} |
||||
|
||||
void |
||||
handle_to_device_messages(const std::vector<nlohmann::json> &msgs) |
||||
{ |
||||
if (msgs.empty()) |
||||
return; |
||||
|
||||
nhlog::crypto()->info("received {} to_device messages", msgs.size()); |
||||
|
||||
for (const auto &msg : msgs) { |
||||
try { |
||||
OlmMessage olm_msg = msg; |
||||
handle_olm_message(std::move(olm_msg)); |
||||
} catch (const nlohmann::json::exception &e) { |
||||
nhlog::crypto()->warn( |
||||
"parsing error for olm message: {} {}", e.what(), msg.dump(2)); |
||||
} catch (const std::invalid_argument &e) { |
||||
nhlog::crypto()->warn( |
||||
"validation error for olm message: {} {}", e.what(), msg.dump(2)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void |
||||
handle_olm_message(const OlmMessage &msg) |
||||
{ |
||||
nhlog::crypto()->info("sender : {}", msg.sender); |
||||
nhlog::crypto()->info("sender_key: {}", msg.sender_key); |
||||
|
||||
const auto my_key = olm::client()->identity_keys().curve25519; |
||||
|
||||
for (const auto &cipher : msg.ciphertext) { |
||||
// We skip messages not meant for the current device.
|
||||
if (cipher.first != my_key) |
||||
continue; |
||||
|
||||
const auto type = cipher.second.type; |
||||
nhlog::crypto()->info("type: {}", type == 0 ? "OLM_PRE_KEY" : "OLM_MESSAGE"); |
||||
|
||||
auto payload = try_olm_decryption(msg.sender_key, cipher.second); |
||||
|
||||
if (payload) { |
||||
nhlog::crypto()->info("decrypted olm payload: {}", payload.value().dump(2)); |
||||
create_inbound_megolm_session(msg.sender, msg.sender_key, payload.value()); |
||||
return; |
||||
} |
||||
|
||||
// Not a PRE_KEY message
|
||||
if (cipher.second.type != 0) { |
||||
// TODO: log that it should have matched something
|
||||
return; |
||||
} |
||||
|
||||
handle_pre_key_olm_message(msg.sender, msg.sender_key, cipher.second); |
||||
} |
||||
} |
||||
|
||||
void |
||||
handle_pre_key_olm_message(const std::string &sender, |
||||
const std::string &sender_key, |
||||
const OlmCipherContent &content) |
||||
{ |
||||
nhlog::crypto()->info("opening olm session with {}", sender); |
||||
|
||||
OlmSessionPtr inbound_session = nullptr; |
||||
try { |
||||
inbound_session = olm::client()->create_inbound_session(content.body); |
||||
|
||||
// We also remove the one time key used to establish that
|
||||
// session so we'll have to update our copy of the account object.
|
||||
cache::client()->saveOlmAccount(olm::client()->save("secret")); |
||||
} catch (const olm_exception &e) { |
||||
nhlog::crypto()->critical( |
||||
"failed to create inbound session with {}: {}", sender, e.what()); |
||||
return; |
||||
} |
||||
|
||||
if (!matches_inbound_session_from(inbound_session.get(), sender_key, content.body)) { |
||||
nhlog::crypto()->warn("inbound olm session doesn't match sender's key ({})", |
||||
sender); |
||||
return; |
||||
} |
||||
|
||||
mtx::crypto::BinaryBuf output; |
||||
try { |
||||
output = |
||||
olm::client()->decrypt_message(inbound_session.get(), content.type, content.body); |
||||
} catch (const olm_exception &e) { |
||||
nhlog::crypto()->critical( |
||||
"failed to decrypt olm message {}: {}", content.body, e.what()); |
||||
return; |
||||
} |
||||
|
||||
auto plaintext = json::parse(std::string((char *)output.data(), output.size())); |
||||
nhlog::crypto()->info("decrypted message: \n {}", plaintext.dump(2)); |
||||
|
||||
try { |
||||
cache::client()->saveOlmSession(sender_key, std::move(inbound_session)); |
||||
} catch (const lmdb::error &e) { |
||||
nhlog::db()->warn( |
||||
"failed to save inbound olm session from {}: {}", sender, e.what()); |
||||
} |
||||
|
||||
create_inbound_megolm_session(sender, sender_key, plaintext); |
||||
} |
||||
|
||||
mtx::events::msg::Encrypted |
||||
encrypt_group_message(const std::string &room_id, |
||||
const std::string &device_id, |
||||
const std::string &body) |
||||
{ |
||||
using namespace mtx::events; |
||||
|
||||
// Always chech before for existence.
|
||||
auto res = cache::client()->getOutboundMegolmSession(room_id); |
||||
auto payload = olm::client()->encrypt_group_message(res.session, body); |
||||
|
||||
// Prepare the m.room.encrypted event.
|
||||
msg::Encrypted data; |
||||
data.ciphertext = std::string((char *)payload.data(), payload.size()); |
||||
data.sender_key = olm::client()->identity_keys().curve25519; |
||||
data.session_id = res.data.session_id; |
||||
data.device_id = device_id; |
||||
|
||||
auto message_index = olm_outbound_group_session_message_index(res.session); |
||||
nhlog::crypto()->info("next message_index {}", message_index); |
||||
|
||||
// We need to re-pickle the session after we send a message to save the new message_index.
|
||||
cache::client()->updateOutboundMegolmSession(room_id, message_index); |
||||
|
||||
return data; |
||||
} |
||||
|
||||
boost::optional<json> |
||||
try_olm_decryption(const std::string &sender_key, const OlmCipherContent &msg) |
||||
{ |
||||
auto session_ids = cache::client()->getOlmSessions(sender_key); |
||||
|
||||
for (const auto &id : session_ids) { |
||||
auto session = cache::client()->getOlmSession(sender_key, id); |
||||
|
||||
if (!session) |
||||
continue; |
||||
|
||||
mtx::crypto::BinaryBuf text; |
||||
|
||||
try { |
||||
text = olm::client()->decrypt_message(session->get(), msg.type, msg.body); |
||||
cache::client()->saveOlmSession(id, std::move(session.value())); |
||||
|
||||
} catch (const olm_exception &e) { |
||||
nhlog::crypto()->info("failed to decrypt olm message ({}, {}) with {}: {}", |
||||
msg.type, |
||||
sender_key, |
||||
id, |
||||
e.what()); |
||||
continue; |
||||
} catch (const lmdb::error &e) { |
||||
nhlog::crypto()->critical("failed to save session: {}", e.what()); |
||||
return {}; |
||||
} |
||||
|
||||
try { |
||||
return json::parse(std::string((char *)text.data(), text.size())); |
||||
} catch (const json::exception &e) { |
||||
nhlog::crypto()->critical("failed to parse the decrypted session msg: {}", |
||||
e.what()); |
||||
} |
||||
} |
||||
|
||||
return {}; |
||||
} |
||||
|
||||
void |
||||
create_inbound_megolm_session(const std::string &sender, |
||||
const std::string &sender_key, |
||||
const nlohmann::json &payload) |
||||
{ |
||||
std::string room_id, session_id, session_key; |
||||
|
||||
try { |
||||
room_id = payload.at("content").at("room_id"); |
||||
session_id = payload.at("content").at("session_id"); |
||||
session_key = payload.at("content").at("session_key"); |
||||
} catch (const nlohmann::json::exception &e) { |
||||
nhlog::crypto()->critical( |
||||
"failed to parse plaintext olm message: {} {}", e.what(), payload.dump(2)); |
||||
return; |
||||
} |
||||
|
||||
MegolmSessionIndex index; |
||||
index.room_id = room_id; |
||||
index.session_id = session_id; |
||||
index.sender_key = sender_key; |
||||
|
||||
try { |
||||
auto megolm_session = olm::client()->init_inbound_group_session(session_key); |
||||
cache::client()->saveInboundMegolmSession(index, std::move(megolm_session)); |
||||
} catch (const lmdb::error &e) { |
||||
nhlog::crypto()->critical("failed to save inbound megolm session: {}", e.what()); |
||||
return; |
||||
} catch (const olm_exception &e) { |
||||
nhlog::crypto()->critical("failed to create inbound megolm session: {}", e.what()); |
||||
return; |
||||
} |
||||
|
||||
nhlog::crypto()->info("established inbound megolm session ({}, {})", room_id, sender); |
||||
} |
||||
|
||||
} // namespace olm
|
Loading…
Reference in new issue