1// SPDX-FileCopyrightText: 2019 Alexey Andreyev <aa13q@ya.ru>
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#pragma once
5
6#include "roomevent.h"
7
8namespace Quotient {
9
10constexpr inline auto CiphertextKey = "ciphertext"_ls;
11constexpr inline auto SenderKeyKey = "sender_key"_ls;
12constexpr inline auto DeviceIdKey = "device_id"_ls;
13constexpr inline auto SessionIdKey = "session_id"_ls;
14
15/*
16 * While the specification states:
17 *
18 * "This event type is used when sending encrypted events.
19 * It can be used either within a room
20 * (in which case it will have all of the Room Event fields),
21 * or as a to-device event."
22 * "The encrypted payload can contain any message event."
23 * https://matrix.org/docs/spec/client_server/latest#id493
24 *
25 * -- for most of the cases the message event is the room message event.
26 * And even for the to-device events the context is for the room.
27 *
28 * So, to simplify integration to the timeline, EncryptedEvent is a RoomEvent
29 * inheritor. Strictly speaking though, it's not always a RoomEvent, but an Event
30 * in general. It's possible, because RoomEvent interface is similar to Event's
31 * one and doesn't add new restrictions, just provides additional features.
32 */
33class QUOTIENT_API EncryptedEvent : public RoomEvent {
34public:
35 QUO_EVENT(EncryptedEvent, "m.room.encrypted")
36
37 /* In case with Olm, the encrypted content of the event is
38 * a map from the recipient Curve25519 identity key to ciphertext
39 * information */
40 explicit EncryptedEvent(const QJsonObject& ciphertexts,
41 const QString& senderKey);
42 /* In case with Megolm, device_id and session_id are required */
43 explicit EncryptedEvent(const QByteArray& ciphertext,
44 const QString& senderKey, const QString& deviceId,
45 const QString& sessionId);
46 // TODO: replace with 'using RoomEvent::RoomEvent' in 0.8
47 explicit EncryptedEvent(const QJsonObject& obj);
48
49 QString algorithm() const;
50 QByteArray ciphertext() const
51 {
52 return contentPart<QString>(key: CiphertextKey).toLatin1();
53 }
54 QJsonObject ciphertext(const QString& identityKey) const
55 {
56 return contentPart<QJsonObject>(key: CiphertextKey)
57 .value(key: identityKey)
58 .toObject();
59 }
60 QString senderKey() const { return contentPart<QString>(key: SenderKeyKey); }
61
62 /* device_id and session_id are required with Megolm */
63 QString deviceId() const { return contentPart<QString>(key: DeviceIdKey); }
64 QString sessionId() const { return contentPart<QString>(key: SessionIdKey); }
65 RoomEventPtr createDecrypted(const QString &decrypted) const;
66
67 void setRelation(const QJsonObject& relation);
68};
69
70class QUOTIENT_API DummyEvent : public Event {
71public:
72 QUO_EVENT(DummyEvent, "m.dummy")
73 using Event::Event;
74 explicit DummyEvent()
75 : Event(basicJson(matrixType: TypeId, content: {}))
76 {}
77};
78} // namespace Quotient
79