mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-19 14:25:27 +00:00
mobile: add ability to delete cloud account
Apple store rules require this. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
941aaf5b65
commit
32bc034f41
9 changed files with 159 additions and 0 deletions
|
@ -1,3 +1,4 @@
|
|||
mobile: allow cloud account deletion (Apple app store requirement)
|
||||
|
||||
---
|
||||
* Always add new entries at the very top of this file above other existing entries and this note.
|
||||
|
|
|
@ -17,6 +17,7 @@ CloudStorageAuthenticate::CloudStorageAuthenticate(QObject *parent) :
|
|||
#define CLOUDBACKENDSTORAGE CLOUDURL + "/storage"
|
||||
#define CLOUDBACKENDVERIFY CLOUDURL + "/verify"
|
||||
#define CLOUDBACKENDUPDATE CLOUDURL + "/update"
|
||||
#define CLOUDBACKENDDELETE CLOUDURL + "/delete-account"
|
||||
|
||||
QNetworkReply* CloudStorageAuthenticate::backend(const QString& email,const QString& password,const QString& pin,const QString& newpasswd)
|
||||
{
|
||||
|
@ -50,6 +51,34 @@ QNetworkReply* CloudStorageAuthenticate::backend(const QString& email,const QStr
|
|||
return reply;
|
||||
}
|
||||
|
||||
QNetworkReply* CloudStorageAuthenticate::deleteAccount(const QString& email, const QString& password)
|
||||
{
|
||||
QString payload(email + QChar(' ') + password);
|
||||
QNetworkRequest *request = new QNetworkRequest(QUrl(CLOUDBACKENDDELETE));
|
||||
request->setRawHeader("Accept", "text/xml, text/plain");
|
||||
request->setRawHeader("User-Agent", userAgent.toUtf8());
|
||||
request->setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
|
||||
reply = manager()->post(*request, qPrintable(payload));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
connect(reply, &QNetworkReply::finished, this, &CloudStorageAuthenticate::deleteFinished);
|
||||
connect(reply, &QNetworkReply::sslErrors, this, &CloudStorageAuthenticate::sslErrors);
|
||||
connect(reply, &QNetworkReply::errorOccurred, this, &CloudStorageAuthenticate::uploadError);
|
||||
#else
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(deleteFinished()));
|
||||
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
|
||||
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
|
||||
SLOT(uploadError(QNetworkReply::NetworkError)));
|
||||
#endif
|
||||
return reply;
|
||||
}
|
||||
|
||||
void CloudStorageAuthenticate::deleteFinished()
|
||||
{
|
||||
QString cloudAuthReply(reply->readAll());
|
||||
qDebug() << "Completed connection with cloud storage backend, response" << cloudAuthReply;
|
||||
emit finishedDelete();
|
||||
}
|
||||
|
||||
void CloudStorageAuthenticate::uploadFinished()
|
||||
{
|
||||
static QString myLastError;
|
||||
|
|
|
@ -9,15 +9,18 @@ class CloudStorageAuthenticate : public QObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
QNetworkReply* backend(const QString& email,const QString& password,const QString& pin = QString(),const QString& newpasswd = QString());
|
||||
QNetworkReply* deleteAccount(const QString& email, const QString &passwd);
|
||||
explicit CloudStorageAuthenticate(QObject *parent);
|
||||
signals:
|
||||
void finishedAuthenticate();
|
||||
void finishedDelete();
|
||||
void passwordChangeSuccessful();
|
||||
private
|
||||
slots:
|
||||
void uploadError(QNetworkReply::NetworkError error);
|
||||
void sslErrors(const QList<QSslError> &errorList);
|
||||
void uploadFinished();
|
||||
void deleteFinished();
|
||||
private:
|
||||
QNetworkReply *reply;
|
||||
QString userAgent;
|
||||
|
|
75
mobile-widgets/qml/DeleteAccount.qml
Normal file
75
mobile-widgets/qml/DeleteAccount.qml
Normal file
|
@ -0,0 +1,75 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.2
|
||||
import org.kde.kirigami 2.4 as Kirigami
|
||||
import org.subsurfacedivelog.mobile 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: deleteAccountPage
|
||||
property int pageWidth: deleteAccountPage.width - deleteAccountPage.leftPadding - deleteAccountPage.rightPadding
|
||||
title: qsTr("Delete Subsurface Cloud Account")
|
||||
background: Rectangle { color: subsurfaceTheme.backgroundColor }
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
width: deleteAccountPage.width
|
||||
Layout.margins: Kirigami.Units.gridUnit / 2
|
||||
|
||||
Kirigami.Heading {
|
||||
text: qsTr("Delete Subsurface Cloud Account")
|
||||
color: subsurfaceTheme.textColor
|
||||
Layout.topMargin: Kirigami.Units.gridUnit
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.maximumWidth: pageWidth
|
||||
wrapMode: TextEdit.NoWrap
|
||||
fontSizeMode: Text.Fit
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
text: qsTr("Deleting your Subsurface Cloud account is permanent.\n") +
|
||||
qsTr("There is no way to undo this action.")
|
||||
level: 4
|
||||
color: subsurfaceTheme.textColor
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing * 3
|
||||
Layout.maximumWidth: pageWidth
|
||||
wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
|
||||
anchors.horizontalCenter: parent.Center
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
text: PrefCloudStorage.cloud_storage_email
|
||||
level: 4
|
||||
color: subsurfaceTheme.textColor
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing * 3
|
||||
Layout.maximumWidth: pageWidth
|
||||
wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
|
||||
anchors.horizontalCenter: parent.Center
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
|
||||
TemplateButton {
|
||||
id: deleteCloudAccount
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("delete cloud account")
|
||||
onClicked: {
|
||||
manager.appendTextToLog("request to delete account confirmed")
|
||||
manager.deleteAccount()
|
||||
rootItem.returnTopPage()
|
||||
}
|
||||
}
|
||||
|
||||
TemplateButton {
|
||||
id: dontDeleteCloudAccount
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("never mind")
|
||||
onClicked: {
|
||||
manager.appendTextToLog("request to delete account cancelled")
|
||||
rootItem.returnTopPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,6 +61,15 @@ TemplatePage {
|
|||
text: describe[Backend.cloud_verification_status]
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 1.5
|
||||
}
|
||||
TemplateButton {
|
||||
id: deleteCloudAccount
|
||||
enabled: Backend.cloud_verification_status !== Enums.CS_NOCLOUD
|
||||
text: qsTr("Delete Account")
|
||||
onClicked: {
|
||||
manager.appendTextToLog("requesting account deletion");
|
||||
showPage(deleteAccount)
|
||||
}
|
||||
}
|
||||
}
|
||||
TemplateLine {
|
||||
visible: sectionGeneral.isExpanded
|
||||
|
|
|
@ -783,6 +783,10 @@ if you have network connectivity and want to sync your data to cloud storage."),
|
|||
id: settingsWindow
|
||||
}
|
||||
|
||||
DeleteAccount {
|
||||
id: deleteAccount
|
||||
}
|
||||
|
||||
CopySettings {
|
||||
id: settingsCopyWindow
|
||||
visible: false
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<!-- ********** qml ********** -->
|
||||
<file>About.qml</file>
|
||||
<file>CloudCredentials.qml</file>
|
||||
<file>DeleteAccount.qml</file>
|
||||
<file>DiveDetails.qml</file>
|
||||
<file>DiveDetailsEdit.qml</file>
|
||||
<file>DiveDetailsView.qml</file>
|
||||
|
|
|
@ -725,6 +725,42 @@ bool QMLManager::verifyCredentials(QString email, QString password, QString pin)
|
|||
return true;
|
||||
}
|
||||
|
||||
void QMLManager::deleteAccount()
|
||||
{
|
||||
QString email(prefs.cloud_storage_email);
|
||||
QString passwd(prefs.cloud_storage_password);
|
||||
if (email.isEmpty() || passwd.isEmpty())
|
||||
return;
|
||||
|
||||
setStartPageText(tr("Deleting cloud account..."));
|
||||
appendTextToLog(QStringLiteral("user requested that we delete cloud account for email %1").arg(email));
|
||||
CloudStorageAuthenticate *csa = new CloudStorageAuthenticate(this);
|
||||
csa->deleteAccount(email, passwd);
|
||||
// let's wait here for the signal to avoid too many more nested functions
|
||||
QTimer myTimer;
|
||||
myTimer.setSingleShot(true);
|
||||
QEventLoop loop;
|
||||
connect(csa, &CloudStorageAuthenticate::finishedDelete, &loop, &QEventLoop::quit);
|
||||
connect(&myTimer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
myTimer.start(prefs.cloud_timeout * 3 * 1000); // give it extra time
|
||||
loop.exec();
|
||||
if (!myTimer.isActive()) {
|
||||
// got no response from the server
|
||||
setStartPageText(RED_FONT + tr("No response from cloud server to delete account") + END_FONT);
|
||||
appendTextToLog(QStringLiteral("no response from cloud server to delete account"));
|
||||
return;
|
||||
}
|
||||
myTimer.stop();
|
||||
appendTextToLog(QStringLiteral("deleted the account"));
|
||||
qPrefCloudStorage::set_cloud_storage_email("");
|
||||
qPrefCloudStorage::set_cloud_storage_email_encoded("");
|
||||
qPrefCloudStorage::set_cloud_storage_password("");
|
||||
qPrefCloudStorage::set_cloud_verification_status(qPrefCloudStorage::CS_NOCLOUD);
|
||||
set_filename(qPrintable(nocloud_localstorage()));
|
||||
setStartPageText(tr("Cloud storage account deleted."));
|
||||
return;
|
||||
}
|
||||
|
||||
void QMLManager::loadDivesWithValidCredentials()
|
||||
{
|
||||
QString url;
|
||||
|
|
|
@ -180,6 +180,7 @@ public slots:
|
|||
void saveChangesCloud(bool forceRemoteSync, bool fromUndo = false);
|
||||
void selectDive(int id);
|
||||
void deleteDive(int id);
|
||||
void deleteAccount();
|
||||
void toggleDiveInvalid(int id);
|
||||
void copyDiveData(int id);
|
||||
void pasteDiveData(int id);
|
||||
|
|
Loading…
Add table
Reference in a new issue