1// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4
5#pragma once
6
7#include <Quotient/converters.h>
8
9#include <array>
10
11namespace Quotient {
12/**
13 * JSON Web Key object as specified in
14 * https://spec.matrix.org/unstable/client-server-api/#extensions-to-mroommessage-msgtypes
15 * The only currently relevant member is `k`, the rest needs to be set to the defaults specified in the spec.
16 */
17struct JWK
18{
19 Q_GADGET
20 Q_PROPERTY(QString kty MEMBER kty CONSTANT)
21 Q_PROPERTY(QStringList keyOps MEMBER keyOps CONSTANT)
22 Q_PROPERTY(QString alg MEMBER alg CONSTANT)
23 Q_PROPERTY(QString k MEMBER k CONSTANT)
24 Q_PROPERTY(bool ext MEMBER ext CONSTANT)
25
26public:
27 QString kty;
28 QStringList keyOps;
29 QString alg;
30 QString k;
31 bool ext;
32};
33
34struct QUOTIENT_API EncryptedFileMetadata {
35 Q_GADGET
36 Q_PROPERTY(QUrl url MEMBER url CONSTANT)
37 Q_PROPERTY(JWK key MEMBER key CONSTANT)
38 Q_PROPERTY(QString iv MEMBER iv CONSTANT)
39 Q_PROPERTY(QHash<QString, QString> hashes MEMBER hashes CONSTANT)
40 Q_PROPERTY(QString v MEMBER v CONSTANT)
41 Q_PROPERTY(bool isValid READ isValid CONSTANT)
42
43public:
44 QUrl url;
45 JWK key;
46 QString iv;
47 QHash<QString, QString> hashes;
48 QString v;
49
50 bool isValid() const { return url.isValid(); }
51};
52
53#ifdef Quotient_E2EE_ENABLED
54QUOTIENT_API std::pair<EncryptedFileMetadata, QByteArray> encryptFile(
55 const QByteArray& plainText);
56QUOTIENT_API QByteArray decryptFile(const QByteArray& ciphertext,
57 const EncryptedFileMetadata& metadata);
58#endif
59
60template <>
61struct QUOTIENT_API JsonObjectConverter<EncryptedFileMetadata> {
62 static void dumpTo(QJsonObject& jo, const EncryptedFileMetadata& pod);
63 static void fillFrom(const QJsonObject& jo, EncryptedFileMetadata& pod);
64};
65
66template <>
67struct QUOTIENT_API JsonObjectConverter<JWK> {
68 static void dumpTo(QJsonObject& jo, const JWK& pod);
69 static void fillFrom(const QJsonObject& jo, JWK& pod);
70};
71
72using FileSourceInfo = std::variant<QUrl, EncryptedFileMetadata>;
73
74QUOTIENT_API QUrl getUrlFromSourceInfo(const FileSourceInfo& fsi);
75
76QUOTIENT_API void setUrlInSourceInfo(FileSourceInfo& fsi, const QUrl& newUrl);
77
78// The way FileSourceInfo is stored in JSON requires an extra parameter so
79// the original template is not applicable
80template <>
81void fillJson(QJsonObject&, const FileSourceInfo&) = delete;
82
83//! \brief Export FileSourceInfo to a JSON object
84//!
85//! Depending on what is stored inside FileSourceInfo, this function will insert
86//! - a key-to-string pair where key is taken from jsonKeys[0] and the string
87//! is the URL, if FileSourceInfo stores a QUrl;
88//! - a key-to-object mapping where key is taken from jsonKeys[1] and the object
89//! is the result of converting EncryptedFileMetadata to JSON,
90//! if FileSourceInfo stores EncryptedFileMetadata
91QUOTIENT_API void fillJson(QJsonObject& jo,
92 const std::array<QLatin1String, 2>& jsonKeys,
93 const FileSourceInfo& fsi);
94
95namespace FileMetadataMap {
96 QUOTIENT_API void add(const QString& roomId,
97 const QString& eventId,
98 const EncryptedFileMetadata& fileMetadata);
99 QUOTIENT_API void remove(const QString& roomId,
100 const QString& eventId);
101
102 //! \brief Obtain file source information across connections, thread-safely
103 //! \return the previously saved EncryptedFileMetadata object, or an invalid
104 //! (default-constructed) object in case of unsuccessful lookup
105 QUOTIENT_API EncryptedFileMetadata lookup(const QString& roomId,
106 const QString& eventId);
107}
108
109} // namespace Quotient
110