2017-07-29 11:49:00 +03:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2018-06-28 16:16:43 +03:00
|
|
|
#include <QDateTime>
|
2017-08-26 14:31:23 +03:00
|
|
|
#include <QDir>
|
2018-04-29 15:42:40 +03:00
|
|
|
#include <QImage>
|
2018-06-28 16:16:43 +03:00
|
|
|
#include <QString>
|
2018-06-10 20:03:45 +03:00
|
|
|
|
2020-01-24 20:39:26 +03:00
|
|
|
#if __has_include(<lmdbxx/lmdb++.h>)
|
|
|
|
#include <lmdbxx/lmdb++.h>
|
|
|
|
#else
|
2017-07-29 11:49:00 +03:00
|
|
|
#include <lmdb++.h>
|
2020-01-24 20:39:26 +03:00
|
|
|
#endif
|
2019-12-14 19:08:36 +03:00
|
|
|
|
2020-10-27 19:45:28 +03:00
|
|
|
#include <mtx/events/event_type.hpp>
|
|
|
|
#include <mtx/events/presence.hpp>
|
|
|
|
#include <mtx/responses/crypto.hpp>
|
|
|
|
#include <mtxclient/crypto/types.hpp>
|
2018-06-10 20:03:45 +03:00
|
|
|
|
2019-12-15 01:39:02 +03:00
|
|
|
#include "CacheCryptoStructs.h"
|
|
|
|
#include "CacheStructs.h"
|
2018-06-18 18:36:19 +03:00
|
|
|
|
2020-10-27 19:45:28 +03:00
|
|
|
namespace mtx::responses {
|
|
|
|
struct Notifications;
|
|
|
|
}
|
|
|
|
|
2019-12-15 04:56:04 +03:00
|
|
|
namespace cache {
|
|
|
|
void
|
|
|
|
init(const QString &user_id);
|
|
|
|
|
|
|
|
std::string
|
|
|
|
displayName(const std::string &room_id, const std::string &user_id);
|
|
|
|
QString
|
|
|
|
displayName(const QString &room_id, const QString &user_id);
|
|
|
|
QString
|
|
|
|
avatarUrl(const QString &room_id, const QString &user_id);
|
|
|
|
|
2020-06-08 02:45:24 +03:00
|
|
|
// presence
|
|
|
|
mtx::presence::PresenceState
|
|
|
|
presenceState(const std::string &user_id);
|
|
|
|
std::string
|
|
|
|
statusMessage(const std::string &user_id);
|
|
|
|
|
2020-10-02 02:14:42 +03:00
|
|
|
// user cache stores user keys
|
|
|
|
std::optional<UserKeyCache>
|
|
|
|
userKeys(const std::string &user_id);
|
2020-07-06 19:02:21 +03:00
|
|
|
void
|
2020-10-02 02:14:42 +03:00
|
|
|
updateUserKeys(const std::string &sync_token, const mtx::responses::QueryKeys &keyQuery);
|
2020-06-28 18:31:34 +03:00
|
|
|
|
2020-10-02 02:14:42 +03:00
|
|
|
// device & user verification cache
|
2020-10-08 00:03:14 +03:00
|
|
|
std::optional<VerificationStatus>
|
2020-10-02 02:14:42 +03:00
|
|
|
verificationStatus(const std::string &user_id);
|
|
|
|
void
|
2020-10-08 00:03:14 +03:00
|
|
|
markDeviceVerified(const std::string &user_id, const std::string &device);
|
2020-10-02 02:14:42 +03:00
|
|
|
void
|
2020-10-08 00:03:14 +03:00
|
|
|
markDeviceUnverified(const std::string &user_id, const std::string &device);
|
2020-06-28 18:31:34 +03:00
|
|
|
|
2019-12-15 04:56:04 +03:00
|
|
|
std::vector<std::string>
|
|
|
|
joinedRooms();
|
|
|
|
|
|
|
|
QMap<QString, RoomInfo>
|
|
|
|
roomInfo(bool withInvites = true);
|
|
|
|
std::map<QString, bool>
|
|
|
|
invites();
|
|
|
|
|
|
|
|
//! Calculate & return the name of the room.
|
|
|
|
QString
|
|
|
|
getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
|
|
|
|
//! Get room join rules
|
|
|
|
mtx::events::state::JoinRule
|
|
|
|
getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb);
|
|
|
|
bool
|
|
|
|
getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb);
|
|
|
|
//! Retrieve the topic of the room if any.
|
|
|
|
QString
|
|
|
|
getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
|
|
|
|
//! Retrieve the room avatar's url if any.
|
|
|
|
QString
|
2020-11-26 00:45:33 +03:00
|
|
|
getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
|
2019-12-15 04:56:04 +03:00
|
|
|
//! Retrieve the version of the room if any.
|
|
|
|
QString
|
|
|
|
getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb);
|
|
|
|
|
|
|
|
//! Retrieve member info from a room.
|
|
|
|
std::vector<RoomMember>
|
|
|
|
getMembers(const std::string &room_id, std::size_t startIndex = 0, std::size_t len = 30);
|
2018-06-10 20:03:45 +03:00
|
|
|
|
2019-12-15 04:56:04 +03:00
|
|
|
bool
|
|
|
|
isInitialized();
|
|
|
|
|
|
|
|
std::string
|
|
|
|
nextBatchToken();
|
|
|
|
|
|
|
|
void
|
|
|
|
deleteData();
|
|
|
|
|
|
|
|
void
|
|
|
|
removeInvite(lmdb::txn &txn, const std::string &room_id);
|
|
|
|
void
|
|
|
|
removeInvite(const std::string &room_id);
|
|
|
|
void
|
|
|
|
removeRoom(lmdb::txn &txn, const std::string &roomid);
|
|
|
|
void
|
|
|
|
removeRoom(const std::string &roomid);
|
|
|
|
void
|
|
|
|
removeRoom(const QString &roomid);
|
|
|
|
void
|
|
|
|
setup();
|
|
|
|
|
2020-05-02 17:44:50 +03:00
|
|
|
//! returns if the format is current, older or newer
|
|
|
|
cache::CacheVersion
|
|
|
|
formatVersion();
|
|
|
|
//! set the format version to the current version
|
2019-12-15 04:56:04 +03:00
|
|
|
void
|
|
|
|
setCurrentFormat();
|
2020-05-02 17:44:50 +03:00
|
|
|
//! migrates db to the current format
|
|
|
|
bool
|
|
|
|
runMigrations();
|
2019-12-15 04:56:04 +03:00
|
|
|
|
|
|
|
QMap<QString, mtx::responses::Notifications>
|
|
|
|
getTimelineMentions();
|
|
|
|
|
|
|
|
//! Retrieve all the user ids from a room.
|
|
|
|
std::vector<std::string>
|
|
|
|
roomMembers(const std::string &room_id);
|
|
|
|
|
|
|
|
//! Check if the given user has power leve greater than than
|
|
|
|
//! lowest power level of the given events.
|
|
|
|
bool
|
|
|
|
hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
|
|
|
|
const std::string &room_id,
|
|
|
|
const std::string &user_id);
|
|
|
|
|
|
|
|
//! Retrieves the saved room avatar.
|
|
|
|
QImage
|
|
|
|
getRoomAvatar(const QString &id);
|
|
|
|
QImage
|
|
|
|
getRoomAvatar(const std::string &id);
|
|
|
|
|
|
|
|
//! Adds a user to the read list for the given event.
|
|
|
|
//!
|
|
|
|
//! There should be only one user id present in a receipt list per room.
|
|
|
|
//! The user id should be removed from any other lists.
|
|
|
|
using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
|
|
|
|
void
|
|
|
|
updateReadReceipt(lmdb::txn &txn, const std::string &room_id, const Receipts &receipts);
|
|
|
|
|
|
|
|
//! Retrieve all the read receipts for the given event id and room.
|
|
|
|
//!
|
|
|
|
//! Returns a map of user ids and the time of the read receipt in milliseconds.
|
|
|
|
using UserReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>;
|
|
|
|
UserReceipts
|
|
|
|
readReceipts(const QString &event_id, const QString &room_id);
|
|
|
|
|
|
|
|
QByteArray
|
|
|
|
image(const QString &url);
|
|
|
|
QByteArray
|
|
|
|
image(lmdb::txn &txn, const std::string &url);
|
|
|
|
inline QByteArray
|
|
|
|
image(const std::string &url)
|
|
|
|
{
|
|
|
|
return image(QString::fromStdString(url));
|
|
|
|
}
|
|
|
|
void
|
|
|
|
saveImage(const std::string &url, const std::string &data);
|
|
|
|
void
|
|
|
|
saveImage(const QString &url, const QByteArray &data);
|
|
|
|
|
|
|
|
RoomInfo
|
|
|
|
singleRoomInfo(const std::string &room_id);
|
|
|
|
std::map<QString, RoomInfo>
|
|
|
|
getRoomInfo(const std::vector<std::string> &rooms);
|
2018-05-08 20:30:09 +03:00
|
|
|
|
2019-12-15 04:56:04 +03:00
|
|
|
//! Calculates which the read status of a room.
|
|
|
|
//! Whether all the events in the timeline have been read.
|
|
|
|
bool
|
|
|
|
calculateRoomReadStatus(const std::string &room_id);
|
2018-05-08 20:30:09 +03:00
|
|
|
void
|
2019-12-15 04:56:04 +03:00
|
|
|
calculateRoomReadStatus();
|
|
|
|
|
|
|
|
std::vector<RoomSearchResult>
|
|
|
|
searchRooms(const std::string &query, std::uint8_t max_items = 5);
|
|
|
|
|
|
|
|
void
|
|
|
|
markSentNotification(const std::string &event_id);
|
|
|
|
//! Removes an event from the sent notifications.
|
|
|
|
void
|
|
|
|
removeReadNotification(const std::string &event_id);
|
|
|
|
//! Check if we have sent a desktop notification for the given event id.
|
|
|
|
bool
|
|
|
|
isNotificationSent(const std::string &event_id);
|
|
|
|
|
|
|
|
//! Add all notifications containing a user mention to the db.
|
|
|
|
void
|
|
|
|
saveTimelineMentions(const mtx::responses::Notifications &res);
|
2018-05-08 20:30:09 +03:00
|
|
|
|
2019-12-15 04:56:04 +03:00
|
|
|
//! Remove old unused data.
|
|
|
|
void
|
|
|
|
deleteOldMessages();
|
|
|
|
void
|
|
|
|
deleteOldData() noexcept;
|
|
|
|
//! Retrieve all saved room ids.
|
|
|
|
std::vector<std::string>
|
|
|
|
getRoomIds(lmdb::txn &txn);
|
|
|
|
|
|
|
|
//! Mark a room that uses e2e encryption.
|
|
|
|
void
|
|
|
|
setEncryptedRoom(lmdb::txn &txn, const std::string &room_id);
|
|
|
|
bool
|
|
|
|
isRoomEncrypted(const std::string &room_id);
|
|
|
|
|
|
|
|
//! Check if a user is a member of the room.
|
|
|
|
bool
|
|
|
|
isRoomMember(const std::string &user_id, const std::string &room_id);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Outbound Megolm Sessions
|
|
|
|
//
|
|
|
|
void
|
|
|
|
saveOutboundMegolmSession(const std::string &room_id,
|
|
|
|
const OutboundGroupSessionData &data,
|
2020-11-30 02:26:27 +03:00
|
|
|
mtx::crypto::OutboundGroupSessionPtr &session);
|
2019-12-15 04:56:04 +03:00
|
|
|
OutboundGroupSessionDataRef
|
|
|
|
getOutboundMegolmSession(const std::string &room_id);
|
|
|
|
bool
|
|
|
|
outboundMegolmSessionExists(const std::string &room_id) noexcept;
|
|
|
|
void
|
2020-11-27 06:56:44 +03:00
|
|
|
updateOutboundMegolmSession(const std::string &room_id,
|
2020-11-30 02:26:27 +03:00
|
|
|
const OutboundGroupSessionData &data,
|
2020-11-27 06:56:44 +03:00
|
|
|
mtx::crypto::OutboundGroupSessionPtr &session);
|
2020-10-03 19:38:28 +03:00
|
|
|
void
|
|
|
|
dropOutboundMegolmSession(const std::string &room_id);
|
2019-12-15 04:56:04 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys);
|
|
|
|
mtx::crypto::ExportedSessionKeys
|
|
|
|
exportSessionKeys();
|
|
|
|
|
|
|
|
//
|
|
|
|
// Inbound Megolm Sessions
|
|
|
|
//
|
|
|
|
void
|
|
|
|
saveInboundMegolmSession(const MegolmSessionIndex &index,
|
|
|
|
mtx::crypto::InboundGroupSessionPtr session);
|
2020-11-27 06:19:03 +03:00
|
|
|
mtx::crypto::InboundGroupSessionPtr
|
2019-12-15 04:56:04 +03:00
|
|
|
getInboundMegolmSession(const MegolmSessionIndex &index);
|
|
|
|
bool
|
|
|
|
inboundMegolmSessionExists(const MegolmSessionIndex &index);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Olm Sessions
|
|
|
|
//
|
|
|
|
void
|
2020-10-20 14:46:05 +03:00
|
|
|
saveOlmSession(const std::string &curve25519,
|
|
|
|
mtx::crypto::OlmSessionPtr session,
|
|
|
|
uint64_t timestamp);
|
2019-12-15 04:56:04 +03:00
|
|
|
std::vector<std::string>
|
|
|
|
getOlmSessions(const std::string &curve25519);
|
|
|
|
std::optional<mtx::crypto::OlmSessionPtr>
|
|
|
|
getOlmSession(const std::string &curve25519, const std::string &session_id);
|
2020-10-20 14:46:05 +03:00
|
|
|
std::optional<mtx::crypto::OlmSessionPtr>
|
|
|
|
getLatestOlmSession(const std::string &curve25519);
|
2019-12-15 04:56:04 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
saveOlmAccount(const std::string &pickled);
|
2020-11-27 06:56:44 +03:00
|
|
|
|
2019-12-15 04:56:04 +03:00
|
|
|
std::string
|
|
|
|
restoreOlmAccount();
|
2020-12-17 00:10:09 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
storeSecret(const std::string &name, const std::string &secret);
|
|
|
|
std::optional<std::string>
|
|
|
|
secret(const std::string &name);
|
2018-05-08 20:30:09 +03:00
|
|
|
}
|