File indexing completed on 2024-12-08 04:33:09
0001 /* 0002 0003 * SPDX-FileCopyrightText: 2016 Riccardo Iaconelli <riccardo@kde.org> 0004 * SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.0-or-later 0007 * 0008 */ 0009 0010 #include "ddpclient.h" 0011 #include "messagequeue.h" 0012 #include "plugins/pluginauthenticationinterface.h" 0013 #include "rocketchataccount.h" 0014 #include "rocketchatbackend.h" 0015 #include "ruqola_ddpapi_command_debug.h" 0016 #include "ruqola_ddpapi_debug.h" 0017 #include "ruqolalogger.h" 0018 #include "ruqolawebsocket.h" 0019 #include "utils.h" 0020 0021 #include "ddpapi/ddpauthenticationmanager.h" 0022 #include "ddpapi/ddpmanager.h" 0023 0024 #include <QJsonArray> 0025 #include <QJsonDocument> 0026 #include <QJsonObject> 0027 #include <QStandardPaths> 0028 0029 namespace RuqolaTestWebSocket 0030 { 0031 LIBRUQOLACORE_EXPORT AbstractWebSocket *_k_ruqola_webSocket = nullptr; 0032 } 0033 0034 void video_conference_call(const QJsonObject &root, RocketChatAccount *account) 0035 { 0036 qDebug() << "video_conference_call root " << root; 0037 if (account->ruqolaLogger()) { 0038 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Video Conference Call:") + QJsonDocument(root).toJson()); 0039 } 0040 } 0041 0042 void video_conference_rejected(const QJsonObject &root, RocketChatAccount *account) 0043 { 0044 qDebug() << "video_conference_rejected root " << root; 0045 if (account->ruqolaLogger()) { 0046 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Video Conference Rejected:") + QJsonDocument(root).toJson()); 0047 } 0048 } 0049 0050 void video_conference_accepted(const QJsonObject &root, RocketChatAccount *account) 0051 { 0052 qDebug() << "video_conference_accepted root " << root; 0053 if (account->ruqolaLogger()) { 0054 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Video Conference Accepted:") + QJsonDocument(root).toJson()); 0055 } 0056 } 0057 0058 void video_conference_confirmed(const QJsonObject &root, RocketChatAccount *account) 0059 { 0060 qDebug() << "video_conference_confirmed root " << root; 0061 if (account->ruqolaLogger()) { 0062 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Video Conference Confirmed:") + QJsonDocument(root).toJson()); 0063 } 0064 } 0065 0066 void license_get_modules(const QJsonObject &root, RocketChatAccount *account) 0067 { 0068 // qDebug() << " root " << root; 0069 if (account->ruqolaLogger()) { 0070 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("License GetModule:") + QJsonDocument(root).toJson()); 0071 } 0072 const QJsonArray obj = root.value(QLatin1String("result")).toArray(); 0073 account->parseLicenses(obj); 0074 } 0075 0076 void banner_dismiss(const QJsonObject &root, RocketChatAccount *account) 0077 { 0078 // qDebug() << " root " << root; 0079 if (account->ruqolaLogger()) { 0080 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Banner Dismiss:") + QJsonDocument(root).toJson()); 0081 } 0082 } 0083 0084 void list_custom_sounds(const QJsonObject &root, RocketChatAccount *account) 0085 { 0086 qDebug() << " root " << root; 0087 if (account->ruqolaLogger()) { 0088 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("list custom sounds:") + QJsonDocument(root).toJson()); 0089 } 0090 const QJsonArray obj = root.value(QLatin1String("result")).toArray(); 0091 account->parseCustomSounds(obj); 0092 } 0093 0094 void delete_oauth_app(const QJsonObject &root, RocketChatAccount *account) 0095 { 0096 if (account->ruqolaLogger()) { 0097 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Delete Oauth app:") + QJsonDocument(root).toJson()); 0098 } 0099 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0100 qDebug() << "delete_oauth_app root " << root; 0101 } 0102 0103 void update_oauth_app(const QJsonObject &root, RocketChatAccount *account) 0104 { 0105 if (account->ruqolaLogger()) { 0106 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Update Oauth App:") + QJsonDocument(root).toJson()); 0107 } 0108 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0109 account->setOauthAppUpdated(obj); 0110 qDebug() << "update_oauth_app root " << root; 0111 } 0112 0113 void add_oauth_app(const QJsonObject &root, RocketChatAccount *account) 0114 { 0115 if (account->ruqolaLogger()) { 0116 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Add Oauth App:") + QJsonDocument(root).toJson()); 0117 } 0118 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0119 account->setOauthAppAdded(obj); 0120 } 0121 0122 void admin_status(const QJsonObject &root, RocketChatAccount *account) 0123 { 0124 qDebug() << " root " << root; 0125 if (account->ruqolaLogger()) { 0126 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Admin Status:") + QJsonDocument(root).toJson()); 0127 } 0128 } 0129 0130 void block_user(const QJsonObject &root, RocketChatAccount *account) 0131 { 0132 if (account->ruqolaLogger()) { 0133 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Block User:") + QJsonDocument(root).toJson()); 0134 } 0135 } 0136 0137 void unblock_user(const QJsonObject &root, RocketChatAccount *account) 0138 { 0139 if (account->ruqolaLogger()) { 0140 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("UnBlock User:") + QJsonDocument(root).toJson()); 0141 } 0142 } 0143 0144 void delete_custom_sound(const QJsonObject &root, RocketChatAccount *account) 0145 { 0146 if (account->ruqolaLogger()) { 0147 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Delete Custom Sound:") + QJsonDocument(root).toJson()); 0148 } 0149 } 0150 0151 void update_custom_sound(const QJsonObject &root, RocketChatAccount *account) 0152 { 0153 if (account->ruqolaLogger()) { 0154 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Update Custom Sound:") + QJsonDocument(root).toJson()); 0155 } 0156 } 0157 0158 void validateTempToken_2fa(const QJsonObject &root, RocketChatAccount *account) 0159 { 0160 if (account->ruqolaLogger()) { 0161 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Validate Temp Token 2FA:") + QJsonDocument(root).toJson()); 0162 } 0163 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0164 account->totpVerify(obj); 0165 } 0166 0167 void disable_2fa(const QJsonObject &root, RocketChatAccount *account) 0168 { 0169 if (account->ruqolaLogger()) { 0170 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Disable 2FA:") + QJsonDocument(root).toJson()); 0171 } 0172 account->totpDisabledVerify(root); 0173 } 0174 0175 void regenerateCodes_2fa(const QJsonObject &root, RocketChatAccount *account) 0176 { 0177 if (account->ruqolaLogger()) { 0178 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Regenerate Codes 2FA:") + QJsonDocument(root).toJson()); 0179 } 0180 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0181 // TODO 0182 qDebug() << " regenerateCodes_2fa " << root; 0183 } 0184 0185 void enable_2fa(const QJsonObject &root, RocketChatAccount *account) 0186 { 0187 if (account->ruqolaLogger()) { 0188 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Enable 2FA:") + QJsonDocument(root).toJson()); 0189 } 0190 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0191 account->generate2FaTotp(obj); 0192 } 0193 0194 void otr_end(const QJsonObject &root, RocketChatAccount *account) 0195 { 0196 qDebug() << "otr_end " << root; 0197 if (account->ruqolaLogger()) { 0198 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Otr End:") + QJsonDocument(root).toJson()); 0199 } 0200 } 0201 0202 void input_user_channel_autocomplete(const QJsonObject &root, RocketChatAccount *account) 0203 { 0204 if (account->ruqolaLogger()) { 0205 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Input channel/User autocomplete:") + QJsonDocument(root).toJson()); 0206 } 0207 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0208 account->inputTextManager()->inputTextCompleter(obj); 0209 } 0210 0211 void room_name_exist(const QJsonObject &root, RocketChatAccount *account) 0212 { 0213 if (account->ruqolaLogger()) { 0214 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Check if Room Name Exist:") + QJsonDocument(root).toJson()); 0215 } 0216 Q_EMIT account->ddp()->result(root.value(QLatin1String("id")).toString().toULongLong(), QJsonDocument(root)); 0217 } 0218 0219 void input_user_channel_autocomplete_thread(const QJsonObject &root, RocketChatAccount *account) 0220 { 0221 if (account->ruqolaLogger()) { 0222 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Input channel/User autocomplete thread dialog:") + QJsonDocument(root).toJson()); 0223 } 0224 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0225 0226 account->inputThreadMessageTextManager()->inputTextCompleter(obj); 0227 } 0228 0229 void process_backlog(const QJsonObject &root, RocketChatAccount *account) 0230 { 0231 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0232 // qCDebug(RUQOLA_DDPAPI_LOG) << obj.value(QLatin1String("messages")).toArray().size(); 0233 account->rocketChatBackend()->processIncomingMessages(obj.value(QLatin1String("messages")).toArray(), true); 0234 } 0235 0236 void change_room_settings(const QJsonObject &root, RocketChatAccount *account) 0237 { 0238 if (account->ruqolaLogger()) { 0239 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Change Room Settings:") + QJsonDocument(root).toJson()); 0240 } 0241 } 0242 0243 void create_jitsi_conf_call(const QJsonObject &root, RocketChatAccount *account) 0244 { 0245 if (account->ruqolaLogger()) { 0246 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Create Jitsi Conf Call:") + QJsonDocument(root).toJson()); 0247 } 0248 } 0249 0250 void open_direct_channel(const QJsonObject &root, RocketChatAccount *account) 0251 { 0252 const QJsonObject obj = root.value(QLatin1String("result")).toObject(); 0253 // qDebug() << " void open_direct_channel(const QJsonObject &root, RocketChatAccount *account)" << obj; 0254 if (!obj.isEmpty()) { 0255 const QString rid = obj.value(QLatin1String("rid")).toString(); 0256 if (!rid.isEmpty()) { 0257 account->ddp()->subscribeRoomMessage(rid); 0258 } 0259 } 0260 if (account->ruqolaLogger()) { 0261 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Open Direct channel:") + QJsonDocument(root).toJson()); 0262 } 0263 } 0264 0265 void get_room_by_id(const QJsonObject &obj, RocketChatAccount *account) 0266 { 0267 if (account->ruqolaLogger()) { 0268 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Get Room By ID :") + QJsonDocument(obj).toJson()); 0269 } 0270 } 0271 0272 void open_room(const QJsonObject &obj, RocketChatAccount *account) 0273 { 0274 if (account->ruqolaLogger()) { 0275 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Open Room :") + QJsonDocument(obj).toJson()); 0276 } 0277 } 0278 0279 void join_room(const QJsonObject &obj, RocketChatAccount *account) 0280 { 0281 if (account->ruqolaLogger()) { 0282 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Join Room :") + QJsonDocument(obj).toJson()); 0283 } 0284 } 0285 0286 void change_default_status(const QJsonObject &obj, RocketChatAccount *account) 0287 { 0288 if (account->ruqolaLogger()) { 0289 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Change Default Status :") + QJsonDocument(obj).toJson()); 0290 } 0291 } 0292 0293 void empty_callback(const QJsonObject &obj, RocketChatAccount *account) 0294 { 0295 if (account->ruqolaLogger()) { 0296 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Empty call back :") + QJsonDocument(obj).toJson()); 0297 } else { 0298 qCWarning(RUQOLA_DDPAPI_LOG) << "empty_callback " << obj; 0299 } 0300 } 0301 0302 DDPClient::DDPClient(RocketChatAccount *account, QObject *parent) 0303 : QObject(parent) 0304 , m_uid(1) 0305 , mRocketChatMessage(new RocketChatMessage) 0306 , mRocketChatAccount(account) 0307 , mAuthenticationManager(new DDPAuthenticationManager(this, this)) 0308 { 0309 } 0310 0311 DDPClient::~DDPClient() 0312 { 0313 disconnect(mWebSocket, &AbstractWebSocket::disconnected, this, &DDPClient::onWSclosed); 0314 mWebSocket->close(); 0315 // Don't delete socket when we use specific socket. 0316 if (!RuqolaTestWebSocket::_k_ruqola_webSocket) { 0317 delete mWebSocket; 0318 mWebSocket = nullptr; 0319 } 0320 delete mRocketChatMessage; 0321 mRocketChatMessage = nullptr; 0322 } 0323 0324 void DDPClient::setServerUrl(const QString &url) 0325 { 0326 mUrl = url; 0327 } 0328 0329 void DDPClient::initializeWebSocket() 0330 { 0331 mWebSocket->ignoreSslErrors(); 0332 connect(mWebSocket, &AbstractWebSocket::connected, this, &DDPClient::onWSConnected); 0333 connect(mWebSocket, &AbstractWebSocket::textMessageReceived, this, &DDPClient::onTextMessageReceived); 0334 connect(mWebSocket, &AbstractWebSocket::disconnected, this, &DDPClient::onWSclosed); 0335 connect(mWebSocket, &AbstractWebSocket::socketError, this, &DDPClient::socketError); 0336 connect(mWebSocket, &AbstractWebSocket::sslErrors, this, &DDPClient::onSslErrors); 0337 } 0338 0339 void DDPClient::start() 0340 { 0341 if (!mWebSocket) { 0342 if (!RuqolaTestWebSocket::_k_ruqola_webSocket) { 0343 mWebSocket = new RuqolaWebSocket(mRocketChatAccount->ruqolaLogger(), this); 0344 } else { 0345 mWebSocket = RuqolaTestWebSocket::_k_ruqola_webSocket; 0346 } 0347 initializeWebSocket(); 0348 } 0349 connect(mRocketChatAccount, &RocketChatAccount::serverUrlChanged, this, &DDPClient::onServerURLChange); 0350 0351 if (!mUrl.isEmpty()) { 0352 const QUrl serverUrl = adaptUrl(mUrl); 0353 if (serverUrl.isValid()) { 0354 mWebSocket->openUrl(serverUrl); 0355 qCDebug(RUQOLA_DDPAPI_LOG) << "Trying to connect to URL" << serverUrl; 0356 Q_EMIT connecting(); 0357 } 0358 } else { 0359 qCDebug(RUQOLA_DDPAPI_LOG) << "url is empty"; 0360 } 0361 } 0362 0363 void DDPClient::connectWebSocket() 0364 { 0365 mWebSocket->openUrl(adaptUrl(mUrl)); 0366 qCDebug(RUQOLA_DDPAPI_LOG) << "Reconnecting" << mUrl; 0367 } 0368 0369 QUrl DDPClient::adaptUrl(const QString &url) 0370 { 0371 return Utils::generateServerUrl(url); 0372 } 0373 0374 void DDPClient::onServerURLChange() 0375 { 0376 if (mRocketChatAccount->settings()->serverUrl() != mUrl || !mWebSocket->isValid()) { 0377 if (mWebSocket->isValid()) { 0378 mWebSocket->flush(); 0379 mWebSocket->close(); 0380 } 0381 mUrl = mRocketChatAccount->settings()->serverUrl(); 0382 connectWebSocket(); 0383 } 0384 } 0385 0386 DDPAuthenticationManager *DDPClient::authenticationManager() const 0387 { 0388 return mAuthenticationManager; 0389 } 0390 0391 bool DDPClient::isConnected() const 0392 { 0393 return m_connected; 0394 } 0395 0396 QString DDPClient::cachePath() const 0397 { 0398 return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); 0399 } 0400 0401 QQueue<QPair<QString, QJsonDocument>> DDPClient::messageQueue() const 0402 { 0403 return m_messageQueue; 0404 } 0405 0406 quint64 DDPClient::setRoomEncrypted(const QString &roomId, bool encrypted) 0407 { 0408 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomEncrypted(roomId, encrypted, m_uid); 0409 return method(result, change_room_settings, DDPClient::Persistent); 0410 } 0411 0412 void DDPClient::subscribeRoomMessage(const QString &roomId) 0413 { 0414 QJsonArray params; 0415 params.append(QJsonValue(roomId)); 0416 subscribe(QStringLiteral("stream-room-messages"), params); 0417 0418 const QJsonArray params2{QJsonValue(QStringLiteral("%1/%2").arg(roomId, QStringLiteral("deleteMessage")))}; 0419 subscribe(QStringLiteral("stream-notify-room"), params2); 0420 const QJsonArray params3{QJsonValue(QStringLiteral("%1/%2").arg(roomId, QStringLiteral("deleteMessageBulk")))}; 0421 subscribe(QStringLiteral("stream-notify-room"), params3); 0422 const QJsonArray params4{QJsonValue(QStringLiteral("%1/%2").arg(roomId, QStringLiteral("user-activity")))}; // It seems that it's the new "typing" 0423 subscribe(QStringLiteral("stream-notify-room"), params4); 0424 } 0425 0426 quint64 DDPClient::openDirectChannel(const QString &userId) 0427 { 0428 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->openDirectChannel(userId, m_uid); 0429 return method(result, open_direct_channel, DDPClient::Persistent); 0430 } 0431 0432 quint64 DDPClient::deleteFileMessage(const QString &roomId, const QString &fileid, Room::RoomType channelType) 0433 { 0434 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->deleteFileMessage(fileid, m_uid); 0435 0436 std::function<void(QJsonObject, RocketChatAccount *)> callback = [roomId, channelType](const QJsonObject &root, RocketChatAccount *account) { 0437 if (account->ruqolaLogger()) { 0438 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Delete Attachment File:") + QJsonDocument(root).toJson()); 0439 } else { 0440 qCDebug(RUQOLA_DDPAPI_LOG) << " parse users for room" << roomId; 0441 } 0442 account->roomFiles(roomId, channelType); 0443 }; 0444 0445 return method(result, callback, DDPClient::Persistent); 0446 } 0447 0448 quint64 DDPClient::openRoom(const QString &roomId) 0449 { 0450 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->openRoom(roomId, m_uid); 0451 return method(result, open_room, DDPClient::Persistent); 0452 } 0453 0454 quint64 DDPClient::getRoomById(const QString &roomId) 0455 { 0456 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->getRoomById(roomId, m_uid); 0457 return method(result, get_room_by_id, DDPClient::Persistent); 0458 } 0459 0460 quint64 DDPClient::joinRoom(const QString &roomId, const QString &joinCode) 0461 { 0462 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->joinRoom(roomId, joinCode, m_uid); 0463 return method(result, join_room, DDPClient::Persistent); 0464 } 0465 0466 quint64 DDPClient::setDefaultStatus(User::PresenceStatus status) 0467 { 0468 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setDefaultStatus(status, m_uid); 0469 return method(result, change_default_status, DDPClient::Persistent); 0470 } 0471 0472 quint64 DDPClient::userAutocomplete(const QString &pattern, const QString &exception) 0473 { 0474 const quint64 subscribeId = m_uid; 0475 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->userAutocomplete(pattern, exception, subscribeId); 0476 std::function<void(QJsonObject, RocketChatAccount *)> callback = [=](const QJsonObject &root, RocketChatAccount *account) { 0477 if (account->ruqolaLogger()) { 0478 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("User AutoComplete:") + QJsonDocument(root).toJson()); 0479 } else { 0480 qCDebug(RUQOLA_DDPAPI_LOG) << " User AutoComplete" << root; 0481 } 0482 account->insertCompleterUsers(); 0483 0484 const RocketChatMessage::RocketChatMessageResult resultUnsubscribe = mRocketChatMessage->unsubscribe(subscribeId); 0485 std::function<void(QJsonObject, RocketChatAccount *)> callbackUnsubscribeAutoComplete = [=](const QJsonObject &root, RocketChatAccount *account) { 0486 if (account->ruqolaLogger()) { 0487 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Unsubscribe AutoComplete:") + QJsonDocument(root).toJson()); 0488 } else { 0489 qDebug() << " Unsubscribe AutoComplete" << root; 0490 qCDebug(RUQOLA_DDPAPI_LOG) << " Unsubscribe AutoComplete" << root; 0491 } 0492 }; 0493 method(resultUnsubscribe, callbackUnsubscribeAutoComplete, DDPClient::Persistent); 0494 }; 0495 0496 return method(result, callback, DDPClient::Persistent); 0497 } 0498 0499 quint64 DDPClient::createJitsiConfCall(const QString &roomId) 0500 { 0501 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->createJitsiConfCall(roomId, m_uid); 0502 return method(result, create_jitsi_conf_call, DDPClient::Persistent); 0503 } 0504 0505 quint64 DDPClient::roomNameExists(const QString &roomName) 0506 { 0507 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->roomNameExists(roomName, m_uid); 0508 return method(result, room_name_exist, DDPClient::Persistent); 0509 } 0510 0511 quint64 DDPClient::inputChannelAutocomplete(const QString &roomId, const QString &pattern, const QString &exceptions, bool threadDialog) 0512 { 0513 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->inputChannelAutocomplete(roomId, pattern, exceptions, m_uid); 0514 if (threadDialog) { 0515 return method(result, input_user_channel_autocomplete_thread, DDPClient::Persistent); 0516 } else { 0517 return method(result, input_user_channel_autocomplete, DDPClient::Persistent); 0518 } 0519 } 0520 0521 quint64 DDPClient::inputUserAutocomplete(const QString &roomId, const QString &pattern, const QString &exceptions, bool threadDialog) 0522 { 0523 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->inputUserAutocomplete(roomId, pattern, exceptions, m_uid); 0524 if (threadDialog) { 0525 return method(result, input_user_channel_autocomplete_thread, DDPClient::Persistent); 0526 } else { 0527 return method(result, input_user_channel_autocomplete, DDPClient::Persistent); 0528 } 0529 } 0530 0531 quint64 DDPClient::unBlockUser(const QString &rid, const QString &userId) 0532 { 0533 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->unblockUser(rid, userId, m_uid); 0534 return method(result, unblock_user, DDPClient::Persistent); 0535 } 0536 0537 quint64 DDPClient::listCustomSounds() 0538 { 0539 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->listCustomSounds(m_uid); 0540 return method(result, list_custom_sounds, DDPClient::Persistent); 0541 } 0542 0543 quint64 DDPClient::deleteCustomSound(const QString &identifier) 0544 { 0545 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->deleteCustomSound(identifier, m_uid); 0546 return method(result, delete_custom_sound, DDPClient::Persistent); 0547 } 0548 0549 quint64 DDPClient::uploadCustomSound(const QByteArray &sound) 0550 { 0551 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->uploadCustomSound(sound, m_uid); 0552 return method(result, update_custom_sound, DDPClient::Persistent); 0553 } 0554 0555 quint64 DDPClient::streamNotifyUserOtrEnd(const QString &roomId, const QString &userId) 0556 { 0557 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->streamNotifyUserOtrEnd(roomId, userId, m_uid); 0558 qDebug() << " result " << result; 0559 return method(result, otr_end, DDPClient::Persistent); 0560 } 0561 0562 quint64 DDPClient::streamNotifyUserOtrHandshake(const QString &userFrom, const QString &userTo, const QString &publicKey) 0563 { 0564 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->streamNotifyUserOtrHandshake(userFrom, userTo, publicKey, m_uid); 0565 return method(result, otr_end, DDPClient::Persistent); 0566 } 0567 0568 quint64 DDPClient::enable2fa() 0569 { 0570 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->enable2fa(m_uid); 0571 return method(result, enable_2fa, DDPClient::Persistent); 0572 } 0573 0574 quint64 DDPClient::disable2fa(const QString &code) 0575 { 0576 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->disable2fa(code, m_uid); 0577 return method(result, disable_2fa, DDPClient::Persistent); 0578 } 0579 0580 quint64 DDPClient::regenerateCodes2fa(const QString &code) 0581 { 0582 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->regenerateCodes2fa(code, m_uid); 0583 return method(result, regenerateCodes_2fa, DDPClient::Persistent); 0584 } 0585 0586 quint64 DDPClient::validateTempToken2fa(const QString &code) 0587 { 0588 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->validateTempToken2fa(code, m_uid); 0589 return method(result, validateTempToken_2fa, DDPClient::Persistent); 0590 } 0591 0592 quint64 DDPClient::streamNotifyUserOtrAcknowledge(const QString &roomId, const QString &userId, const QString &publicKey) 0593 { 0594 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->streamNotifyUserOtrAcknowledge(roomId, userId, publicKey, m_uid); 0595 qDebug() << "streamNotifyUserOtrAcknowledge result " << result; 0596 return method(result, otr_end, DDPClient::Persistent); 0597 } 0598 0599 quint64 DDPClient::addOAuthApp(const QString &name, bool active, const QString &redirectUrl) 0600 { 0601 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->addOAuthApp(name, active, redirectUrl, m_uid); 0602 return method(result, add_oauth_app, DDPClient::Persistent); 0603 } 0604 0605 quint64 DDPClient::updateOAuthApp(const QString &name, bool active, const QString &redirectUrl) 0606 { 0607 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->updateOAuthApp(name, active, redirectUrl, m_uid); 0608 return method(result, update_oauth_app, DDPClient::Persistent); 0609 } 0610 0611 quint64 DDPClient::blockUser(const QString &rid, const QString &userId) 0612 { 0613 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->blockUser(rid, userId, m_uid); 0614 return method(result, block_user, DDPClient::Persistent); 0615 } 0616 0617 quint64 DDPClient::setAdminStatus(const QString &userId, bool admin) 0618 { 0619 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setAdminStatus(userId, admin, m_uid); 0620 return method(result, admin_status, DDPClient::Persistent); 0621 } 0622 0623 quint64 DDPClient::deleteOAuthApp(const QString &appId) 0624 { 0625 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->deleteOAuthApp(appId, m_uid); 0626 return method(result, delete_oauth_app, DDPClient::Persistent); 0627 } 0628 0629 quint64 DDPClient::bannerDismiss(const QString &bannerId) 0630 { 0631 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->bannerDismiss(bannerId, m_uid); 0632 return method(result, banner_dismiss, DDPClient::Persistent); 0633 } 0634 0635 quint64 DDPClient::licenseGetModules() 0636 { 0637 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->licenseGetModules(m_uid); 0638 return method(result, license_get_modules, DDPClient::Persistent); 0639 } 0640 0641 quint64 DDPClient::videoConferenceAccepted(const QString &roomId, const QString &callId, const QString &userId) 0642 { 0643 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->videoConferenceAccepted(roomId, callId, userId, m_uid); 0644 return method(result, video_conference_accepted, DDPClient::Persistent); 0645 } 0646 0647 quint64 DDPClient::videoConferenceRejected(const QString &roomId, const QString &callId, const QString &userId) 0648 { 0649 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->videoConferenceRejected(roomId, callId, userId, m_uid); 0650 return method(result, video_conference_rejected, DDPClient::Persistent); 0651 } 0652 0653 quint64 DDPClient::videoConferenceConfirmed(const QString &roomId, const QString &callId, const QString &userId) 0654 { 0655 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->videoConferenceConfirmed(roomId, callId, userId, m_uid); 0656 return method(result, video_conference_confirmed, DDPClient::Persistent); 0657 } 0658 0659 quint64 DDPClient::videoConferenceCall(const QString &roomId, const QString &callId, const QString &userId) 0660 { 0661 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->videoConferenceCall(roomId, callId, userId, m_uid); 0662 return method(result, video_conference_call, DDPClient::Persistent); 0663 } 0664 0665 quint64 DDPClient::informTypingStatus(const QString &roomId, bool typing, const QString &userName) 0666 { 0667 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->informTypingStatus(roomId, userName, typing, m_uid); 0668 const qint64 bytes = mWebSocket->sendTextMessage(result.result); 0669 if (bytes < result.result.length()) { 0670 qCDebug(RUQOLA_DDPAPI_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; 0671 qCDebug(RUQOLA_DDPAPI_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); 0672 } else { 0673 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << result.result; 0674 } 0675 const quint64 value = m_uid; 0676 m_uid++; 0677 return value; 0678 } 0679 0680 quint64 DDPClient::method(const RocketChatMessage::RocketChatMessageResult &result, 0681 const std::function<void(QJsonObject, RocketChatAccount *)> &callback, 0682 DDPClient::MessageType messageType) 0683 { 0684 qint64 bytes = mWebSocket->sendTextMessage(result.result); 0685 if (bytes < result.result.length()) { 0686 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; 0687 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); 0688 0689 if (messageType == DDPClient::Persistent) { 0690 m_messageQueue.enqueue(qMakePair(result.method, result.jsonDocument)); 0691 mRocketChatAccount->messageQueue()->processQueue(); 0692 } 0693 } else { 0694 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << result.result; 0695 } 0696 0697 m_callbackHash[m_uid] = callback; 0698 0699 const quint64 value = m_uid; 0700 m_uid++; 0701 return value; 0702 } 0703 0704 quint64 DDPClient::method(const QString &m, const QJsonDocument ¶ms, DDPClient::MessageType messageType) 0705 { 0706 return method(m, params, empty_callback, messageType); 0707 } 0708 0709 quint64 DDPClient::method(const QString &method, 0710 const QJsonDocument ¶ms, 0711 const std::function<void(QJsonObject, RocketChatAccount *)> &callback, 0712 DDPClient::MessageType messageType) 0713 { 0714 const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->generateMethod(method, params, m_uid); 0715 qint64 bytes = mWebSocket->sendTextMessage(result.result); 0716 if (bytes < result.result.length()) { 0717 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; 0718 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); 0719 0720 if (messageType == DDPClient::Persistent) { 0721 m_messageQueue.enqueue(qMakePair(result.method, result.jsonDocument)); 0722 mRocketChatAccount->messageQueue()->processQueue(); 0723 } 0724 } else { 0725 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << result.result; 0726 } 0727 0728 m_callbackHash[m_uid] = callback; 0729 0730 const quint64 uidCurrent = m_uid; 0731 m_uid++; 0732 return uidCurrent; 0733 } 0734 0735 void DDPClient::unsubscribe(quint64 registerId) 0736 { 0737 const RocketChatMessage::RocketChatMessageResult resultUnsubscribe = mRocketChatMessage->unsubscribe(registerId); 0738 std::function<void(QJsonObject, RocketChatAccount *)> callbackUnsubscribeMethod = [=](const QJsonObject &root, RocketChatAccount *account) { 0739 if (account->ruqolaLogger()) { 0740 account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Unsubscribe Method:") + QJsonDocument(root).toJson()); 0741 } else { 0742 qDebug() << " Unsubscribe Method" << root; 0743 qCDebug(RUQOLA_DDPAPI_LOG) << " Unsubscribe Method" << root; 0744 } 0745 }; 0746 method(resultUnsubscribe, callbackUnsubscribeMethod, DDPClient::Persistent); 0747 } 0748 0749 quint64 DDPClient::subscribe(const QString &collection, const QJsonArray ¶ms) 0750 { 0751 quint64 registerId = m_uid; 0752 QJsonObject json; 0753 json[QLatin1String("msg")] = QStringLiteral("sub"); 0754 json[QLatin1String("id")] = QString::number(m_uid); 0755 json[QLatin1String("name")] = collection; 0756 0757 QJsonArray newParams = params; 0758 0759 if (mRocketChatAccount->needAdaptNewSubscriptionRC60()) { 0760 QJsonArray args; 0761 QJsonObject obj; 0762 obj[QLatin1String("useCollection")] = false; 0763 obj[QLatin1String("args")] = args; 0764 newParams.append(std::move(obj)); 0765 } 0766 0767 json[QLatin1String("params")] = newParams; 0768 // qDebug() << "subscribe: json " << json; 0769 qint64 bytes = mWebSocket->sendTextMessage(QString::fromUtf8(QJsonDocument(json).toJson(QJsonDocument::Compact))); 0770 if (bytes < json.length()) { 0771 qCWarning(RUQOLA_DDPAPI_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; 0772 qCWarning(RUQOLA_DDPAPI_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); 0773 } else { 0774 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << json; 0775 } 0776 m_uid++; 0777 return registerId; 0778 } 0779 0780 void DDPClient::registerSubscriber(const QString &collection, const QString &event, DDPManager *ddpManager, int subscriptionId) 0781 { 0782 const QPair<QString, QString> &key{collection, event}; 0783 0784 if (mEventSubscriptionHash.contains(key)) { 0785 qCCritical(RUQOLA_DDPAPI_LOG) << "ERROR! Another manager is subscribed to this event, registration failed."; 0786 return; 0787 } 0788 0789 mEventSubscriptionHash[key] = {ddpManager, subscriptionId}; 0790 // Registering the client through its existing subscribe API 0791 // TODO: check how useCollection and args are used 0792 const QString params = QStringLiteral(R"([ 0793 "%1", 0794 { 0795 "useCollection": false, 0796 "args": [] 0797 } 0798 ])") 0799 .arg(event); 0800 0801 subscribe(collection, Utils::strToJsonArray(params)); 0802 } 0803 0804 void DDPClient::deregisterSubscriber(const QString &collection, const QString &event, DDPManager *ddpManager, int subscriptionId) 0805 { 0806 const QPair<QString, QString> key{collection, event}; 0807 0808 if (!mEventSubscriptionHash.contains(key)) { 0809 qCWarning(RUQOLA_DDPAPI_LOG) << "No DDPManager is subscribed to this event" << key; 0810 return; 0811 } 0812 0813 const QPair<DDPManager *, int> subscriptionParams = mEventSubscriptionHash.value(key); 0814 const auto unsubscriptionParams = QPair<DDPManager *, int>{ddpManager, subscriptionId}; 0815 if (subscriptionParams != unsubscriptionParams) { 0816 qCWarning(RUQOLA_DDPAPI_LOG) << "Unsubscription parameters don't match subscription parameters."; 0817 qCWarning(RUQOLA_DDPAPI_LOG).nospace() << "Subscription parameters: " << subscriptionParams << ", unsubscription parameters: " << unsubscriptionParams; 0818 return; 0819 } 0820 0821 qCDebug(RUQOLA_DDPAPI_LOG) << "Subscription to event" << key << "was removed successfully."; 0822 mEventSubscriptionHash.remove(key); 0823 } 0824 0825 quint64 DDPClient::invokeMethodAndRegister(const QString &methodName, const QJsonArray ¶ms, DDPManager *ddpManager, int operationId) 0826 { 0827 qCDebug(RUQOLA_DDPAPI_LOG) << Q_FUNC_INFO << "invoked with" << methodName << params; 0828 mMethodResponseHash[m_uid] = QPair<DDPManager *, int>(ddpManager, operationId); 0829 return method(methodName, QJsonDocument(params)); 0830 } 0831 0832 void DDPClient::deregisterFromMethodResponse(quint64 methodId, DDPManager *ddpManager, int operationId) 0833 { 0834 if (!mMethodResponseHash.contains(methodId)) { 0835 qCWarning(RUQOLA_DDPAPI_LOG) << "No API manager is registered to this method's responses. Method id:" << methodId; 0836 return; 0837 } 0838 0839 const auto registerParams = mMethodResponseHash[methodId]; 0840 const QPair<DDPManager *, int> deregisterParams{ddpManager, operationId}; 0841 if (registerParams != deregisterParams) { 0842 qCWarning(RUQOLA_DDPAPI_LOG) << "Registration parameters for this method don't match the ones in the unregister request."; 0843 qCWarning(RUQOLA_DDPAPI_LOG).nospace() << "Method ID: " << methodId << ", registration parameters: " << registerParams 0844 << ", deregistration parameters: " << deregisterParams; 0845 return; 0846 } 0847 0848 qCDebug(RUQOLA_DDPAPI_LOG) << "Registration to method" << methodId << "was removed successfully."; 0849 mMethodResponseHash.remove(methodId); 0850 } 0851 0852 void DDPClient::onTextMessageReceived(const QString &message) 0853 { 0854 QJsonDocument response = QJsonDocument::fromJson(message.toUtf8()); 0855 if (!response.isNull() && response.isObject()) { 0856 QJsonObject root = response.object(); 0857 0858 const QString messageType = root.value(QLatin1String("msg")).toString(); 0859 0860 if (messageType == QLatin1String("updated")) { 0861 // nothing to do. 0862 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << " message updated ! not implemented yet" << response; 0863 } else if (messageType == QLatin1String("result")) { 0864 quint64 id = root.value(QLatin1String("id")).toString().toULongLong(); 0865 0866 // Checking first if any of the new DDPManager claimed the result, 0867 // otherwise defaulting to old behaviour. 0868 if (mMethodResponseHash.contains(id)) { 0869 QPair<DDPManager *, int> managerOperationPair = mMethodResponseHash[id]; 0870 managerOperationPair.first->processMethodResponse(managerOperationPair.second, root); 0871 return; 0872 } 0873 0874 if (m_callbackHash.contains(id)) { 0875 std::function<void(QJsonObject, RocketChatAccount *)> callback = m_callbackHash.take(id); 0876 callback(root, mRocketChatAccount); 0877 } 0878 0879 Q_EMIT result(id, QJsonDocument(root.value(QLatin1String("result")).toObject())); 0880 } else if (messageType == QLatin1String("connected")) { 0881 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << " Connected!"; 0882 m_connected = true; 0883 Q_EMIT connectedChanged(); 0884 } else if (messageType == QLatin1String("error")) { 0885 qWarning() << mRocketChatAccount->accountName() << " ERROR!!" << message; 0886 } else if (messageType == QLatin1String("ping")) { 0887 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "Ping - Pong"; 0888 pong(); 0889 } else if (messageType == QLatin1String("added")) { 0890 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "ADDING element" << response; 0891 Q_EMIT added(root); 0892 } else if (messageType == QLatin1String("changed")) { 0893 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "Changed element" << response; 0894 Q_EMIT changed(root); 0895 } else if (messageType == QLatin1String("ready")) { 0896 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "READY element" << response; 0897 executeSubsCallBack(root); 0898 } else if (messageType == QLatin1String("removed")) { 0899 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "REMOVED element" << response; 0900 Q_EMIT removed(root); 0901 } else if (messageType == QLatin1String("nosub")) { 0902 const QString id = root.value(QStringLiteral("id")).toString(); 0903 qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "Unsubscribe element" << message << id; 0904 const QJsonObject errorObj = root[QLatin1String("error")].toObject(); 0905 if (!errorObj.isEmpty()) { 0906 qWarning() << mRocketChatAccount->accountName() << "Error unsubscribing from" << id; 0907 qWarning() << mRocketChatAccount->accountName() << "ERROR: " << errorObj[QLatin1String("error")].toString(); 0908 qWarning() << mRocketChatAccount->accountName() << "Message: " << errorObj[QLatin1String("message")].toString(); 0909 qWarning() << mRocketChatAccount->accountName() << "Reason: " << errorObj[QLatin1String("reason")].toString(); 0910 qWarning() << mRocketChatAccount->accountName() << "-- Error found END --"; 0911 } 0912 } else { 0913 // The very first message we receive is {"server_id":"0"}, can't find it in the spec, just ignore it. 0914 if (messageType.isEmpty() && !root.value(QStringLiteral("server_id")).isUndefined()) { 0915 return; 0916 } 0917 qWarning() << mRocketChatAccount->accountName() << "received something unhandled:" << messageType << message; 0918 } 0919 } else { 0920 qWarning() << mRocketChatAccount->accountName() << "received something unhandled unknown " << message; 0921 } 0922 } 0923 0924 quint64 DDPClient::loadHistory(const QJsonArray ¶ms) 0925 { 0926 return method(QStringLiteral("loadHistory"), QJsonDocument(params), process_backlog); 0927 } 0928 0929 void DDPClient::login() 0930 { 0931 if (mRocketChatAccount->defaultAuthenticationInterface()) { 0932 mRocketChatAccount->defaultAuthenticationInterface()->login(); 0933 } else { 0934 qCWarning(RUQOLA_DDPAPI_LOG) << "No plugins loaded. Please verify your installation."; 0935 } 0936 } 0937 0938 void DDPClient::enqueueLogin() 0939 { 0940 if (isConnected()) { 0941 login(); 0942 } else { 0943 // if the connection is already in, it's enough to wait for the web socket to connect 0944 mLoginEnqueued = true; 0945 if (!mWebSocket->isValid()) { 0946 connectWebSocket(); 0947 } 0948 } 0949 } 0950 0951 void DDPClient::onWSConnected() 0952 { 0953 qCDebug(RUQOLA_DDPAPI_LOG) << "Websocket connected at URL" << mUrl; 0954 0955 QJsonArray supportedVersions; 0956 supportedVersions.append(QLatin1String("1")); 0957 QJsonObject protocol; 0958 protocol[QLatin1String("msg")] = QStringLiteral("connect"); 0959 protocol[QLatin1String("version")] = QStringLiteral("1"); 0960 protocol[QLatin1String("support")] = supportedVersions; 0961 const QByteArray serialize = QJsonDocument(protocol).toJson(QJsonDocument::Compact); 0962 qint64 bytes = mWebSocket->sendTextMessage(QString::fromUtf8(serialize)); 0963 if (bytes < serialize.length()) { 0964 qCWarning(RUQOLA_DDPAPI_COMMAND_LOG) << "onWSConnected: ERROR! I couldn't send all of my message. This is a bug! (try again)"; 0965 qCWarning(RUQOLA_DDPAPI_COMMAND_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); 0966 } else { 0967 qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << serialize; 0968 } 0969 0970 if (mLoginEnqueued) { 0971 login(); 0972 mLoginEnqueued = false; 0973 } 0974 } 0975 0976 void DDPClient::onSslErrors(const QList<QSslError> &errors) 0977 { 0978 qCDebug(RUQOLA_DDPAPI_LOG) << "SSL error" << errors.count(); 0979 for (const QSslError &err : errors) { 0980 qCWarning(RUQOLA_DDPAPI_LOG) << "error ssl type:" << err.errorString(); 0981 } 0982 mWebSocket->ignoreSslErrors(); 0983 } 0984 0985 void DDPClient::onWSclosed() 0986 { 0987 const bool normalClose = mWebSocket->closeCode() == QWebSocketProtocol::CloseCodeNormal; 0988 if (normalClose) { 0989 Q_EMIT disconnectedByServer(); 0990 } else { 0991 qCWarning(RUQOLA_DDPAPI_LOG) << "WebSocket CLOSED reason:" << mWebSocket->closeReason() << " error: " << mWebSocket->error() 0992 << " close code : " << mWebSocket->closeCode() << " error string " << mWebSocket->errorString(); 0993 authenticationManager()->setLoginStatus(DDPAuthenticationManager::GenericError); 0994 Q_EMIT wsClosedSocketError(); 0995 } 0996 0997 m_connected = false; 0998 Q_EMIT connectedChanged(); 0999 } 1000 1001 void DDPClient::pong() 1002 { 1003 QJsonObject pong; 1004 pong[QLatin1String("msg")] = QStringLiteral("pong"); 1005 mWebSocket->sendBinaryMessage(QJsonDocument(pong).toJson(QJsonDocument::Compact)); 1006 } 1007 1008 void DDPClient::executeSubsCallBack(const QJsonObject &root) 1009 { 1010 const QJsonArray subs = root[QLatin1String("subs")].toArray(); 1011 if (!subs.isEmpty()) { 1012 const quint64 id = subs.at(0).toString().toULongLong(); 1013 if (m_callbackHash.contains(id)) { 1014 std::function<void(QJsonObject, RocketChatAccount *)> callback = m_callbackHash.take(id); 1015 callback(root, mRocketChatAccount); 1016 } 1017 } else { 1018 qCWarning(RUQOLA_DDPAPI_LOG) << "Problem with subs json " << root; 1019 } 1020 } 1021 1022 // Otr end 1023 //["{\"msg\":\"method\",\"id\":\"22\",\"method\":\"stream-notify-user\",\"params\":[\"YbwG4T2uB3wZSZSKB/otr\",\"end\",{\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\",\"userId\":\"4faACeGzSvG7xMcTy\"}]}"] 1024 // Otr handshake 1025 //\"msg\":\"method\",\"id\":\"24\",\"method\":\"stream-notify-user\",\"params\":[\"YbwG4T2uB3wZSZSKB/otr\",\"handshake\",{\"roomId\":\"4faACeGzSvG7xMcTyYbwG4T2uB3wZSZSKB\",\"userId\":\"4faACeGzSvG7xMcTy\",\"publicKey\":\"{\\\ 1026 1027 #include "moc_ddpclient.cpp"