Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package moolticute for openSUSE:Factory 
checked in at 2023-06-29 17:29:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/moolticute (Old)
 and      /work/SRC/openSUSE:Factory/.moolticute.new.13546 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "moolticute"

Thu Jun 29 17:29:09 2023 rev:4 rq:1095913 version:1.01.0.r0.g77100ea

Changes:
--------
--- /work/SRC/openSUSE:Factory/moolticute/moolticute.changes    2022-12-14 
14:12:51.792068797 +0100
+++ /work/SRC/openSUSE:Factory/.moolticute.new.13546/moolticute.changes 
2023-06-29 17:29:27.590657003 +0200
@@ -1,0 +2,18 @@
+Thu Jun 29 07:08:47 UTC 2023 - Stefan Weiberg <opens...@hibiki.eu>
+
+- Update to v1.01.0
+    [BLE] Remove not tagged notes during import
+    [BLE] Fetch notes after import
+    [BLE] Fix import data nodes
+    [BLE] Display when entered multiple domain is invalid
+    [BLE] Fix multiple low battery notification
+    [BLE] Improve NoBundle FW upload
+    Fix application exit on Mac
+    bug fix: in a "no bundle" case, allow moolticute to fetch platform info
+    Mini BLE: increase file size to 20kB
+    Fix saving credential without passwords Qt6
+    changing hidden tabs shortcuts to SHIFT + Fx
+    increasing daemon log size
+    Mini: fix files upload
+
+-------------------------------------------------------------------

Old:
----
  moolticute-1.00.1.r0.gf211d93.tar.gz

New:
----
  moolticute-1.01.0.r0.g77100ea.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ moolticute.spec ++++++
--- /var/tmp/diff_new_pack.dWXUoh/_old  2023-06-29 17:29:28.382661642 +0200
+++ /var/tmp/diff_new_pack.dWXUoh/_new  2023-06-29 17:29:28.390661689 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package moolticute
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %global UDEVDIR %{_udevrulesdir}
 %global QMAKE_BIN qmake-qt5
 Name:           moolticute
-Version:        1.00.1.r0.gf211d93
+Version:        1.01.0.r0.g77100ea
 Release:        0
 Summary:        Companion GUI application for Mooltipass password manager 
devices
 License:        GPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.dWXUoh/_old  2023-06-29 17:29:28.450662040 +0200
+++ /var/tmp/diff_new_pack.dWXUoh/_new  2023-06-29 17:29:28.454662063 +0200
@@ -4,7 +4,7 @@
     <param name="url">https://github.com/mooltipass/moolticute.git</param>
     <param name="filename">moolticute</param>
     <param name="package-meta">yes</param>
-    <param name="revision">v1.00.1</param>
+    <param name="revision">v1.01.0</param>
     <param name="versionrewrite-pattern">v([0-9\.]*)(-testing)?(.*)</param>
     <param name="versionrewrite-replacement">\1\3</param>
     <param name="versionformat">@PARENT_TAG@.r@TAG_OFFSET@.g%h</param>

