Add cloud password support

This commit is contained in:
Sergey Chupligin 2025-11-06 21:17:42 +03:00
parent b6bcbac4ab
commit 8c932f5bd7
10 changed files with 493 additions and 17 deletions

View file

@ -49,7 +49,7 @@ void ServerConnection::init()
payload["deviceId"] = m_settings->value(QString("deviceId")).toString();
QJsonObject userAgent;
userAgent.insert("appVersion", "25.6.11");
userAgent.insert("appVersion", "25.11.1");
userAgent.insert("deviceLocale", "ru");
userAgent.insert("deviceName", "Chrome");
userAgent.insert("deviceType", "WEB");
@ -73,10 +73,40 @@ void ServerConnection::sendHeartBeatMessage()
void ServerConnection::onMessageReceived(RawApiMessage message)
{
if(message.seq() == m_messSeq && !message.payload().isEmpty()) {
qDebug() << "READY TO LOGIN";
if(message.opcode() == 6) {
//COUNTRY CODES AND OTHER FOR PHONENUMBERS
emit readyToLogin();
}
if(message.opcode() == 17) {
if(!message.payload()["token"].toString().isEmpty()) {
emit tokenReady(message.payload()["token"].toString());
}
}
if(message.opcode() == 18) {
QJsonObject payload = message.payload();
if(payload["passwordChallenge"].isUndefined()) {
qDebug() << "READY TO LOGIN";
emit readyToLogin();
} else {
QString trackId = payload["passwordChallenge"].toObject()["trackId"].toString();
emit requestPassword(trackId);
}
}
if(message.opcode() == 115) {
if(!message.payload()["error"].isUndefined()) {
qWarning() << message.payload()["localizedMessage"];
return;
}
QString token = message.payload()["tokenAttrs"].toObject()["LOGIN"].toObject()["token"].toString();
if(!token.isEmpty()) {
emit tokenReady(token);
} else {
qWarning() << message.payload();
}
}
m_heartBeatTimer->start(30000);
}
@ -87,14 +117,7 @@ void ServerConnection::sendPhone(QString phone)
payload["language"] = "ru";
payload["phone"] = phone;
int seq = m_messQueue->sendMessage(17, payload);
connect(m_messQueue, &MessagesQueue::messageReceived, [=](RawApiMessage message) {
if(message.seq() == seq) {
if(!message.payload()["token"].toString().isEmpty()) {
emit tokenReady(message.payload()["token"].toString());
}
}
});
m_messQueue->sendMessage(17, payload);
}
void ServerConnection::sendCode(QString code)
@ -107,6 +130,15 @@ void ServerConnection::sendCode(QString code)
m_messQueue->sendMessage(18, payload);
}
void ServerConnection::sendPassword(QString password, QString trackId)
{
QJsonObject payload;
payload["password"] = password;
payload["trackId"] = trackId;
m_messQueue->sendMessage(115, payload);
}
void ServerConnection::requestDataSync()
{
QJsonObject payload;

View file

@ -36,6 +36,7 @@ public:
Q_INVOKABLE void sendPhone(QString phone);
Q_INVOKABLE void sendCode(QString code);
Q_INVOKABLE void sendPassword(QString password, QString trackId);
Q_INVOKABLE void requestDataSync();
Q_INVOKABLE void requestContactsByIDs(QList<int> idS);
Q_INVOKABLE void requestChatById(int chatId, int from, int backward = 30, int forward = 0);
@ -47,6 +48,7 @@ signals:
void userIdChanged();
void tokenReady(QString token);
void connectionError();
void requestPassword(QString trackId);
private slots:
void sendHeartBeatMessage();

View file

@ -32,13 +32,17 @@ UserSession::UserSession(QObject *parent)
{
connect(m_messQueue, &MessagesQueue::messageReceived, [=](RawApiMessage message) {
//FROM LOGIN DATA
if(message.opcode() == 18) {
if(message.opcode() == 18 || message.opcode() == 115) {
updateSessionData(message.payload());
}
//FROM UPDATE ON START DATA
if(message.opcode() == 19) {
updateOnStartData(message.payload());
}
//FROM START
if(message.opcode() == 6) {
coldStart();
}
});
}
@ -115,7 +119,7 @@ void UserSession::updateSessionData(QJsonObject payload)
{
QString authToken = payload["tokenAttrs"].toObject()["LOGIN"].toObject()["token"].toString();
if(authToken.isEmpty()) {
qDebug() << "Auth token is empty!";
qWarning() << "Auth token is empty!";
return;
}
m_settings->setValue("authToken", authToken);
@ -127,17 +131,21 @@ void UserSession::updateSessionData(QJsonObject payload)
void UserSession::updateOnStartData(QJsonObject payload)
{
QJsonObject profile = payload["profile"].toObject();
QJsonObject profile = payload["profile"].toObject()["contact"].toObject();
updateProfile(profile);
}
void UserSession::updateProfile(QJsonObject profile)
{
Contact* userProfile = new Contact(profile);
if(userProfile->userId() == 0) {
qWarning() << "UserProfile ID is 0";
return;
}
if(userProfile->userId() != m_userProfile->userId()) {
m_userProfile = userProfile;
emit userIdChanged();
}
}
}
QString UserSession::authToken()

View file

@ -37,6 +37,11 @@ ApplicationWindow {
requestDataSync();
}
}
onRequestPassword: {
pageStack.replace(Qt.resolvedUrl("pages/EntherPasswordPage.qml"), {trackId: trackId})
}
onTokenReady: {
userSession.storeToken(token)
pageStack.push(Qt.resolvedUrl("pages/EntherCodePage.qml"))
@ -49,9 +54,11 @@ ApplicationWindow {
UserSession{
id: userSession
onUserIdChanged: {
if(userSession.userId > 0) {
if (userSession.userId > 0) {
pageStack.clear();
pageStack.push(Qt.resolvedUrl("pages/ChatListPage.qml"))
} else {
console.log("+++++++++++++++++++++++++++++++++++++++++")
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (C) 2025 Chupligin Sergey <neochapay@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
Item{
height: Theme.itemSizeLarge
width: messagesListView.width / 2
Row {
id: audioMessageControlItem
spacing: height * 0.1
width: parent.width - height * 0.1
height: parent.height
anchors{
left: parent.left
leftMargin: height * 0.1
}
ColorIcon{
id: playIcon
height: parent.height * 0.8
width: height
source: "../icons/audio.svg"
}
Slider {
width: audioMessageControlItem.width
height: parent.height * 0.8
minimumValue: 0
maximumValue: duration
value: 0
}
}
}

View file

@ -0,0 +1,292 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:ns1="http://sozi.baierouge.fr"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="svg18586"
sodipodi:docname="JPortugall_icon_speaker.svg"
viewBox="0 0 212.6 212.6"
sodipodi:version="0.32"
version="1.0"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:version="0.47pre4 r22446"
>
<defs
id="defs18588"
>
<filter
id="filter4352"
inkscape:collect="always"
>
<feGaussianBlur
id="feGaussianBlur4354"
stdDeviation="4.5056841"
inkscape:collect="always"
/>
</filter
>
</defs
>
<sodipodi:namedview
id="base"
inkscape:zoom="1.351626"
height="6cm"
borderopacity="1.0"
inkscape:current-layer="layer1"
inkscape:cx="-25.124812"
inkscape:cy="61.428571"
inkscape:window-maximized="0"
showgrid="false"
width="6cm"
inkscape:guide-bbox="true"
units="cm"
showguides="true"
bordercolor="#666666"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-width="1274"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
pagecolor="#ffffff"
inkscape:document-units="px"
inkscape:window-height="726"
>
<sodipodi:guide
id="guide3811"
position="241.19098,76.204511"
orientation="1,0"
/>
</sodipodi:namedview
>
<g
id="layer1"
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
transform="translate(17.728 7.9865)"
>
<path
id="path4346"
sodipodi:rx="75.094734"
sodipodi:ry="75.094734"
style="stroke-linejoin:round;color:#000000;filter:url(#filter4352);stroke:#000000;stroke-linecap:round;stroke-width:12;fill:#ffffff"
sodipodi:type="arc"
d="m-67.326 107.17a75.095 75.095 0 1 1 -150.19 0 75.095 75.095 0 1 1 150.19 0z"
inkscape:export-ydpi="10.898185"
inkscape:export-filename="/home/lila/posgrado/prodmult2/diapos/audio.png"
transform="matrix(1.1232 0 0 1.1232 236.75 -24.515)"
sodipodi:cy="107.16988"
sodipodi:cx="-142.42105"
inkscape:export-xdpi="10.898185"
/>
<path
id="path4337"
sodipodi:rx="75.094734"
sodipodi:ry="75.094734"
style="stroke-linejoin:round;color:#000000;stroke:#000000;stroke-linecap:round;stroke-width:12;fill:#ffffff"
sodipodi:type="arc"
d="m-67.326 107.17a75.095 75.095 0 1 1 -150.19 0 75.095 75.095 0 1 1 150.19 0z"
inkscape:export-ydpi="10.898185"
inkscape:export-filename="/home/lila/posgrado/prodmult2/diapos/audio.png"
transform="matrix(1.1232 0 0 1.1232 236.75 -24.515)"
sodipodi:cy="107.16988"
sodipodi:cx="-142.42105"
inkscape:export-xdpi="10.898185"
/>
<symbol
id="symbol18404"
style="fill-rule:evenodd"
transform="matrix(.18633 0 0 .18633 -2727.2 -629.38)"
>
<path
id="path18383"
style="fill:#ffffff"
class="fil0"
d="m13816 8478.1c299 0 543 244 543 543.1s-244 543.1-543 543.1c-300 0-544-244-544-543.1s244-543.1 544-543.1z"
/>
<path
id="path18385"
style="fill:#ff0000"
class="fil1"
d="m13816 8450.7c314 0 570 256.3 570 570.5s-256 570.5-570 570.5c-315 0-571-256.3-571-570.5s256-570.5 571-570.5zm-14 577.4c18 0 35 6 48 16.1-12-10.1-27-17.1-44-19.9-50-8.3-98 26.2-107 76.7v4.8c-48-18.7-79-69.3-70-122.2l30-183.5 208 22.4c4 0.4 8-4.3 8-10.6 1-6.2-2-11.7-6-12.2l-206-22.2 2-13.8 208 22.4c4 0.4 8-4.3 9-10.6 0-6.2-3-11.7-7-12.2l-206-22.2 3-19.8 207 22.3c4 0.5 8-4.3 9-10.5 0-6.3-3-11.8-7-12.2l-205-22.2 3-18.8 208 22.5c4 0.4 8-4.3 9-10.6s-2-11.8-6-12.2l-208-22.4 4-20.9c25-153.6 343-111.9 316 51.9l-57 347.3c-6 36.8-30 66.5-61 81.9 0-11.7-2-23-6-33.5 3 7.7 4 15.9 4 24.4 0 37.3-25 68.8-60 77.7v284c0 17.4-12 31.7-26 31.7h-35c-15 0-26-14.3-26-31.7v-317.9c-8-12.6-13-27.6-13-43.8 0-44.2 36-80.2 80-80.2z"
/>
</symbol
>
<symbol
id="35441304"
style="fill-rule:evenodd"
transform="matrix(.18633 0 0 .18633 -1780.5 -1202.1)"
>
<path
id="path18346"
style="fill:#ffffff"
class="fil0"
d="m13816 8478.1c299.14 0 543.12 243.98 543.12 543.12 0 299.13-243.98 543.12-543.12 543.12-299.13 0-543.12-243.98-543.12-543.12s243.98-543.12 543.12-543.12z"
/>
<path
id="path18348"
style="fill:#ff0000"
class="fil1"
d="m13816 8450.7c314.22 0 570.5 256.28 570.5 570.5s-256.28 570.5-570.5 570.5-570.5-256.28-570.5-570.5 256.28-570.5 570.5-570.5zm-13.508 577.37c18.075 0 34.78 6.0276 48.217 16.173-12.237-10.098-27.197-17.185-43.926-19.933-50.543-8.2953-98.531 26.154-106.83 76.697-0.256 1.5866-0.472 3.1732-0.649 4.7598-48.17-18.638-78.634-69.315-69.957-122.18l30.126-183.5 207.62 22.409c4.185 0.4489 8.169-4.2992 8.843-10.559 0.681-6.2598-2.205-11.752-6.386-12.201l-206.36-22.272 2.26-13.791 207.71 22.417c4.185 0.4489 8.169-4.2992 8.842-10.559 0.681-6.2598-2.205-11.752-6.386-12.201l-206.45-22.284 3.244-19.752 206.82 22.323c4.185 0.4489 8.17-4.2992 8.843-10.559 0.681-6.2598-2.201-11.752-6.386-12.201l-205.56-22.185 3.087-18.819 208.52 22.504c4.181 0.4489 8.169-4.2992 8.842-10.559 0.677-6.2598-2.204-11.752-6.386-12.201l-207.26-22.366 3.433-20.929c25.209-153.57 343.13-111.92 316.23 51.906l-57.003 347.29c-6.04 36.776-29.678 66.48-60.874 81.921 0.173-11.673-1.882-23.02-5.804-33.563 2.477 7.7126 3.827 15.933 3.827 24.453 0 37.327-25.709 68.831-60.327 77.72v283.97c0 17.417-11.574 31.665-25.724 31.665h-35.618c-14.146 0-25.721-14.248-25.721-31.665v-317.89c-8.259-12.61-13.082-27.661-13.082-43.807 0-44.197 36.039-80.236 80.236-80.236z"
/>
</symbol
>
<g
id="g4339"
inkscape:export-ydpi="10.898185"
inkscape:export-xdpi="10.898185"
inkscape:export-filename="/home/lila/posgrado/prodmult2/diapos/audio.png"
transform="translate(-20.386 -.49025)"
>
<rect
id="rect3807"
style="color:#000000;fill:#000000"
ry="7.3985"
height="48.09"
width="39.212"
y="72.299"
x="31.102"
/>
<path
id="path3809"
style="stroke-linejoin:round;color:#000000;stroke:#000000;stroke-linecap:round;stroke-width:7.7261;fill:#000000"
sodipodi:type="star"
d="m151.34 121.29-78.918-45.564 78.918-45.564v91.128z"
sodipodi:r1="52.612621"
inkscape:flatsided="true"
transform="matrix(.75222 0 0 1.0722 -14.421 15.149)"
sodipodi:arg2="2.0943951"
sodipodi:arg1="1.0471976"
inkscape:randomized="0"
sodipodi:cy="75.726273"
sodipodi:cx="125.03459"
inkscape:rounded="0"
sodipodi:r2="26.306311"
sodipodi:sides="3"
/>
<path
id="path4323"
sodipodi:rx="21.455639"
sodipodi:ry="34.715954"
style="stroke-linejoin:round;color:#000000;stroke:#000000;stroke-linecap:round;stroke-width:8.1;fill:#000000"
sodipodi:type="arc"
d="m210.86 99.344c0 19.173-9.606 34.716-21.456 34.716s-21.456-15.543-21.456-34.716 9.606-34.716 21.456-34.716 21.456 15.543 21.456 34.716z"
transform="matrix(.73652 0 0 .96503 -51.057 .47397)"
sodipodi:cy="99.344475"
sodipodi:cx="189.4015"
/>
<path
id="path4329"
style="stroke-linejoin:round;stroke:#000000;stroke-linecap:round;stroke-width:12;fill:none"
d="m121.71 124.32c5.9-7.9392 9.2195-17.765 9.343-27.656 0.12566-10.064-3.0618-20.142-8.9516-28.304"
sodipodi:nodetypes="csc"
inkscape:path-effect="#path-effect4331"
inkscape:original-d="m 121.71338,124.32419 c 0,0 -7.87543,-5.35017 9.34296,-27.655821 17.2184,-22.305656 -8.95164,-28.30398 -8.95164,-28.30398"
/>
<path
id="path4333"
style="stroke-linejoin:round;stroke:#000000;stroke-linecap:round;stroke-width:15.658;fill:none"
d="m143.22 132.85c7.6985-10.359 12.03-23.18 12.191-36.086 0.16396-13.132-3.9951-26.282-11.68-36.932"
sodipodi:nodetypes="csc"
inkscape:path-effect="#path-effect4335"
inkscape:original-d="m 143.22419,132.85314 c 0,0 -10.27605,-6.98104 12.19092,-36.085988 C 177.8821,67.662192 143.7348,59.835434 143.7348,59.835434"
/>
</g
>
</g
>
<metadata
>
<rdf:RDF
>
<cc:Work
>
<dc:format
>image/svg+xml</dc:format
>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"
/>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/"
/>
<dc:publisher
>
<cc:Agent
rdf:about="http://openclipart.org/"
>
<dc:title
>Openclipart</dc:title
>
</cc:Agent
>
</dc:publisher
>
<dc:title
>audio</dc:title
>
<dc:date
>2010-07-28T00:35:01</dc:date
>
<dc:description
>icon for audio</dc:description
>
<dc:source
>https://openclipart.org/detail/74875/audio-by-nomade</dc:source
>
<dc:creator
>
<cc:Agent
>
<dc:title
>nomade</dc:title
>
</cc:Agent
>
</dc:creator
>
<dc:subject
>
<rdf:Bag
>
<rdf:li
>audio</rdf:li
>
<rdf:li
>sound</rdf:li
>
<rdf:li
>speaker</rdf:li
>
</rdf:Bag
>
</dc:subject
>
</cc:Work
>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:License
>
</rdf:RDF
>
</metadata
>
</svg
>

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -36,6 +36,7 @@ Page {
TextField {
id: codeNumberField
placeholderText: qsTr("XXXXXX")
inputMethodHints: Qt.ImhFormattedNumbersOnly
anchors.centerIn: parent
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2025 Chupligin Sergey <neochapay@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
objectName: "entherPasswordPage"
allowedOrientations: Orientation.All
property string trackId
PageHeader {
id: header
objectName: "pageHeader"
title: qsTr("Enther password")
}
SilicaFlickable {
anchors.fill: parent
TextField {
id: passswordField
anchors.centerIn: parent
inputMethodHints: Qt.ImhHiddenText
echoMode: TextInput.Password
}
Button{
id: sendPasswordButton
text: qsTr("Send password")
width: passswordField.width
anchors.top: passswordField.bottom
onClicked: {
serverConnection.sendPassword(passswordField.text, trackId)
}
}
}
}

View file

@ -118,6 +118,17 @@
<translation>Отправить</translation>
</message>
</context>
<context>
<name>EntherPasswordPage</name>
<message>
<source>Enther password</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Send password</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EntherPhonePage</name>
<message>

View file

@ -137,11 +137,24 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/EntherCodePage.qml" line="44"/>
<location filename="../qml/pages/EntherCodePage.qml" line="45"/>
<source>Send</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EntherPasswordPage</name>
<message>
<location filename="../qml/pages/EntherPasswordPage.qml" line="32"/>
<source>Enther password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/EntherPasswordPage.qml" line="47"/>
<source>Send password</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EntherPhonePage</name>
<message>