File indexing completed on 2023-11-26 08:17:53

0001 /*
0002    SPDX-FileCopyrightText: 2017-2023 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "rocketchatmessage.h"
0008 #include "ruqola_debug.h"
0009 #include "utils.h"
0010 
0011 #include <QCryptographicHash>
0012 #include <QDateTime>
0013 #include <QJsonArray>
0014 #include <QJsonObject>
0015 
0016 RocketChatMessage::RocketChatMessage() = default;
0017 
0018 void RocketChatMessage::setJsonFormat(QJsonDocument::JsonFormat jsonFormat)
0019 {
0020     mJsonFormat = jsonFormat;
0021 }
0022 
0023 RocketChatMessage::RocketChatMessageResult RocketChatMessage::openDirectChannel(const QString &username, quint64 id)
0024 {
0025     const QJsonArray params{QJsonValue(username)};
0026     return generateMethod(QStringLiteral("createDirectMessage"), QJsonDocument(params), id);
0027 }
0028 
0029 RocketChatMessage::RocketChatMessageResult RocketChatMessage::setRoomEncrypted(const QString &roomId, bool encrypted, quint64 id)
0030 {
0031     return saveRoomSettings(QStringLiteral("encrypted"), roomId, encrypted, id);
0032 }
0033 
0034 RocketChatMessage::RocketChatMessageResult RocketChatMessage::updateOAuthApp(const QString &name, bool active, const QString &redirectUrl, quint64 id)
0035 {
0036     QJsonObject obj{
0037         {QStringLiteral("name"), name},
0038         {QStringLiteral("active"), active},
0039         {QStringLiteral("redirectUri"), redirectUrl},
0040     };
0041     const QJsonArray params{obj};
0042     return generateMethod(QStringLiteral("updateOAuthApp"), QJsonDocument(params), id);
0043 }
0044 
0045 RocketChatMessage::RocketChatMessageResult RocketChatMessage::addOAuthApp(const QString &name, bool active, const QString &redirectUrl, quint64 id)
0046 {
0047     QJsonObject obj{
0048         {QStringLiteral("name"), name},
0049         {QStringLiteral("active"), active},
0050         {QStringLiteral("redirectUri"), redirectUrl},
0051     };
0052     const QJsonArray params{obj};
0053     return generateMethod(QStringLiteral("addOAuthApp"), QJsonDocument(params), id);
0054 }
0055 
0056 RocketChatMessage::RocketChatMessageResult RocketChatMessage::deleteOAuthApp(const QString &appId, quint64 id)
0057 {
0058     const QJsonArray params{{appId}};
0059     qDebug() << " DELETE " << appId;
0060     return generateMethod(QStringLiteral("deleteOAuthApp"), QJsonDocument(params), id);
0061 }
0062 
0063 RocketChatMessage::RocketChatMessageResult
0064 RocketChatMessage::videoConferenceConfirmed(const QString &roomId, const QString &callId, const QString &userId, quint64 id)
0065 {
0066     return generateVideoConferenceAction(QStringLiteral("confirmed"), roomId, callId, userId, id);
0067 }
0068 
0069 RocketChatMessage::RocketChatMessageResult
0070 RocketChatMessage::videoConferenceRejected(const QString &roomId, const QString &callId, const QString &userId, quint64 id)
0071 {
0072     return generateVideoConferenceAction(QStringLiteral("rejected"), roomId, callId, userId, id);
0073 }
0074 
0075 RocketChatMessage::RocketChatMessageResult
0076 RocketChatMessage::videoConferenceCall(const QString &roomId, const QString &callId, const QString &userId, quint64 id)
0077 {
0078     return generateVideoConferenceAction(QStringLiteral("call"), roomId, callId, userId, id);
0079 }
0080 
0081 RocketChatMessage::RocketChatMessageResult
0082 RocketChatMessage::videoConferenceAccepted(const QString &roomId, const QString &callId, const QString &userId, quint64 id)
0083 {
0084     return generateVideoConferenceAction(QStringLiteral("accepted"), roomId, callId, userId, id);
0085 }
0086 
0087 RocketChatMessage::RocketChatMessageResult
0088 RocketChatMessage::generateVideoConferenceAction(const QString &action, const QString &roomId, const QString &callId, const QString &userId, quint64 id)
0089 {
0090     QJsonObject actionParamsObj{
0091         {QStringLiteral("callId"), callId},
0092         {QStringLiteral("uid"), userId},
0093         {QStringLiteral("rid"), roomId},
0094     };
0095     QJsonObject actionObj{
0096         {QStringLiteral("action"), action},
0097         {QStringLiteral("params"), actionParamsObj},
0098     };
0099 
0100     QString videoConferenceId = roomId;
0101     videoConferenceId.remove(userId);
0102     const QJsonArray params{QStringLiteral("%1/video-conference").arg(videoConferenceId), actionObj};
0103     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0104 }
0105 
0106 RocketChatMessage::RocketChatMessageResult RocketChatMessage::licenseGetModules(quint64 id)
0107 {
0108     const QJsonArray params{{}};
0109     return generateMethod(QStringLiteral("license:getModules"), QJsonDocument(params), id);
0110 }
0111 
0112 RocketChatMessage::RocketChatMessageResult RocketChatMessage::bannerDismiss(const QString &bannerId, quint64 id)
0113 {
0114     QJsonObject obj{
0115         {QStringLiteral("id"), bannerId},
0116     };
0117 
0118     const QJsonArray params{obj};
0119     return generateMethod(QStringLiteral("banner/dismiss"), QJsonDocument(params), id);
0120 }
0121 
0122 RocketChatMessage::RocketChatMessageResult RocketChatMessage::blockUser(const QString &rid, const QString &userId, quint64 id)
0123 {
0124     QJsonObject obj{
0125         {QStringLiteral("rid"), rid},
0126         {QStringLiteral("blocked"), userId},
0127     };
0128     const QJsonArray params{{obj}};
0129 
0130     return generateMethod(QStringLiteral("blockUser"), QJsonDocument(params), id);
0131 }
0132 
0133 RocketChatMessage::RocketChatMessageResult RocketChatMessage::setAdminStatus(const QString &userId, bool admin, quint64 id)
0134 {
0135     const QJsonArray params{{userId}, {admin}};
0136     return generateMethod(QStringLiteral("setAdminStatus"), QJsonDocument(params), id);
0137 }
0138 
0139 RocketChatMessage::RocketChatMessageResult RocketChatMessage::uploadCustomSound(const QByteArray &sound, quint64 id)
0140 {
0141     // TODO fix me
0142     const QJsonArray params{{}};
0143 
0144     return generateMethod(QStringLiteral("uploadCustomSound"), QJsonDocument(params), id);
0145 }
0146 
0147 RocketChatMessage::RocketChatMessageResult RocketChatMessage::deleteCustomSound(const QString &identifier, quint64 id)
0148 {
0149     const QJsonArray params{{identifier}};
0150 
0151     return generateMethod(QStringLiteral("deleteCustomSound"), QJsonDocument(params), id);
0152 }
0153 
0154 RocketChatMessage::RocketChatMessageResult RocketChatMessage::listCustomSounds(quint64 id)
0155 {
0156     const QJsonArray params{{}};
0157 
0158     return generateMethod(QStringLiteral("listCustomSounds"), QJsonDocument(params), id);
0159 }
0160 
0161 RocketChatMessage::RocketChatMessageResult RocketChatMessage::unblockUser(const QString &rid, const QString &userId, quint64 id)
0162 {
0163     QJsonObject obj{
0164         {QStringLiteral("rid"), rid},
0165         {QStringLiteral("blocked"), userId},
0166     };
0167     const QJsonArray params{{obj}};
0168 
0169     return generateMethod(QStringLiteral("unblockUser"), QJsonDocument(params), id);
0170 }
0171 
0172 RocketChatMessage::RocketChatMessageResult RocketChatMessage::saveRoomSettings(const QString &key, const QString &roomId, const QJsonValue &value, quint64 id)
0173 {
0174     const QJsonArray params{{roomId}, {key}, {value}};
0175     return generateMethod(QStringLiteral("saveRoomSettings"), QJsonDocument(params), id);
0176 }
0177 
0178 RocketChatMessage::RocketChatMessageResult RocketChatMessage::joinRoom(const QString &roomId, const QString &accessCode, quint64 id)
0179 {
0180     const QJsonArray params{{roomId}, {accessCode}};
0181     return generateMethod(QStringLiteral("joinRoom"), QJsonDocument(params), id);
0182 }
0183 
0184 RocketChatMessage::RocketChatMessageResult RocketChatMessage::getRoomById(const QString &roomId, quint64 id)
0185 {
0186     const QJsonArray params{{roomId}};
0187     return generateMethod(QStringLiteral("getRoomById"), QJsonDocument(params), id);
0188 }
0189 
0190 RocketChatMessage::RocketChatMessageResult RocketChatMessage::openRoom(const QString &roomId, quint64 id)
0191 {
0192     const QJsonArray params{{roomId}};
0193     return generateMethod(QStringLiteral("openRoom"), QJsonDocument(params), id);
0194 }
0195 
0196 // Verify
0197 RocketChatMessage::RocketChatMessageResult RocketChatMessage::deleteFileMessage(const QString &fileId, quint64 id)
0198 {
0199     const QJsonArray params{{fileId}};
0200     return generateMethod(QStringLiteral("deleteFileMessage"), QJsonDocument(params), id);
0201 }
0202 
0203 RocketChatMessage::RocketChatMessageResult RocketChatMessage::informTypingStatus(const QString &roomId, const QString &userId, bool typingStatus, quint64 id)
0204 {
0205     const QString eventName = roomId + QStringLiteral("/user-activity");
0206     const QJsonArray params{{eventName}, {userId}, {typingStatus}};
0207     return generateMethod(QStringLiteral("stream-notify-room"), QJsonDocument(params), id);
0208 }
0209 
0210 QJsonValue RocketChatMessage::toJsonDateTime(const QDateTime &dateTime)
0211 {
0212     if (dateTime.isNull()) {
0213         return {};
0214     }
0215 
0216     return QJsonObject{{QStringLiteral("$date"), dateTime.toMSecsSinceEpoch()}};
0217 }
0218 
0219 RocketChatMessage::RocketChatMessageResult RocketChatMessage::setDefaultStatus(User::PresenceStatus status, quint64 id)
0220 {
0221     const QString strPresence = Utils::presenceStatusToString(status);
0222     const QJsonArray params{{strPresence}};
0223     return generateMethod(QStringLiteral("UserPresence:setDefaultStatus"), QJsonDocument(params), id);
0224 }
0225 
0226 RocketChatMessage::RocketChatMessageResult RocketChatMessage::roomNameExists(const QString &roomName, quint64 id)
0227 {
0228     const QJsonArray params{{QJsonValue(roomName)}};
0229     return generateMethod(QStringLiteral("roomNameExists"), QJsonDocument(params), id);
0230 }
0231 
0232 RocketChatMessage::RocketChatMessageResult RocketChatMessage::createJitsiConfCall(const QString &roomId, quint64 id)
0233 {
0234     const QJsonArray params{{QJsonValue(roomId)}};
0235     return generateMethod(QStringLiteral("jitsi:updateTimeout"), QJsonDocument(params), id);
0236 }
0237 
0238 RocketChatMessage::RocketChatMessageResult RocketChatMessage::userAutocomplete(const QString &searchText, const QString &exception, quint64 id)
0239 {
0240     QJsonArray params;
0241 
0242     QJsonObject firstParam;
0243 
0244     const QStringList users = exception.split(QLatin1Char(','));
0245     QJsonArray exceptionEntries;
0246     for (const QString &entry : users) {
0247         exceptionEntries.append(entry);
0248     }
0249     firstParam[QLatin1String("exceptions")] = exceptionEntries;
0250     firstParam[QLatin1String("term")] = searchText;
0251     params.append(std::move(firstParam));
0252     return subscribe(QStringLiteral("userAutocomplete"), QJsonDocument(params), id);
0253 }
0254 
0255 RocketChatMessage::RocketChatMessageResult RocketChatMessage::inputChannelAutocomplete(const QString &pattern, const QString &exceptions, quint64 id)
0256 {
0257     return searchRoomUsers(pattern, exceptions, false, true, id);
0258 }
0259 
0260 RocketChatMessage::RocketChatMessageResult RocketChatMessage::inputUserAutocomplete(const QString &pattern, const QString &exceptions, quint64 id)
0261 {
0262     return searchRoomUsers(pattern, exceptions, true, false, id);
0263 }
0264 
0265 RocketChatMessage::RocketChatMessageResult
0266 RocketChatMessage::searchRoomUsers(const QString &pattern, const QString &exceptions, bool searchUser, bool searchRoom, quint64 id)
0267 {
0268     QJsonArray params;
0269     params.append(pattern);
0270 
0271     const QJsonArray exceptionJson = QJsonArray::fromStringList(exceptions.split(QLatin1Char(',')));
0272     params.append(std::move(exceptionJson));
0273 
0274     QJsonObject secondParams;
0275     secondParams[QLatin1String("rooms")] = searchRoom;
0276     secondParams[QLatin1String("users")] = searchUser;
0277     params.append(std::move(secondParams));
0278     return generateMethod(QStringLiteral("spotlight"), QJsonDocument(params), id);
0279 }
0280 
0281 // Verify
0282 RocketChatMessage::RocketChatMessageResult RocketChatMessage::unsubscribe(quint64 id)
0283 {
0284     QJsonObject json;
0285     json[QLatin1String("msg")] = QStringLiteral("unsub");
0286     json[QLatin1String("id")] = QString::number(id);
0287     const QString generatedJsonDoc = QString::fromUtf8(QJsonDocument(json).toJson(mJsonFormat));
0288     RocketChatMessageResult result;
0289     result.result = generatedJsonDoc;
0290     return result;
0291 }
0292 
0293 RocketChatMessage::RocketChatMessageResult RocketChatMessage::subscribe(const QString &name, const QJsonDocument &params, quint64 id)
0294 {
0295     // TODO fixme.
0296     QJsonObject json;
0297     json[QLatin1String("msg")] = QStringLiteral("sub");
0298     json[QLatin1String("id")] = QString::number(id);
0299     json[QLatin1String("name")] = name;
0300     if (params.isArray()) {
0301         json[QLatin1String("params")] = params.array();
0302     } else if (params.isObject()) {
0303         QJsonArray arr;
0304         arr.append(params.object());
0305         json[QLatin1String("params")] = arr;
0306     }
0307 
0308     const QString generatedJsonDoc = QString::fromUtf8(QJsonDocument(json).toJson(mJsonFormat));
0309     RocketChatMessageResult result;
0310     result.jsonDocument = params;
0311     result.method = name;
0312     result.result = generatedJsonDoc;
0313     return result;
0314 }
0315 
0316 RocketChatMessage::RocketChatMessageResult RocketChatMessage::generateMethod(const QString &method, const QJsonDocument &params, quint64 id)
0317 {
0318     QJsonObject json;
0319     json[QLatin1String("msg")] = QStringLiteral("method");
0320     json[QLatin1String("method")] = method;
0321     json[QLatin1String("id")] = QString::number(id);
0322 
0323     if (!params.isEmpty()) {
0324         if (params.isArray()) {
0325             json[QLatin1String("params")] = params.array();
0326         } else if (params.isObject()) {
0327             QJsonArray arr;
0328             arr.append(params.object());
0329             json[QLatin1String("params")] = arr;
0330         }
0331     }
0332     const QString generatedJsonDoc = QString::fromUtf8(QJsonDocument(json).toJson(mJsonFormat));
0333     RocketChatMessageResult result;
0334     result.jsonDocument = params;
0335     result.method = method;
0336     result.result = generatedJsonDoc;
0337     return result;
0338 }
0339 
0340 RocketChatMessage::RocketChatMessageResult RocketChatMessage::streamNotifyUserOtrEnd(const QString &roomId, const QString &userId, quint64 id)
0341 {
0342     const QJsonObject endObject{{QStringLiteral("roomId"), roomId}, {QStringLiteral("userId"), userId}};
0343     QString otrId = roomId;
0344     otrId = otrId.remove(userId);
0345     const QJsonArray params{QStringLiteral("%1/otr").arg(otrId), QStringLiteral("end"), endObject};
0346     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0347 }
0348 
0349 RocketChatMessage::RocketChatMessageResult RocketChatMessage::enable2fa(quint64 id)
0350 {
0351     const QJsonArray params;
0352     return generateMethod(QStringLiteral("2fa:enable"), QJsonDocument(params), id);
0353 }
0354 
0355 RocketChatMessage::RocketChatMessageResult RocketChatMessage::disable2fa(const QString &code, quint64 id)
0356 {
0357     const QJsonArray params{code};
0358     return generateMethod(QStringLiteral("2fa:disable"), QJsonDocument(params), id);
0359 }
0360 
0361 RocketChatMessage::RocketChatMessageResult RocketChatMessage::regenerateCodes2fa(const QString &code, quint64 id)
0362 {
0363     const QJsonArray params{code};
0364     return generateMethod(QStringLiteral("2fa:regenerateCodes"), QJsonDocument(params), id);
0365 }
0366 
0367 RocketChatMessage::RocketChatMessageResult RocketChatMessage::validateTempToken2fa(const QString &code, quint64 id)
0368 {
0369     const QJsonArray params{code};
0370     return generateMethod(QStringLiteral("2fa:validateTempToken"), QJsonDocument(params), id);
0371 }
0372 
0373 RocketChatMessage::RocketChatMessageResult
0374 RocketChatMessage::streamNotifyUserOtrHandshake(const QString &userFrom, const QString &userTo, const QString &publicKeys, quint64 id)
0375 {
0376     const QJsonObject endObject{{QStringLiteral("roomId"), QStringLiteral("%1%2").arg(userTo, userFrom)},
0377                                 {QStringLiteral("userId"), userTo},
0378                                 {QStringLiteral("publicKey"), publicKeys}};
0379     const QJsonArray params{QStringLiteral("%1/otr").arg(userFrom), QStringLiteral("handshake"), endObject};
0380     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0381 }
0382 
0383 RocketChatMessage::RocketChatMessageResult
0384 RocketChatMessage::streamNotifyUserOtrAcknowledge(const QString &roomId, const QString &userId, const QString &publicKeys, quint64 id)
0385 {
0386     const QJsonObject acknowledgeObject{{QStringLiteral("roomId"), roomId}, {QStringLiteral("userId"), userId}, {QStringLiteral("publicKey"), publicKeys}};
0387     QString otrId = roomId;
0388     otrId = otrId.remove(userId);
0389     const QJsonArray params{QStringLiteral("%1/otr").arg(otrId), QStringLiteral("acknowledge"), acknowledgeObject};
0390     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0391 #if 0
0392     {\"id\":\"30\",\"method\":\"stream-notify-user\",\"msg\":\"method\",\"params\":[\"4faACeGzSvG7xMcTy/otr\",\"acknowledge\",{\"publicKey\":\"{\\\"crv\\\":\\\"P-256\\\",\\\"ext\\\":true,\\\"key_ops\\\":[],\\\"kty\\\":\\\"EC\\\",\\\"x\\\":\\\"Jg7HgVygchsJSpGc1N36I7-4xlIF2Y4kBB0cKoT5rW8\\\",\\\"y\\\":\\\"rhdmHfXGihoZI0eBL1lADOm3FGrQ3qO6y2rXuV9YNC8\\\"}\",\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\",\"userId\":\"4faACeGzSvG7xMcTy\"}]}"
0393     {\"id\":\"30\",\"method\":\"stream-notify-user\",\"msg\":\"method\",\"params\":[\"4faACeGzSvG7xMcTy/otr\",\"acknowledge\",{\"publicKey\":\"{}\",\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB4faACeGzSvG7xMcTy\",\"userId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\"}]}
0394     {\"msg\":\"method\",\"id\":\"22\",\"method\":\"stream-notify-user\",\"params\":[\"YbwG4T2uB3wZSZSKB/otr\",\"acknowledge\",{\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\",\"userId\":\"4faACeGzSvG7xMcTy\",\"publicKey\":\"{
0395 #endif
0396 }
0397 
0398 QDebug operator<<(QDebug d, const RocketChatMessage::RocketChatMessageResult &t)
0399 {
0400     d << "json: " << t.jsonDocument;
0401     d << "method: " << t.method;
0402     d << "result: " << t.result;
0403     return d;
0404 }
0405 
0406 #include "moc_rocketchatmessage.cpp"