File indexing completed on 2024-11-10 04:32:41

0001 /*
0002    SPDX-FileCopyrightText: 2017-2024 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
0256 RocketChatMessage::inputChannelAutocomplete(const QString &roomId, const QString &pattern, const QString &exceptions, quint64 id)
0257 {
0258     return searchRoomUsers(roomId, pattern, exceptions, false, true, id);
0259 }
0260 
0261 RocketChatMessage::RocketChatMessageResult
0262 RocketChatMessage::inputUserAutocomplete(const QString &roomId, const QString &pattern, const QString &exceptions, quint64 id)
0263 {
0264     return searchRoomUsers(roomId, pattern, exceptions, true, false, id);
0265 }
0266 
0267 RocketChatMessage::RocketChatMessageResult
0268 RocketChatMessage::searchRoomUsers(const QString &roomId, const QString &pattern, const QString &exceptions, bool searchUser, bool searchRoom, quint64 id)
0269 {
0270     QJsonArray params;
0271     params.append(pattern);
0272 
0273     const QJsonArray exceptionJson = QJsonArray::fromStringList(exceptions.split(QLatin1Char(',')));
0274     params.append(std::move(exceptionJson));
0275 
0276     QJsonObject secondParams;
0277     if (searchRoom) {
0278         secondParams[QLatin1String("rooms")] = searchRoom;
0279     }
0280     if (searchUser) {
0281         secondParams[QLatin1String("users")] = searchUser;
0282     }
0283     secondParams[QLatin1String("mentions")] = true;
0284     params.append(std::move(secondParams));
0285     if (!roomId.isEmpty()) {
0286         params.append(roomId);
0287     }
0288     return generateMethod(QStringLiteral("spotlight"), QJsonDocument(params), id);
0289 }
0290 
0291 // Verify
0292 RocketChatMessage::RocketChatMessageResult RocketChatMessage::unsubscribe(quint64 id)
0293 {
0294     QJsonObject json;
0295     json[QLatin1String("msg")] = QStringLiteral("unsub");
0296     json[QLatin1String("id")] = QString::number(id);
0297     const QString generatedJsonDoc = QString::fromUtf8(QJsonDocument(json).toJson(mJsonFormat));
0298     RocketChatMessageResult result;
0299     result.result = generatedJsonDoc;
0300     return result;
0301 }
0302 
0303 RocketChatMessage::RocketChatMessageResult RocketChatMessage::subscribe(const QString &name, const QJsonDocument &params, quint64 id)
0304 {
0305     // TODO fixme.
0306     QJsonObject json;
0307     json[QLatin1String("msg")] = QStringLiteral("sub");
0308     json[QLatin1String("id")] = QString::number(id);
0309     json[QLatin1String("name")] = name;
0310     if (params.isArray()) {
0311         json[QLatin1String("params")] = params.array();
0312     } else if (params.isObject()) {
0313         QJsonArray arr;
0314         arr.append(params.object());
0315         json[QLatin1String("params")] = arr;
0316     }
0317 
0318     const QString generatedJsonDoc = QString::fromUtf8(QJsonDocument(json).toJson(mJsonFormat));
0319     RocketChatMessageResult result;
0320     result.jsonDocument = params;
0321     result.method = name;
0322     result.result = generatedJsonDoc;
0323     return result;
0324 }
0325 
0326 RocketChatMessage::RocketChatMessageResult RocketChatMessage::generateMethod(const QString &method, const QJsonDocument &params, quint64 id)
0327 {
0328     QJsonObject json;
0329     json[QLatin1String("msg")] = QStringLiteral("method");
0330     json[QLatin1String("method")] = method;
0331     json[QLatin1String("id")] = QString::number(id);
0332 
0333     if (!params.isEmpty()) {
0334         if (params.isArray()) {
0335             json[QLatin1String("params")] = params.array();
0336         } else if (params.isObject()) {
0337             QJsonArray arr;
0338             arr.append(params.object());
0339             json[QLatin1String("params")] = arr;
0340         }
0341     }
0342     const QString generatedJsonDoc = QString::fromUtf8(QJsonDocument(json).toJson(mJsonFormat));
0343     RocketChatMessageResult result;
0344     result.jsonDocument = params;
0345     result.method = method;
0346     result.result = generatedJsonDoc;
0347     return result;
0348 }
0349 
0350 RocketChatMessage::RocketChatMessageResult RocketChatMessage::streamNotifyUserOtrEnd(const QString &roomId, const QString &userId, quint64 id)
0351 {
0352     const QJsonObject endObject{{QStringLiteral("roomId"), roomId}, {QStringLiteral("userId"), userId}};
0353     QString otrId = roomId;
0354     otrId = otrId.remove(userId);
0355     const QJsonArray params{QStringLiteral("%1/otr").arg(otrId), QStringLiteral("end"), endObject};
0356     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0357 }
0358 
0359 RocketChatMessage::RocketChatMessageResult RocketChatMessage::enable2fa(quint64 id)
0360 {
0361     const QJsonArray params;
0362     return generateMethod(QStringLiteral("2fa:enable"), QJsonDocument(params), id);
0363 }
0364 
0365 RocketChatMessage::RocketChatMessageResult RocketChatMessage::disable2fa(const QString &code, quint64 id)
0366 {
0367     const QJsonArray params{code};
0368     return generateMethod(QStringLiteral("2fa:disable"), QJsonDocument(params), id);
0369 }
0370 
0371 RocketChatMessage::RocketChatMessageResult RocketChatMessage::regenerateCodes2fa(const QString &code, quint64 id)
0372 {
0373     const QJsonArray params{code};
0374     return generateMethod(QStringLiteral("2fa:regenerateCodes"), QJsonDocument(params), id);
0375 }
0376 
0377 RocketChatMessage::RocketChatMessageResult RocketChatMessage::validateTempToken2fa(const QString &code, quint64 id)
0378 {
0379     const QJsonArray params{code};
0380     return generateMethod(QStringLiteral("2fa:validateTempToken"), QJsonDocument(params), id);
0381 }
0382 
0383 RocketChatMessage::RocketChatMessageResult
0384 RocketChatMessage::streamNotifyUserOtrHandshake(const QString &userFrom, const QString &userTo, const QString &publicKeys, quint64 id)
0385 {
0386     const QJsonObject endObject{{QStringLiteral("roomId"), QStringLiteral("%1%2").arg(userTo, userFrom)},
0387                                 {QStringLiteral("userId"), userTo},
0388                                 {QStringLiteral("publicKey"), publicKeys}};
0389     const QJsonArray params{QStringLiteral("%1/otr").arg(userFrom), QStringLiteral("handshake"), endObject};
0390     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0391 }
0392 
0393 RocketChatMessage::RocketChatMessageResult
0394 RocketChatMessage::streamNotifyUserOtrAcknowledge(const QString &roomId, const QString &userId, const QString &publicKeys, quint64 id)
0395 {
0396     const QJsonObject acknowledgeObject{{QStringLiteral("roomId"), roomId}, {QStringLiteral("userId"), userId}, {QStringLiteral("publicKey"), publicKeys}};
0397     QString otrId = roomId;
0398     otrId = otrId.remove(userId);
0399     const QJsonArray params{QStringLiteral("%1/otr").arg(otrId), QStringLiteral("acknowledge"), acknowledgeObject};
0400     return generateMethod(QStringLiteral("stream-notify-user"), QJsonDocument(params), id);
0401 #if 0
0402     {\"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\"}]}"
0403     {\"id\":\"30\",\"method\":\"stream-notify-user\",\"msg\":\"method\",\"params\":[\"4faACeGzSvG7xMcTy/otr\",\"acknowledge\",{\"publicKey\":\"{}\",\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB4faACeGzSvG7xMcTy\",\"userId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\"}]}
0404     {\"msg\":\"method\",\"id\":\"22\",\"method\":\"stream-notify-user\",\"params\":[\"YbwG4T2uB3wZSZSKB/otr\",\"acknowledge\",{\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\",\"userId\":\"4faACeGzSvG7xMcTy\",\"publicKey\":\"{
0405 #endif
0406 }
0407 
0408 QDebug operator<<(QDebug d, const RocketChatMessage::RocketChatMessageResult &t)
0409 {
0410     d << "json: " << t.jsonDocument;
0411     d << "method: " << t.method;
0412     d << "result: " << t.result;
0413     return d;
0414 }
0415 
0416 #include "moc_rocketchatmessage.cpp"