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 ¶ms, 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 ¶ms, 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"