++++++ moolticute-1.00.1.r0.gf211d93.tar.gz -> 
moolticute-1.01.0.r0.g77100ea.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/README.md 
new/moolticute-1.01.0.r0.g77100ea/README.md
--- old/moolticute-1.00.1.r0.gf211d93/README.md 2022-12-01 00:09:56.000000000 
+0100
+++ new/moolticute-1.01.0.r0.g77100ea/README.md 2023-02-05 21:17:46.000000000 
+0100
@@ -32,6 +32,7 @@
 ##### Linux
  - Requires the qt-dbus module
  - Requires to install [udev 
rule](https://github.com/mooltipass/mooltipass-udev) for it
+   - Note: For Linux systems without systemd please refer to [dedicated 
section](#non-systemd-linux)
 
 Moolticute comes in two part on Linux:
   - A daemon that runs in background named moolticuted that proxy
@@ -96,6 +97,17 @@
             '';
 ```
 
+##### Non systemd Linux
+The main [udev rules](https://github.com/mooltipass/mooltipass-udev)
+relies on integration between systemd, systemd-login and systemd-udevd
+to automatically allow any user logged in to access mooltipass devices.
+This will not work on Linux ecosystem without systemd, one
+workaround is to change the `TAG+="uaccess"` to
+`GROUP="plugdev"` and add your interactive user to this group.
+
+Refer to [this
+issue](https://github.com/mooltipass/mooltipass-udev/pull/3) for more 
information.
+
 ### How to build
 
 For now, no binary releases are out yet. You will need to build the software 
by following the next step.
@@ -108,7 +120,7 @@
 
  - Download and install the Qt SDK from their [website](http://qt.io)
  - Start Qt-Creator
- - Open the main Moolticute.pro project file 
+ - Open the main Moolticute.pro project file
     - Note for Windows users: make sure that you select a "kit" that uses the 
MinGW compiler.
       Moolticute currently won't compile successfully when using the Microsoft 
Visual C++ compiler.
  - Click on the "play" button to build and run
@@ -143,6 +155,4 @@
 
 ### Licensing
 
-Moolticute is free software: you can redistribute it and/or modify it under 
the terms of the GNU Public License as published by the Free Software 
Foundation; either version 3 of the License, or (at your option) any later 
version. 
-       
- 
+Moolticute is free software: you can redistribute it and/or modify it under 
the terms of the GNU Public License as published by the Free Software 
Foundation; either version 3 of the License, or (at your option) any later 
version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/AppGui.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/AppGui.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/AppGui.cpp    2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/AppGui.cpp    2023-02-05 
21:17:46.000000000 +0100
@@ -137,7 +137,14 @@
     });
 
     QAction* quitAction = new QAction(tr("&Quit"), this);
+
+#ifdef Q_OS_MAC
+    // Since Qt6 quit is not exiting application properly on Mac
+    // daemon keeps running and prepareToQuit is not called
+    connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::exit, 
Qt::QueuedConnection);
+#else
     connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit, 
Qt::QueuedConnection);
+#endif
 
     QMenu *systrayMenu = new QMenu();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/BleDev.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/BleDev.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/BleDev.cpp    2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/BleDev.cpp    2023-02-05 
21:17:46.000000000 +0100
@@ -69,6 +69,10 @@
     {
         DeviceDetector::instance().shiftPressed();
     }
+    if (event->key() == Qt::Key_Control)
+    {
+        DeviceDetector::instance().ctrlPressed();
+    }
 }
 
 void BleDev::keyReleaseEvent(QKeyEvent *event)
@@ -77,6 +81,10 @@
     {
         DeviceDetector::instance().shiftReleased();
     }
+    if (event->key() == Qt::Key_Control)
+    {
+        DeviceDetector::instance().ctrlReleased();
+    }
 }
 
 void BleDev::initUITexts()
@@ -179,11 +187,16 @@
     }
     QSettings s;
 
+    bool skipFilePwdCheck = wsClient->get_status() == Common::NoBundle &&
+                                DeviceDetector::instance().isCtrlPressed();
+
     QString fileName = QFileDialog::getOpenFileName(this, tr("Select bundle 
file"),
                                             
s.value("last_used_path/bundle_dir", QDir::homePath()).toString(),
                                             "*.img");
 
+    // Due to file selection dialog opened, release events are not catched
     DeviceDetector::instance().shiftReleased();
+    DeviceDetector::instance().ctrlReleased();
 
     if (fileName.isEmpty())
     {
@@ -211,8 +224,9 @@
     }
 
     QString password = "";
-    if (!checkBundleFilePassword(QFileInfo{file}, password))
+    if (!skipFilePwdCheck && !checkBundleFilePassword(QFileInfo{file}, 
password))
     {
+        qCritical() << "Invalid bundle file password";
         return;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/moolticute-1.00.1.r0.gf211d93/src/CredentialsManagement.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/CredentialsManagement.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/CredentialsManagement.cpp     
2022-12-01 00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/CredentialsManagement.cpp     
2023-02-05 21:17:46.000000000 +0100
@@ -31,6 +31,9 @@
 #include "SettingsGuiBLE.h"
 #include "ParseDomain.h"
 
+const QString CredentialsManagement::INVALID_DOMAIN_TEXT =
+        tr("The following domains are invalid or private: 
<b><ul><li>%1</li></ul></b>They are not saved.");
+
 CredentialsManagement::CredentialsManagement(QWidget *parent) :
     QWidget(parent), ui(new Ui::CredentialsManagement), 
m_pAddedLoginItem(nullptr)
 {
@@ -185,7 +188,7 @@
     connect(ui->credentialTreeView, &CredentialView::collapsed, this, 
&CredentialsManagement::onItemCollapsed);
     connect(ui->pushButtonExpandAll, &QPushButton::clicked, 
ui->credentialTreeView, &CredentialView::onChangeExpandedState);
     connect(ui->credentialTreeView, &CredentialView::expandedStateChanged, 
this, &CredentialsManagement::onExpandedStateChanged);
-    connect(m_pCredModel, &CredentialModel::selectLoginItem, this, 
&CredentialsManagement::onSelectLoginItem, Qt::QueuedConnection);
+    connect(m_pCredModel, &CredentialModel::selectLoginItem, this, 
&CredentialsManagement::onSelectLoginItem);
 
     m_tSelectLoginTimer.setInterval(50);
     m_tSelectLoginTimer.setSingleShot(true);
@@ -533,6 +536,11 @@
 
     if (currentSelectionIndex.isValid())
         saveCredential(currentSelectionIndex);
+
+    if (!m_credentialLinkedAddr.isEmpty())
+    {
+        m_credentialLinkedAddr.clear();
+    }
 }
 
 void CredentialsManagement::saveSelectedTOTP()
@@ -634,6 +642,7 @@
 
 void CredentialsManagement::keyPressEvent(QKeyEvent *event)
 {
+    QWidget::keyPressEvent(event);
     if (wsClient->get_memMgmtMode() || !wsClient->isMPBLE())
     {
         return;
@@ -647,6 +656,7 @@
 
 void CredentialsManagement::keyReleaseEvent(QKeyEvent *event)
 {
+    QWidget::keyReleaseEvent(event);
     if (wsClient->get_memMgmtMode() || !wsClient->isMPBLE())
     {
         return;
@@ -1405,7 +1415,7 @@
     }
 }
 
-QString CredentialsManagement::processMultipleDomainsInput(const QString& 
service, const QString &domains)
+QString CredentialsManagement::processMultipleDomainsInput(const QString& 
service, const QString &domains, const bool disable_tld_check)
 {
 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
     auto splitBehavior = QString::SkipEmptyParts;
@@ -1414,6 +1424,7 @@
 #endif
     auto domainList = domains.split(MULT_DOMAIN_SEPARATOR, splitBehavior);
     QStringList validDomains;
+    QStringList invalidDomains;
     QString result = "";
     auto serviceDomain = service;
     if (serviceDomain.contains('.'))
@@ -1428,15 +1439,21 @@
             domain.prepend('.');
         }
         ParseDomain dom(serviceDomain + domain);
-        if (domain == dom.tld())
+        if (disable_tld_check || domain == dom.tld())
         {
             validDomains.append(domain);
         }
         else
         {
             qWarning() << "The following domain is not valid: " << domain;
+            invalidDomains.append(domain);
         }
     }
+    if (!invalidDomains.isEmpty())
+    {
+        QMessageBox::information(this, tr("Invalid domain"),
+                                
INVALID_DOMAIN_TEXT.arg(invalidDomains.join("</li><li>")));
+    }
     return validDomains.join(MULT_DOMAIN_SEPARATOR);
 }
 
@@ -1670,13 +1687,15 @@
                                 serviceNameChanged = true;
                             }
                         }
+                        QSettings s;
                         bool ok = false;
+                        bool disable_tld_check = 
s.value("settings/disable_tld_check", false).toBool();
                         QString text = QInputDialog::getText(this, 
tr("Multiple Domains for %1").arg(pServiceItem->name()),
                                                                  tr("Enter 
comma separated domain extensions:"), QLineEdit::Normal,
                                                                  
defaultDomains, &ok);
                         if (ok)
                         {
-                            text = processMultipleDomainsInput(serviceName, 
text);
+                            text = processMultipleDomainsInput(serviceName, 
text, disable_tld_check);
                             if (!text.isEmpty())
                             {
                                 pServiceItem->setMultipleDomains(text);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/moolticute-1.00.1.r0.gf211d93/src/CredentialsManagement.h 
new/moolticute-1.01.0.r0.g77100ea/src/CredentialsManagement.h
--- old/moolticute-1.00.1.r0.gf211d93/src/CredentialsManagement.h       
2022-12-01 00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/CredentialsManagement.h       
2023-02-05 21:17:46.000000000 +0100
@@ -54,8 +54,10 @@
 public slots:
     bool confirmDiscardUneditedCredentialChanges(const QModelIndex &proxyIndex 
= {});
     void saveChanges();
-    void keyPressEvent(QKeyEvent* event);
-    void keyReleaseEvent(QKeyEvent* event);
+
+protected:
+    virtual void keyPressEvent(QKeyEvent *event) override;
+    virtual void keyReleaseEvent(QKeyEvent *event) override;
 
 private slots:
     void enableCredentialsManagement(bool);
@@ -140,7 +142,7 @@
 
     void checkLinkingOnLoginSelected(const QModelIndex &srcIndex);
 
-    QString processMultipleDomainsInput(const QString& service, const QString 
&domains);
+    QString processMultipleDomainsInput(const QString& service, const QString 
&domains, const bool disable_tld_check);
 
     bool isUICategoryClean() const;
 
@@ -176,6 +178,7 @@
     static constexpr int MINI_PASSWORD_LENGTH = 31;
     static constexpr int BLE_PASSWORD_LENGTH = 64;
     static constexpr char MULT_DOMAIN_SEPARATOR = ',';
+    static const QString INVALID_DOMAIN_TEXT;
 
 signals:
     void wantEnterMemMode();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/moolticute-1.00.1.r0.gf211d93/src/CredentialsManagement.ui 
new/moolticute-1.01.0.r0.g77100ea/src/CredentialsManagement.ui
--- old/moolticute-1.00.1.r0.gf211d93/src/CredentialsManagement.ui      
2022-12-01 00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/CredentialsManagement.ui      
2023-02-05 21:17:46.000000000 +0100
@@ -54,14 +54,14 @@
          </widget>
         </item>
         <item row="1" column="1">
-         <widget class="QLineEdit" name="addCredLoginInput">
+         <widget class="SimpleLineEdit" name="addCredLoginInput">
           <property name="maxLength">
            <number>62</number>
           </property>
          </widget>
         </item>
         <item row="1" column="0">
-         <widget class="QLineEdit" name="addCredServiceInput">
+         <widget class="SimpleLineEdit" name="addCredServiceInput">
           <property name="maxLength">
            <number>57</number>
           </property>
@@ -1020,6 +1020,11 @@
   </customwidget>
   <customwidget>
    <class>LockedPasswordLineEdit</class>
+   <extends>SimpleLineEdit</extends>
+   <header>PasswordLineEdit.h</header>
+  </customwidget>
+  <customwidget>
+   <class>SimpleLineEdit</class>
    <extends>QLineEdit</extends>
    <header>PasswordLineEdit.h</header>
   </customwidget>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/DeviceDetector.h 
new/moolticute-1.01.0.r0.g77100ea/src/DeviceDetector.h
--- old/moolticute-1.00.1.r0.gf211d93/src/DeviceDetector.h      2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/DeviceDetector.h      2023-02-05 
21:17:46.000000000 +0100
@@ -40,6 +40,9 @@
     void shiftPressed() { m_isShiftPressed = true; }
     void shiftReleased() { m_isShiftPressed = false; }
     bool isShiftPressed() const { return m_isShiftPressed; }
+    void ctrlPressed() { m_isCtrlPressed = true; }
+    void ctrlReleased() { m_isCtrlPressed = false; }
+    bool isCtrlPressed() const { return m_isCtrlPressed; }
 
 signals:
     void deviceChanged(Common::MPHwVersion newDevType);
@@ -53,6 +56,7 @@
     bool m_isConnectedWithBluetooth = false;
     quint8 m_battery = 0;
     bool m_isShiftPressed = false;
+    bool m_isCtrlPressed = false;
 };
 
 #endif // DEVICEDETECTOR_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/moolticute-1.00.1.r0.gf211d93/src/FilesManagement.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/FilesManagement.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/FilesManagement.cpp   2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/FilesManagement.cpp   2023-02-05 
21:17:46.000000000 +0100
@@ -578,7 +578,8 @@
     //Force all service names to lowercase
     service = service.toLower();
 
-    qint64 maxSize = MP_MAX_FILE_SIZE;
+    // For BLE increase max file size to 20kB
+    qint64 maxSize = DeviceDetector::instance().isBle() ? 2*MP_MAX_FILE_SIZE : 
MP_MAX_FILE_SIZE;
     if (service == MC_SSH_SERVICE)
         maxSize = MP_MAX_SSH_SIZE;
     QFileInfo fi(filename);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/MPDevice.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/MPDevice.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/MPDevice.cpp  2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/MPDevice.cpp  2023-02-05 
21:17:46.000000000 +0100
@@ -4917,7 +4917,7 @@
     if (!isBLE())
     {
         currentDataNode.resize(MP_DATA_HEADER_SIZE);
-        qToBigEndian(nodeData.size(), (quint8 *)currentDataNode.data());
+        qToBigEndian<quint32>(nodeData.size(), (quint8 
*)currentDataNode.data());
     }
     currentDataNode.append(nodeData);
 
@@ -6739,7 +6739,7 @@
            /* Create new node with null address and virtual address set to our 
counter value */
            MPNode* newNodePt = 
pMesProt->createMPNode(QByteArray(getParentNodeSize(), 0), this, QByteArray(), 
newAddressesNeededCounter);
            newNodePt->setType(MPNode::NodeParent);
-           newNodePt->setLoginNodeData(importNodes[i]->getNodeFlags(), 
importNodes[i]->getLoginNodeData());
+           newNodePt->setDataNodeData(importNodes[i]->getNodeFlags(), 
importNodes[i]->getDataNodeData());
            newNodePt->setMergeTagged();
 
            /* Add node to list */
@@ -6936,62 +6936,16 @@
             }
         }
 
-        /* Now we check all our parents and childs for non merge tag */
-        QListIterator<MPNode*> j(dataNodes);
-        while (j.hasNext())
+        if (!finishImportDataNodes(stringError, Common::DATA_ADDR_IDX))
         {
-            MPNode* nodeItem = j.next();
-
-            /* No need to check for merge tagged for parent, as it'll 
automatically be removed if it doesn't have any child */
-            QByteArray curChildNodeAddr = nodeItem->getStartChildAddress();
-            bool deleteDataNode = false;
-
-            /* Special case: no child */
-            if (curChildNodeAddr == MPNode::EmptyAddress)
-            {
-                /* Remove parent */
-                qDebug() << "Empty data parent " << nodeItem->getService() << 
" detected, deleting it...";
-                removeEmptyParentFromDB(nodeItem, true, Common::CRED_ADDR_IDX, 
Common::DATA_ADDR_IDX);
-            }
-
-            /* Check every children */
-            while (curChildNodeAddr != MPNode::EmptyAddress)
-            {
-                MPNode* curNode = findNodeWithAddressInList(dataChildNodes, 
curChildNodeAddr);
-
-                /* Safety checks */
-                if (!curNode)
-                {
-                    qCritical() << "Couldn't find child node in list (error in 
algo?)";
-                    stringError = "Moolticute Internal Error: Please Contact 
The Team (IFM#2)";
-                    cleanImportedVars();
-                    return false;
-                }
-
-                /* Next item */
-                curChildNodeAddr = curNode->getNextDataAddress();
-
-                /* Marked for deletion? */
-                if (!curNode->getMergeTagged())
-                {
-                    /* First child? */
-                    if (curNode->getAddress() == 
nodeItem->getStartChildAddress())
-                    {
-                        deleteDataNode = true;
-                    }
-
-                    /* Delete child */
-                    dataChildNodes.removeOne(curNode);
-                    nodeItem->removeChild(curNode);
-                    delete(curNode);
-                }
-            }
+            return false;
+        }
 
-            /* If parent node is marked for deletion */
-            if(deleteDataNode)
+        if (isBLE())
+        {
+            if (!finishImportDataNodes(stringError, Common::NOTE_ADDR_IDX))
             {
-                nodeItem->setStartChildAddress(MPNode::EmptyAddress);
-                removeEmptyParentFromDB(nodeItem, true);
+                return false;
             }
         }
     }
@@ -7116,6 +7070,72 @@
         }
     }
     return true;
+}
+
+bool MPDevice::finishImportDataNodes(QString &stringError, 
Common::DataAddressType addrType)
+{
+    const bool isFile = Common::DATA_ADDR_IDX == addrType;
+    NodeList& nodes = isFile ? dataNodes : notesLoginNodes;
+    NodeList& childNodes = isFile? dataChildNodes : notesLoginChildNodes;
+    /* Now we check all our parents and childs for non merge tag */
+    QListIterator<MPNode*> j(nodes);
+    while (j.hasNext())
+    {
+        MPNode* nodeItem = j.next();
+
+        /* No need to check for merge tagged for parent, as it'll 
automatically be removed if it doesn't have any child */
+        QByteArray curChildNodeAddr = nodeItem->getStartChildAddress();
+        bool deleteDataNode = false;
+
+        /* Special case: no child */
+        if (curChildNodeAddr == MPNode::EmptyAddress)
+        {
+            /* Remove parent */
+            qDebug() << "Empty data parent " << nodeItem->getService() << " 
detected, deleting it...";
+            removeEmptyParentFromDB(nodeItem, true, Common::CRED_ADDR_IDX 
/*not used*/, addrType);
+        }
+
+        /* Check every children */
+        while (curChildNodeAddr != MPNode::EmptyAddress)
+        {
+            MPNode* curNode = findNodeWithAddressInList(childNodes, 
curChildNodeAddr);
+
+            /* Safety checks */
+            if (!curNode)
+            {
+                qCritical() << "Couldn't find child node in list (error in 
algo?)";
+                stringError = "Moolticute Internal Error: Please Contact The 
Team (IFM#2)";
+                cleanImportedVars();
+                return false;
+            }
+
+            /* Next item */
+            curChildNodeAddr = curNode->getNextDataAddress();
+
+            /* Marked for deletion? */
+            if (!curNode->getMergeTagged())
+            {
+                /* First child? */
+                if (curNode->getAddress() == nodeItem->getStartChildAddress())
+                {
+                    deleteDataNode = true;
+                }
+
+                /* Delete child */
+                childNodes.removeOne(curNode);
+                nodeItem->removeChild(curNode);
+                delete(curNode);
+            }
+        }
+
+        /* If parent node is marked for deletion */
+        if(deleteDataNode)
+        {
+            nodeItem->setStartChildAddress(MPNode::EmptyAddress);
+            removeEmptyParentFromDB(nodeItem, true, Common::CRED_ADDR_IDX 
/*not used*/, Common::NOTE_ADDR_IDX);
+        }
+    }
+    return true;
 }
 
 void MPDevice::loadFreeAddresses(AsyncJobs *jobs, const QByteArray 
&addressFrom, bool discardFirstAddr, const MPDeviceProgressCb &cbProgress)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/MPDevice.h 
new/moolticute-1.01.0.r0.g77100ea/src/MPDevice.h
--- old/moolticute-1.00.1.r0.gf211d93/src/MPDevice.h    2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/MPDevice.h    2023-02-05 
21:17:46.000000000 +0100
@@ -329,6 +329,7 @@
     void deletePossibleFavorite(QByteArray parentAddr, QByteArray childAddr);
     bool finishImportFileMerging(QString &stringError, bool noDelete);
     bool finishImportLoginNodes(QString &stringError, Common::AddressType 
addrType);
+    bool finishImportDataNodes(QString &stringError, Common::DataAddressType 
addrType);
     QByteArray getNextNodeAddressInMemory(const QByteArray &address);
     quint16 getFlashPageFromAddress(const QByteArray &address);
     MPNode *findNodeWithServiceInList(const QString &service, 
Common::AddressType addrType = Common::CRED_ADDR_IDX);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/moolticute-1.00.1.r0.gf211d93/src/MPDeviceBleImpl.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/MPDeviceBleImpl.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/MPDeviceBleImpl.cpp   2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/MPDeviceBleImpl.cpp   2023-02-05 
21:17:46.000000000 +0100
@@ -23,7 +23,8 @@
         MPCmd::CANCEL_USER_REQUEST,
         MPCmd::INFORM_LOCKED,
         MPCmd::INFORM_UNLOCKED,
-        MPCmd::SET_DATE};
+        MPCmd::SET_DATE
+    };
 }
 
 bool MPDeviceBleImpl::isFirstPacket(const QByteArray &data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/MainWindow.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/MainWindow.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/MainWindow.cpp        2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/MainWindow.cpp        2023-02-05 
21:17:46.000000000 +0100
@@ -29,7 +29,6 @@
 #include "DeviceDetector.h"
 #include "SystemNotifications/SystemNotification.h"
 
-#include "qtcsv/stringdata.h"
 #include "qtcsv/reader.h"
 
 const QString MainWindow::NONE_STRING = tr("None");
@@ -40,7 +39,7 @@
 const QString MainWindow::MANUAL_STRING = "<a href=\"%1\">" + tr("User 
Manual") + "</a>";
 const QString MainWindow::BLE_MANUAL_URL = 
"https://raw.githubusercontent.com/mooltipass/minible/master/MooltipassMiniBLEUserManual.pdf";;
 const QString MainWindow::MINI_MANUAL_URL = 
"https://raw.githubusercontent.com/limpkin/mooltipass/master/user_manual_mini.pdf";;
-const QString MainWindow::BUNDLE_OUTDATED_TEXT = tr("New bundle update 
available <a 
href=\"https://www.themooltipass.com/updates/index.php?sn=%1&bundlev=%2\";>here.</a>");
+const QString MainWindow::BUNDLE_OUTDATED_TEXT = tr("Bundle v%1 is available 
<a 
href=\"https://www.themooltipass.com/updates/index.php?sn=%2&bundlev=%3\";>here</a>");
 const QString MainWindow::SERIAL_STR_START = "MOOLTIP";
 
 void MainWindow::initHelpLabels()
@@ -167,9 +166,6 @@
     ui->pushButtonNotes->setVisible(false);
 
     unsigned int keyModifiers = Qt::SHIFT;
-#ifndef Q_OS_MACOS
-    keyModifiers |= Qt::CTRL;
-#endif
 
     m_FilesAndSSHKeysTabsShortcut = new QShortcut(QKeySequence(keyModifiers | 
Qt::Key_F1), this);
     setKeysTabVisibleOnDemand(bSSHKeysTabVisibleOnDemand);
@@ -294,15 +290,23 @@
             [this]()
             {
                 ui->lineEdit_AvailableUsers->setText("");
+                m_firstBatteryPctReceived = BatteryNotiStatus::NO_STATUS;
             });
     connect(wsClient, &WSClient::updateBatteryPercent,
             [this](int battery)
             {
                 DeviceDetector::instance().setBattery(battery);
                 ui->pbBleBattery->setValue(battery);
-                if (battery < BATTERY_WARNING_LIMIT && 
!ui->label_charging->isVisible())
+                if (battery < BATTERY_WARNING_LIMIT && 
!ui->label_charging->isVisible() &&
+                        BatteryNotiStatus::VALID_BATTERY_RECIEVED == 
m_firstBatteryPctReceived)
                 {
                     SystemNotification::instance().createNotification(tr("Low 
Battery"), tr("Battery is below %1%, please charge your 
Mooltipass.").arg(BATTERY_WARNING_LIMIT));
+                    m_firstBatteryPctReceived = 
BatteryNotiStatus::LOW_BATTERY_DISPLAYED;
+                }
+                // Only display low battery warning after we received a valid 
battery pct
+                if (BatteryNotiStatus::NO_STATUS == m_firstBatteryPctReceived)
+                {
+                    m_firstBatteryPctReceived = 
BatteryNotiStatus::VALID_BATTERY_RECIEVED;
                 }
             });
 
@@ -316,6 +320,7 @@
                 else
                 {
                     ui->label_charging->hide();
+                    m_firstBatteryPctReceived = BatteryNotiStatus::NO_STATUS;
                 }
             });
 
@@ -504,7 +509,7 @@
         {
             QString bundleStr = QString::number(wsClient->get_bundleVersion());
             setSecurityChallengeText(serialStr, bundleStr);
-            
ui->labelBundleOutdatedText->setText(BUNDLE_OUTDATED_TEXT.arg(serial).arg(bundleStr));
+            
ui->labelBundleOutdatedText->setText(BUNDLE_OUTDATED_TEXT.arg(Common::BLE_LATEST_BUNDLE_VERSION).arg(serial).arg(bundleStr));
         }
         else
         {
@@ -514,7 +519,7 @@
     connect(wsClient, &WSClient::bundleVersionChanged, [this](int 
bundleVersion)
     {
         auto serial = wsClient->get_hwSerial();
-        
ui->labelBundleOutdatedText->setText(BUNDLE_OUTDATED_TEXT.arg(serial).arg(bundleVersion));
+        
ui->labelBundleOutdatedText->setText(BUNDLE_OUTDATED_TEXT.arg(Common::BLE_LATEST_BUNDLE_VERSION).arg(serial).arg(bundleVersion));
         if (wsClient->isMPBLE())
         {
             QString serialStr = serial > 0 ? QString::number(serial) : "XXXX";
@@ -659,6 +664,7 @@
 
     //Check is ssh agent opt has to be checked
     
ui->checkBoxSSHAgent->setChecked(s.value("settings/auto_start_ssh").toBool());
+    
ui->checkBoxTLDCheck->setChecked(s.value("settings/disable_tld_check").toBool());
     ui->lineEditSshArgs->setText(s.value("settings/ssh_args").toString());
 
     ui->scrollArea->setStyleSheet("QScrollArea { background-color:transparent; 
}");
@@ -685,6 +691,8 @@
 
     ui->labelBundleOutdatedWarning->hide();
     
ui->labelBundleOutdatedWarning->setPixmap(AppGui::qtAwesome()->icon(fa::warning).pixmap(QSize(20,
 20)));
+    ui->labelBundleOutdatedWarning2->hide();
+    
ui->labelBundleOutdatedWarning2->setPixmap(AppGui::qtAwesome()->icon(fa::warning).pixmap(QSize(20,
 20)));
     ui->labelBundleOutdatedText->hide();
     ui->labelBundleOutdatedText->setTextFormat(Qt::RichText);
     
ui->labelBundleOutdatedText->setTextInteractionFlags(Qt::TextBrowserInteraction);
@@ -1412,7 +1420,7 @@
         dialogLog->appendData(logdata);
     logBuffer.append(logdata);
 
-    const int maxsz = 100 * 1024;
+    const int maxsz = 1000 * 1024;
 
     if (logBuffer.size() > maxsz)
         logBuffer = logBuffer.right(maxsz);
@@ -1456,6 +1464,12 @@
     s.setValue("settings/auto_start_ssh", ui->checkBoxSSHAgent->isChecked());
 }
 
+void MainWindow::on_checkBoxTLDCheck_stateChanged(int)
+{
+    QSettings s;
+    s.setValue("settings/disable_tld_check", 
ui->checkBoxTLDCheck->isChecked()); 
+}
+
 void MainWindow::on_pushButtonExportFile_clicked()
 {
     wsClient->exportDbFile(Common::SIMPLE_CRYPT);
@@ -1549,6 +1563,7 @@
         if (wsClient->isMPBLE())
         {
             wsClient->sendGetUserCategories();
+            wsClient->sendFetchNotes();
         }
         QMessageBox::information(this, tr("Moolticute"), tr("Successfully 
imported and merged database into the device."));
     }
@@ -1838,14 +1853,16 @@
         ui->pushButtonNotes->setVisible(wsClient->get_bundleVersion() >= 1);
         if (wsClient->get_bundleVersion() < Common::BLE_LATEST_BUNDLE_VERSION)
         {
-            
ui->labelBundleOutdatedText->setText(BUNDLE_OUTDATED_TEXT.arg(wsClient->get_hwSerial()).arg(wsClient->get_bundleVersion()));
+            
ui->labelBundleOutdatedText->setText(BUNDLE_OUTDATED_TEXT.arg(Common::BLE_LATEST_BUNDLE_VERSION).arg(wsClient->get_hwSerial()).arg(wsClient->get_bundleVersion()));
             ui->labelBundleOutdatedText->show();
             ui->labelBundleOutdatedWarning->show();
+            ui->labelBundleOutdatedWarning2->show();
         }
         else
         {
             ui->labelBundleOutdatedText->hide();
             ui->labelBundleOutdatedWarning->hide();
+            ui->labelBundleOutdatedWarning2->hide();
         }
     }
     else
@@ -1854,6 +1871,7 @@
         ui->labelBundleVersionValue->hide();
         ui->labelBundleOutdatedText->hide();
         ui->labelBundleOutdatedWarning->hide();
+        ui->labelBundleOutdatedWarning2->hide();
     }
 }
 
@@ -2389,10 +2407,15 @@
 
 void MainWindow::keyPressEvent(QKeyEvent *event)
 {
-    if (event->key() == Qt::Key_Control)
+    QMainWindow::keyPressEvent(event);
+    if (event->key() == Qt::Key_Shift)
     {
         DeviceDetector::instance().shiftPressed();
     }
+    if (event->key() == Qt::Key_Control)
+    {
+        DeviceDetector::instance().ctrlPressed();
+    }
     if (!ui->tutorialWidget->isTutorialFinished() && event->key() == 
Qt::Key_Escape)
     {
         ui->tutorialWidget->onExitClicked();
@@ -2401,10 +2424,15 @@
 
 void MainWindow::keyReleaseEvent(QKeyEvent *event)
 {
-    if (event->key() == Qt::Key_Control)
+    QMainWindow::keyReleaseEvent(event);
+    if (event->key() == Qt::Key_Shift)
     {
         DeviceDetector::instance().shiftReleased();
     }
+    if (event->key() == Qt::Key_Control)
+    {
+        DeviceDetector::instance().ctrlReleased();
+    }
 }
 
 void MainWindow::on_checkBoxBackupNotification_stateChanged(int)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/MainWindow.h 
new/moolticute-1.01.0.r0.g77100ea/src/MainWindow.h
--- old/moolticute-1.00.1.r0.gf211d93/src/MainWindow.h  2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/MainWindow.h  2023-02-05 
21:17:46.000000000 +0100
@@ -128,6 +128,7 @@
     void on_pushButtonAutoStart_clicked();
 
     void on_checkBoxSSHAgent_stateChanged(int arg1);
+    void on_checkBoxTLDCheck_stateChanged(int arg1);
 
     void on_pushButtonExportFile_clicked();
     void on_pushButtonImportFile_clicked();
@@ -302,6 +303,15 @@
 
     bool m_notesFetched = false;
 
+    enum class BatteryNotiStatus
+    {
+        NO_STATUS,
+        VALID_BATTERY_RECIEVED,
+        LOW_BATTERY_DISPLAYED
+    };
+
+    BatteryNotiStatus m_firstBatteryPctReceived = BatteryNotiStatus::NO_STATUS;
+
     bool m_computerUnlocked = true;
     struct LockUnlockItem
     {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/MainWindow.ui 
new/moolticute-1.01.0.r0.g77100ea/src/MainWindow.ui
--- old/moolticute-1.00.1.r0.gf211d93/src/MainWindow.ui 2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/MainWindow.ui 2023-02-05 
21:17:46.000000000 +0100
@@ -3535,6 +3535,18 @@
               </widget>
              </item>
              <item>
+              <widget class="QLabel" name="labelBundleOutdatedWarning2">
+               <property name="font">
+                <font>
+                 <pointsize>10</pointsize>
+                </font>
+               </property>
+               <property name="text">
+                <string/>
+               </property>
+              </widget>
+             </item>
+             <item>
               <spacer name="horizontalSpacer_58">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
@@ -4051,6 +4063,37 @@
                   </property>
                  </widget>
                 </item>
+               </layout>
+              </item>
+              <item>
+               <layout class="QHBoxLayout" name="horizontalLayout_15">
+                <item>
+                 <widget class="QLabel" name="label_27">
+                  <property name="text">
+                   <string>Allow to use invalid or private TLDs</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <spacer name="horizontalSpacer_63">
+                  <property name="orientation">
+                   <enum>Qt::Horizontal</enum>
+                  </property>
+                  <property name="sizeHint" stdset="0">
+                   <size>
+                    <width>40</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </spacer>
+                </item>
+                <item>
+                 <widget class="QCheckBox" name="checkBoxTLDCheck">
+                  <property name="text">
+                   <string>Disable TLD check</string>
+                  </property>
+                 </widget>
+                </item>
                </layout>
               </item>
               <item>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/moolticute-1.00.1.r0.gf211d93/src/PasswordLineEdit.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/PasswordLineEdit.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/PasswordLineEdit.cpp  2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/PasswordLineEdit.cpp  2023-02-05 
21:17:46.000000000 +0100
@@ -48,7 +48,7 @@
     "}"
 
 PasswordLineEdit::PasswordLineEdit(QWidget* parent):
-    QLineEdit(parent),
+    SimpleLineEdit(parent),
     m_passwordProfilesModel(nullptr),
     m_passwordOptionsPopup(nullptr)
 
@@ -515,3 +515,17 @@
         addAction(pwdAction, QLineEdit::TrailingPosition);
     }
 }
+
+SimpleLineEdit::SimpleLineEdit(QWidget *parent)
+    : QLineEdit{parent}
+{
+
+}
+
+void SimpleLineEdit::keyReleaseEvent(QKeyEvent *event)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    QLineEdit::keyReleaseEvent(event);
+#endif
+    QWidget::keyReleaseEvent(event);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/PasswordLineEdit.h 
new/moolticute-1.01.0.r0.g77100ea/src/PasswordLineEdit.h
--- old/moolticute-1.00.1.r0.gf211d93/src/PasswordLineEdit.h    2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/PasswordLineEdit.h    2023-02-05 
21:17:46.000000000 +0100
@@ -70,7 +70,24 @@
 
 
 class PasswordOptionsPopup;
-class PasswordLineEdit : public QLineEdit
+
+/**
+ * @brief The SimpleLineEdit class
+ * keyReleaseEvent is overwritten for QLineEdit in Qt6, but overwritten
+ * parent function is not called, so event is not delegated from QLineEdit,
+ * to fix this we call keyReleaseEvent for parent (QWidget) here.
+ */
+class SimpleLineEdit : public QLineEdit
+{
+    Q_OBJECT
+public:
+    SimpleLineEdit(QWidget* parent = nullptr);
+
+protected:
+    virtual void keyReleaseEvent(QKeyEvent *event) override;
+};
+
+class PasswordLineEdit : public SimpleLineEdit
 {
     Q_OBJECT
 public:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/moolticute-1.00.1.r0.gf211d93/src/WSServerCon.cpp 
new/moolticute-1.01.0.r0.g77100ea/src/WSServerCon.cpp
--- old/moolticute-1.00.1.r0.gf211d93/src/WSServerCon.cpp       2022-12-01 
00:09:56.000000000 +0100
+++ new/moolticute-1.01.0.r0.g77100ea/src/WSServerCon.cpp       2023-02-05 
21:17:46.000000000 +0100
@@ -401,7 +401,8 @@
             return;
         }
 
-        int maxSize = MP_MAX_FILE_SIZE;
+        // For BLE increase max file size to 20kB
+        int maxSize = mpdevice->isBLE() ? 2*MP_MAX_FILE_SIZE : 
MP_MAX_FILE_SIZE;
         if (service.toLower() == MC_SSH_SERVICE)
             maxSize = MP_MAX_SSH_SIZE;
         if (data.size() > maxSize)

Reply via email to