Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package qt6-networkauth for openSUSE:Factory 
checked in at 2026-03-28 20:12:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qt6-networkauth (Old)
 and      /work/SRC/openSUSE:Factory/.qt6-networkauth.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "qt6-networkauth"

Sat Mar 28 20:12:39 2026 rev:41 rq:1342801 version:6.11.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/qt6-networkauth/qt6-networkauth.changes  
2026-02-03 21:27:39.538960177 +0100
+++ 
/work/SRC/openSUSE:Factory/.qt6-networkauth.new.8177/qt6-networkauth.changes    
    2026-03-28 20:13:03.884713871 +0100
@@ -1,0 +2,6 @@
+Mon Mar 23 10:37:50 UTC 2026 - Christophe Marin <[email protected]>
+
+- Update to 6.11.0
+  https://www.qt.io/blog/qt-6.11-released
+
+-------------------------------------------------------------------

Old:
----
  qtnetworkauth-everywhere-src-6.10.2.tar.xz

New:
----
  qtnetworkauth-everywhere-src-6.11.0.tar.xz

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

Other differences:
------------------
++++++ qt6-networkauth.spec ++++++
--- /var/tmp/diff_new_pack.BuslpR/_old  2026-03-28 20:13:04.620744247 +0100
+++ /var/tmp/diff_new_pack.BuslpR/_new  2026-03-28 20:13:04.624744413 +0100
@@ -16,8 +16,8 @@
 #
 
 
-%define real_version 6.10.2
-%define short_version 6.10
+%define real_version 6.11.0
+%define short_version 6.11
 %define short_name qtnetworkauth
 %define tar_name qtnetworkauth-everywhere-src
 %define tar_suffix %{nil}
@@ -28,7 +28,7 @@
 %endif
 #
 Name:           qt6-networkauth%{?pkg_suffix}
-Version:        6.10.2
+Version:        6.11.0
 Release:        0
 Summary:        Set of APIs to obtain limited access to online accounts and 
HTTP services
 License:        GPL-3.0-only WITH Qt-GPL-exception-1.0

++++++ qtnetworkauth-everywhere-src-6.10.2.tar.xz -> 
qtnetworkauth-everywhere-src-6.11.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtnetworkauth-everywhere-src-6.10.2/.cmake.conf 
new/qtnetworkauth-everywhere-src-6.11.0/.cmake.conf
--- old/qtnetworkauth-everywhere-src-6.10.2/.cmake.conf 2026-01-20 
05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/.cmake.conf 2026-03-09 
10:39:33.000000000 +0100
@@ -1,7 +1,8 @@
-set(QT_REPO_MODULE_VERSION "6.10.2")
+set(QT_REPO_MODULE_VERSION "6.11.0")
 set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
 set(QT_EXTRA_INTERNAL_TARGET_DEFINES
     "QT_NO_CONTEXTLESS_CONNECT=1"
     "QT_NO_FOREACH=1"
     "QT_NO_QASCONST=1"
+    "QT_NO_URL_CAST_FROM_STRING=1"
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtnetworkauth-everywhere-src-6.10.2/.tag 
new/qtnetworkauth-everywhere-src-6.11.0/.tag
--- old/qtnetworkauth-everywhere-src-6.10.2/.tag        2026-01-20 
05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/.tag        2026-03-09 
10:39:33.000000000 +0100
@@ -1 +1 @@
-b3999f9967d65320369bb96b0ae91d810fd3fc38
+4af2f29b09c0e6e80bb99fb2360a8c9395ee3a1d
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtnetworkauth-everywhere-src-6.10.2/CMakeLists.txt 
new/qtnetworkauth-everywhere-src-6.11.0/CMakeLists.txt
--- old/qtnetworkauth-everywhere-src-6.10.2/CMakeLists.txt      2026-01-20 
05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/CMakeLists.txt      2026-03-09 
10:39:33.000000000 +0100
@@ -13,10 +13,15 @@
     LANGUAGES CXX C
 )
 
-find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals 
Core Network) # special case
-find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS Widgets 
Gui) # special case
+find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals)
+
+# This should be called as early as possible, just after 
find_package(BuildInternals) where it is
+# defined.
 qt_internal_project_setup()
 
+find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Network)
+find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS Widgets 
Gui)
+
 if(NOT TARGET Qt::Network)
     message(NOTICE "Skipping the build as the condition \"TARGET Qt::Network\" 
is not met.")
     return()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtnetworkauth-everywhere-src-6.10.2/REUSE.toml 
new/qtnetworkauth-everywhere-src-6.11.0/REUSE.toml
--- old/qtnetworkauth-everywhere-src-6.10.2/REUSE.toml  2026-01-20 
05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/REUSE.toml  2026-03-09 
10:39:33.000000000 +0100
@@ -4,27 +4,27 @@
 path = ["**/.gitattributes", "**.gitignore", "**.gitreview"]
 precedence = "closest"
 comment = "infrastructure"
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
 
 [[annotations]]
 path = ["tests/**"]
 precedence = "closest"
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
 
 [[annotations]]
 path = [".tag", ".cmake.conf", "**.yaml", "**.pro", "**ci_config_linux.json"]
 precedence = "closest"
 comment = "build system"
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "BSD-3-Clause"
 
 [[annotations]]
 path = ["examples/**"]
 comment = "this must be after the build system table because example and 
snippets take precedence over build system"
 precedence = "closest"
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
 
 [[annotations]]
@@ -32,18 +32,18 @@
         "src/oauth/doc/images/**.webp"]
 comment = "documentation"
 precedence = "closest"
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR 
GFDL-1.3-no-invariants-only"
 
 [[annotations]]
 path = ["**.toml", "licenseRule.json"]
 precedence = "override"
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
 
 [[annotations]]
 path = ["**/qt_attribution.json"]
 precedence = "override"
 comment = "not necessary but ready if such a file is added."
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR 
GFDL-1.3-no-invariants-only"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/dependencies.yaml 
new/qtnetworkauth-everywhere-src-6.11.0/dependencies.yaml
--- old/qtnetworkauth-everywhere-src-6.10.2/dependencies.yaml   2026-01-20 
05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/dependencies.yaml   2026-03-09 
10:39:33.000000000 +0100
@@ -1,4 +1,4 @@
 dependencies:
   ../qtbase:
-    ref: 000d6c62f7880bb8d3054724e8da0b8ae244130e
+    ref: 8ba7ea4b77a4b8f1948760221e264917ddc9e1c8
     required: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtnetworkauth-everywhere-src-6.10.2/dist/REUSE.toml 
new/qtnetworkauth-everywhere-src-6.11.0/dist/REUSE.toml
--- old/qtnetworkauth-everywhere-src-6.10.2/dist/REUSE.toml     2026-01-20 
05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/dist/REUSE.toml     2026-03-09 
10:39:33.000000000 +0100
@@ -4,5 +4,5 @@
 path = ["**"]
 precedence = "override"
 comment = "Licensed as documentation."
-SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR 
GFDL-1.3-no-invariants-only"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/CMakeLists.txt 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/CMakeLists.txt
--- old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/CMakeLists.txt    
2026-01-20 05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/CMakeLists.txt    
2026-03-09 10:39:33.000000000 +0100
@@ -33,6 +33,7 @@
 qt_internal_extend_target(NetworkAuth CONDITION 
QT_FEATURE_urischeme_replyhandler
     SOURCES
         qoauthurischemereplyhandler.cpp qoauthurischemereplyhandler.h
+        qoauthurischemereplyhandler_p.h
     LIBRARIES
         Qt::Gui
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qabstractoauth.cpp 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qabstractoauth.cpp
--- old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qabstractoauth.cpp        
2026-01-20 05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qabstractoauth.cpp        
2026-03-09 10:39:33.000000000 +0100
@@ -373,6 +373,13 @@
 {}
 
 /*!
+    \property QAbstractOAuth::clientIdentifier
+
+    This property holds the client identifier used in the authentication 
process.
+
+    \sa setClientIdentifier()
+*/
+/*!
     Returns the current client identifier used in the authentication
     process.
 
@@ -399,6 +406,13 @@
 }
 
 /*!
+    \property QAbstractOAuth::token
+
+    This property holds the token used to sign authenticated requests.
+
+    \sa setToken()
+*/
+/*!
     Returns the token used to sign the authenticated requests.
 
     \sa setToken()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qabstractoauth2.cpp 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qabstractoauth2.cpp
--- old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qabstractoauth2.cpp       
2026-01-20 05:15:31.000000000 +0100
+++ new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qabstractoauth2.cpp       
2026-03-09 10:39:33.000000000 +0100
@@ -771,10 +771,11 @@
         qCWarning(loggingCategory, "Authorization stage: AuthenticationError: 
%ls(%ls): %ls",
                   qUtf16Printable(error), qUtf16Printable(uri), 
qUtf16Printable(description));
 
+        const QUrl url = QUrl{uri};
 #if QT_DEPRECATED_SINCE(6, 13)
-        QT_IGNORE_DEPRECATIONS(Q_EMIT q->error(error, description, uri);)
+        QT_IGNORE_DEPRECATIONS(Q_EMIT q->error(error, description, url);)
 #endif
-        Q_EMIT q->serverReportedErrorOccurred(error, description, uri);
+        Q_EMIT q->serverReportedErrorOccurred(error, description, url);
 
         // Emit also requestFailed() so that it is a signal for all errors
         emit q->requestFailed(QAbstractOAuth::Error::ServerError);
@@ -1324,6 +1325,16 @@
 }
 
 /*!
+    \property QAbstractOAuth2::refreshToken
+
+    This property holds the refresh token used to obtain new access tokens.
+
+    Refresh tokens usually have longer lifespans than access tokens,
+    so it makes sense to save them for later use.
+
+    \sa setRefreshToken()
+*/
+/*!
     \brief Gets the current refresh token.
 
     Refresh tokens usually have longer lifespans than access tokens,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qoauth2deviceauthorizationflow.cpp
 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qoauth2deviceauthorizationflow.cpp
--- 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qoauth2deviceauthorizationflow.cpp
        2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qoauth2deviceauthorizationflow.cpp
        2026-03-09 10:39:33.000000000 +0100
@@ -159,7 +159,7 @@
 
 QOAuth2DeviceAuthorizationFlowPrivate::QOAuth2DeviceAuthorizationFlowPrivate(
     QNetworkAccessManager *manager)
-    : QAbstractOAuth2Private(std::make_pair(QString(), QString()), QString(), 
manager)
+    : QAbstractOAuth2Private(std::make_pair(QString(), QString()), QUrl(), 
manager)
 {
 }
 
@@ -317,7 +317,7 @@
         // https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
         const auto error = data.value(QtOAuth2RfcKeywords::error).toString();
         const auto description = 
data.value(QtOAuth2RfcKeywords::errorDescription).toString();
-        const auto uri = data.value(QtOAuth2RfcKeywords::errorUri).toString();
+        const QUrl uri{data.value(QtOAuth2RfcKeywords::errorUri).toString()};
         qCDebug(loggingCategory) << "Token acquisition failed:" << error << 
description;
 #if QT_DEPRECATED_SINCE(6, 13)
         QT_IGNORE_DEPRECATIONS(Q_EMIT q->error(error, description, uri);)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qoauthurischemereplyhandler.cpp
 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qoauthurischemereplyhandler.cpp
--- 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qoauthurischemereplyhandler.cpp
   2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qoauthurischemereplyhandler.cpp
   2026-03-09 10:39:33.000000000 +0100
@@ -3,8 +3,8 @@
 // Qt-Security score:critical reason:authorization-protocol
 
 #include "qabstractoauthreplyhandler_p.h" // for lcReplyHandler()
-#include "qoauthoobreplyhandler_p.h"
 #include "qoauthurischemereplyhandler.h"
+#include "qoauthurischemereplyhandler_p.h"
 
 #include <QtGui/qdesktopservices.h>
 
@@ -15,6 +15,8 @@
 
 QT_BEGIN_NAMESPACE
 
+using namespace Qt::StringLiterals;
+
 /*!
     \class QOAuthUriSchemeReplyHandler
     \inmodule QtNetworkAuth
@@ -148,70 +150,67 @@
     handler - see \l {Qt OAuth2 Browser Support} for details.
 */
 
-class QOAuthUriSchemeReplyHandlerPrivate : public QOAuthOobReplyHandlerPrivate
+bool QOAuthUriSchemeReplyHandlerPrivate::hasValidRedirectUrl() const
 {
-    Q_DECLARE_PUBLIC(QOAuthUriSchemeReplyHandler)
-
-public:
-    bool hasValidRedirectUrl() const
-    {
-        // RFC 6749 Section 3.1.2
-        return redirectUrl.isValid()
-               && !redirectUrl.scheme().isEmpty()
-               && redirectUrl.fragment().isEmpty();
-    }
+    // RFC 6749 Section 3.1.2
+    return redirectUrl.isValid()
+           && !redirectUrl.scheme().isEmpty()
+           && redirectUrl.fragment().isEmpty();
+}
 
-    bool _q_handleRedirectUrl(const QUrl &url)
-    {
-        Q_Q(QOAuthUriSchemeReplyHandler);
-        // Remove the query parameters from comparison, and compare them 
manually (the parameters
-        // of interest like 'code' and 'state' are received as query 
parameters and comparison
-        // would always fail). Fragments are removed as some servers (eg. 
Reddit) seem to add some,
-        // possibly for some implementation consistency with other OAuth flows 
where fragments
-        // are actually used.
-        bool urlMatch = url.matches(redirectUrl, QUrl::RemoveQuery | 
QUrl::RemoveFragment);
-
-        const QUrlQuery responseQuery{url};
-        if (urlMatch) {
-            // Verify that query parameters that are part of redirect URL are 
present in redirection
-            const auto registeredItems = QUrlQuery{redirectUrl}.queryItems();
-            for (const auto &item: registeredItems) {
-                if (!responseQuery.hasQueryItem(item.first)
-                    || responseQuery.queryItemValue(item.first) != 
item.second) {
-                    urlMatch = false;
-                    break;
-                }
+bool QOAuthUriSchemeReplyHandlerPrivate::_q_handleRedirectUrl(const QUrl &url)
+{
+    Q_Q(QOAuthUriSchemeReplyHandler);
+    // Remove the query parameters from comparison, and compare them manually 
(the parameters
+    // of interest like 'code' and 'state' are received as query parameters 
and comparison
+    // would always fail). Fragments are removed as some servers (eg. Reddit) 
seem to add some,
+    // possibly for some implementation consistency with other OAuth flows 
where fragments
+    // are actually used. Some servers (eg. Microsoft) also add an extra '/' 
path, so treat
+    // '/' and empty paths as equal
+    auto normalized = [](const QUrl &url) {
+        auto normalized = url.adjusted(QUrl::RemoveQuery | 
QUrl::RemoveFragment);
+        if (normalized.path().isEmpty())
+            normalized.setPath("/"_L1);
+        return normalized;
+    };
+
+    bool urlMatch = normalized(url).matches(normalized(redirectUrl), 
QUrl::None);
+
+    const QUrlQuery responseQuery{url};
+    if (urlMatch) {
+        // Verify that query parameters that are part of redirect URL are 
present in redirection
+        const auto registeredItems = QUrlQuery{redirectUrl}.queryItems();
+        for (const auto &item: registeredItems) {
+            if (!responseQuery.hasQueryItem(item.first)
+                || responseQuery.queryItemValue(item.first) != item.second) {
+                urlMatch = false;
+                break;
             }
         }
+    }
 
-        if (!urlMatch) {
-            qCDebug(lcReplyHandler(), "Url ignored");
-            if (forwardUnhandledUrls) {
-                // The URLs received here might be unrelated. Further, in case 
of "https" scheme,
-                // the first request issued to the authorization server comes 
through here
-                // (if this handler is listening)
-                QDesktopServices::openUrl(url);
-            }
-            return false;
+    if (!urlMatch) {
+        qCDebug(lcReplyHandler(), "Url ignored");
+        if (forwardUnhandledUrls) {
+            // The URLs received here might be unrelated. Further, in case of 
"https" scheme,
+            // the first request issued to the authorization server comes 
through here
+            // (if this handler is listening)
+            QDesktopServices::openUrl(url);
         }
-
-        qCDebug(lcReplyHandler(), "Url handled");
-        emit q->callbackDataReceived(url.toEncoded());
-
-        QVariantMap resultParameters;
-        const auto responseItems = 
responseQuery.queryItems(QUrl::FullyDecoded);
-        for (const auto &item : responseItems)
-            resultParameters.insert(item.first, item.second);
-
-        emit q->callbackReceived(resultParameters);
-        return true;
+        return false;
     }
 
-public:
-    QUrl redirectUrl;
-    bool forwardUnhandledUrls = true;
-    bool listening = false;
-};
+    qCDebug(lcReplyHandler(), "Url handled");
+    emit q->callbackDataReceived(url.toEncoded());
+
+    QVariantMap resultParameters;
+    const auto responseItems = responseQuery.queryItems(QUrl::FullyDecoded);
+    for (const auto &item : responseItems)
+        resultParameters.insert(item.first, item.second);
+
+    emit q->callbackReceived(resultParameters);
+    return true;
+}
 
 /*!
     \fn QOAuthUriSchemeReplyHandler::QOAuthUriSchemeReplyHandler()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qoauthurischemereplyhandler_p.h
 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qoauthurischemereplyhandler_p.h
--- 
old/qtnetworkauth-everywhere-src-6.10.2/src/oauth/qoauthurischemereplyhandler_p.h
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/src/oauth/qoauthurischemereplyhandler_p.h
   2026-03-09 10:39:33.000000000 +0100
@@ -0,0 +1,42 @@
+// Copyright (C) 2026 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists for the convenience
+// of the Network Access API.  This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QOAUTHURISCHEMEREPLYHANDLER_P_H
+#define QOAUTHURISCHEMEREPLYHANDLER_P_H
+
+#include <QtNetworkAuth/qoauthglobal.h>
+#include <QtNetworkAuth/qoauthurischemereplyhandler.h>
+
+#include <private/qoauthoobreplyhandler_p.h>
+
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOAuthUriSchemeReplyHandlerPrivate : public QOAuthOobReplyHandlerPrivate
+{
+    Q_DECLARE_PUBLIC(QOAuthUriSchemeReplyHandler)
+
+public:
+    bool hasValidRedirectUrl() const;
+    bool _q_handleRedirectUrl(const QUrl &url);
+
+    QUrl redirectUrl;
+    bool forwardUnhandledUrls = true;
+    bool listening = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QOAUTHURISCHEMEREPLYHANDLER_P_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/abstractoauth2/tst_abstractoauth2.cpp
 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/abstractoauth2/tst_abstractoauth2.cpp
--- 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/abstractoauth2/tst_abstractoauth2.cpp
    2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/abstractoauth2/tst_abstractoauth2.cpp
    2026-03-09 10:39:33.000000000 +0100
@@ -180,8 +180,8 @@
     QFETCH(QSet<QByteArray>, requested_scope);
 
     TestFlow oauth2;
-    oauth2.setAuthorizationUrl({"authorizationUrl"_L1});
-    oauth2.setTokenUrl({"accessTokenUrl"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationUrl"_L1});
+    oauth2.setTokenUrl(QUrl{"accessTokenUrl"_L1});
     QVERIFY(oauth2.scope().isEmpty());
     QVERIFY(oauth2.requestedScopeTokens().isEmpty());
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauth2codeflow/tst_oauth2codeflow.cpp
 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauth2codeflow/tst_oauth2codeflow.cpp
--- 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauth2codeflow/tst_oauth2codeflow.cpp
    2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauth2codeflow/tst_oauth2codeflow.cpp
    2026-03-09 10:39:33.000000000 +0100
@@ -755,8 +755,8 @@
 
     ReplyHandler replyHandler;
     oauth2.setReplyHandler(&replyHandler);
-    oauth2.setAuthorizationUrl({"authorizationUrl"_L1});
-    oauth2.setTokenUrl({"accessTokenUrl"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationUrl"_L1});
+    oauth2.setTokenUrl(QUrl{"accessTokenUrl"_L1});
 
     QByteArray nonceInAuthorizationUrl;
     connect(&oauth2, &QAbstractOAuth::authorizeWithBrowser, this, [&](const 
QUrl &url){
@@ -799,8 +799,8 @@
 {
     QOAuth2AuthorizationCodeFlow oauth2;
     oauth2.setRequestedScopeTokens({"openid"});
-    oauth2.setAuthorizationUrl({"authorizationUrl"_L1});
-    oauth2.setTokenUrl({"accessTokenUrl"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationUrl"_L1});
+    oauth2.setTokenUrl(QUrl{"accessTokenUrl"_L1});
     oauth2.setState("a_state"_L1);
     ReplyHandler replyHandler;
     oauth2.setReplyHandler(&replyHandler);
@@ -943,8 +943,8 @@
     QFETCH(QSet<QByteArray>, expected_requested_scope);
 
     QOAuth2AuthorizationCodeFlow oauth2;
-    oauth2.setAuthorizationUrl({"authorizationUrl"_L1});
-    oauth2.setTokenUrl({"accessTokenUrl"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationUrl"_L1});
+    oauth2.setTokenUrl(QUrl{"accessTokenUrl"_L1});
     QVERIFY(oauth2.requestedScopeTokens().isEmpty());
 
     QSignalSpy requestedScopeTokensSpy(&oauth2, 
&QAbstractOAuth2::requestedScopeTokensChanged);
@@ -1004,8 +1004,8 @@
     QOAuth2AuthorizationCodeFlow oauth2;
     QSignalSpy grantedSpy(&oauth2, 
&QAbstractOAuth2::grantedScopeTokensChanged);
     oauth2.setRequestedScopeTokens(requested_scope);
-    oauth2.setAuthorizationUrl({"authorizationUrl"_L1});
-    oauth2.setTokenUrl({"accessTokenUrl"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationUrl"_L1});
+    oauth2.setTokenUrl(QUrl{"accessTokenUrl"_L1});
     oauth2.setState("a_state"_L1);
     ReplyHandler replyHandler;
     oauth2.setReplyHandler(&replyHandler);
@@ -1209,8 +1209,8 @@
 void tst_OAuth2CodeFlow::extraTokens()
 {
     QOAuth2AuthorizationCodeFlow oauth2;
-    oauth2.setAuthorizationUrl({"authorizationUrl"_L1});
-    oauth2.setTokenUrl({"accessTokenUrl"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationUrl"_L1});
+    oauth2.setTokenUrl(QUrl{"accessTokenUrl"_L1});
     oauth2.setState("a_state"_L1);
     ReplyHandler replyHandler;
     oauth2.setReplyHandler(&replyHandler);
@@ -1260,8 +1260,8 @@
 void tst_OAuth2CodeFlow::expirationAt()
 {
     QOAuth2AuthorizationCodeFlow oauth2;
-    oauth2.setAuthorizationUrl({"authorizationEndpoint"_L1});
-    oauth2.setTokenUrl({"tokenEndpoint"_L1});
+    oauth2.setAuthorizationUrl(QUrl{"authorizationEndpoint"_L1});
+    oauth2.setTokenUrl(QUrl{"tokenEndpoint"_L1});
     oauth2.setState("a_state"_L1);
     ReplyHandler replyHandler;
     oauth2.setReplyHandler(&replyHandler);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauthhttpserverreplyhandler/tst_oauthhttpserverreplyhandler.cpp
 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauthhttpserverreplyhandler/tst_oauthhttpserverreplyhandler.cpp
--- 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauthhttpserverreplyhandler/tst_oauthhttpserverreplyhandler.cpp
  2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauthhttpserverreplyhandler/tst_oauthhttpserverreplyhandler.cpp
  2026-03-09 10:39:33.000000000 +0100
@@ -298,20 +298,20 @@
 
     QVERIFY(replyHandler.isListening());
     replyHandler.setCallbackPath(callbackPath);
-    QUrl callback = replyHandler.callback();
+    QUrl callback{replyHandler.callback()};
     QCOMPARE(callback.path(), callbackPath);
     QCOMPARE(callback.host(), callbackHost);
 
     replyHandler.close();
     QVERIFY(!replyHandler.isListening());
-    callback = replyHandler.callback();
+    callback.setUrl(replyHandler.callback());
     // Should remain after close
     QCOMPARE(callback.path(), callbackPath);
     QCOMPARE(callback.host(), callbackHost);
 
     replyHandler.listen({QHostAddress::SpecialAddress::LocalHost});
     QVERIFY(replyHandler.isListening());
-    callback = replyHandler.callback();
+    callback.setUrl(replyHandler.callback());
     QCOMPARE(callback.path(), callbackPath);
     QCOMPARE(callback.host(), callbackHost);
 }
@@ -439,7 +439,7 @@
     QString expected_response_data = replyHandler.callback() + 
redirect_response_data;
 
     QNetworkAccessManager networkAccessManager;
-    QNetworkRequest request(expected_response_data);
+    QNetworkRequest request(QUrl{expected_response_data});
     QNetworkReplyPtr reply;
 
     reply.reset(networkAccessManager.get(request));
@@ -498,7 +498,7 @@
     // Calling listen() with SSL configuration makes handler to use 'https'
     QVERIFY(replyHandler.listen(serverConfig));
     QVERIFY(replyHandler.isListening());
-    const QUrl redirectUrl = replyHandler.callback() + 
u"?state=somestate&code=somecode"_s;
+    const QUrl redirectUrl{replyHandler.callback() + 
"?state=somestate&code=somecode"_L1};
     QCOMPARE(redirectUrl.scheme(), u"https"_s);
 
     // Issue a HTTP GET to the handler's server to mimic OAuth2 redirection 
event
@@ -539,16 +539,16 @@
     QTest::addColumn<QUrl>("expectedCallback");
 
     const QString localhost = u"localhost"_s;
-    const QUrl localhostCallback = u"http://localhost/"_s;
+    const QUrl localhostCallback{u"http://localhost/"_s};
 
     const QString ipv4literal = u"127.0.0.1"_s;
-    const QUrl ipv4literalCallback = u"http://127.0.0.1/"_s;
+    const QUrl ipv4literalCallback{u"http://127.0.0.1/"_s};
 
     const QString ipv6literal = u"::1"_s;
-    const QUrl ipv6literalCallback = u"http://[::1]/"_s;
+    const QUrl ipv6literalCallback{u"http://[::1]/"_s};
 
     const QString localnet = u"localhost.localnet"_s;
-    const QUrl localnetCallback = u"http://localhost.localnet/"_s;
+    const QUrl localnetCallback{u"http://localhost.localnet/"_s};
 
     QTest::newRow("default")
         << QHostAddress() << QString() << ipv4literalCallback;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauthurischemereplyhandler/CMakeLists.txt
 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauthurischemereplyhandler/CMakeLists.txt
--- 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauthurischemereplyhandler/CMakeLists.txt
        2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauthurischemereplyhandler/CMakeLists.txt
        2026-03-09 10:39:33.000000000 +0100
@@ -9,4 +9,5 @@
         Qt::Gui
         Qt::Network
         Qt::NetworkAuth
+        Qt::NetworkAuthPrivate
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauthurischemereplyhandler/tst_oauthurischemereplyhandler.cpp
 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauthurischemereplyhandler/tst_oauthurischemereplyhandler.cpp
--- 
old/qtnetworkauth-everywhere-src-6.10.2/tests/auto/oauthurischemereplyhandler/tst_oauthurischemereplyhandler.cpp
    2026-01-20 05:15:31.000000000 +0100
+++ 
new/qtnetworkauth-everywhere-src-6.11.0/tests/auto/oauthurischemereplyhandler/tst_oauthurischemereplyhandler.cpp
    2026-03-09 10:39:33.000000000 +0100
@@ -6,6 +6,7 @@
 
 #include <QtGui/qdesktopservices.h>
 
+#include <QtNetworkAuth/private/qoauthurischemereplyhandler_p.h>
 #include <QtNetworkAuth/qoauth2authorizationcodeflow.h>
 #include <QtNetworkAuth/qoauthurischemereplyhandler.h>
 
@@ -43,6 +44,23 @@
     const QVariantMap stateCodeMap{{"state"_L1, state}, {"code"_L1, code}};
 };
 
+// This class is used to access reply handler's private class in order
+// to prevent it from forwarding unhandled URLs. Forwarding these URLs
+// may trigger platform dialogues, which may be problematic for CI runs.
+// These autotests themselves don't rely on the forwarded URL triggering
+// anything in particular, so disabling them is fine.
+class UriSchemeReplyHandler : public QOAuthUriSchemeReplyHandler
+{
+public:
+    using QOAuthUriSchemeReplyHandler::QOAuthUriSchemeReplyHandler;
+
+    void setForwardUnhandledUrls(bool enabled)
+    {
+        auto *d = static_cast<QOAuthUriSchemeReplyHandlerPrivate 
*>(d_ptr.get());
+        d->forwardUnhandledUrls = enabled;
+    }
+};
+
 void tst_QOAuthUriSchemeReplyHandler::construction()
 {
     QOAuthUriSchemeReplyHandler rh1;
@@ -58,7 +76,8 @@
 
 void tst_QOAuthUriSchemeReplyHandler::redirectUrl()
 {
-    QOAuthUriSchemeReplyHandler rh;
+    UriSchemeReplyHandler rh;
+    rh.setForwardUnhandledUrls(false);
     QSignalSpy urlChangedSpy(&rh, 
&QOAuthUriSchemeReplyHandler::redirectUrlChanged);
 
     rh.setRedirectUrl(customUrlWithPath);
@@ -87,9 +106,10 @@
 
 void tst_QOAuthUriSchemeReplyHandler::listenClose()
 {
-    const QUrl scheme1 = u"scheme1:/foo"_s;
-    const QUrl scheme2 = u"scheme2:/foo"_s;
-    QOAuthUriSchemeReplyHandler rh;
+    const QUrl scheme1{u"scheme1:/foo"_s};
+    const QUrl scheme2{u"scheme2:/foo"_s};
+    UriSchemeReplyHandler rh;
+    rh.setForwardUnhandledUrls(false);
     QSignalSpy callbackSpy(&rh, &QAbstractOAuthReplyHandler::callbackReceived);
 
     rh.setRedirectUrl(scheme1);
@@ -101,12 +121,12 @@
     QDesktopServices::openUrl(scheme2);
     QCOMPARE(callbackSpy.size(), 2);
 
-    QDesktopServices::openUrl(scheme1); // Previous scheme should be 
unregistered
+    // Verify old scheme is no longer accepted by the handler
+    QVERIFY(!rh.handleAuthorizationRedirect(scheme1));
     QCOMPARE(callbackSpy.size(), 2);
 
     rh.close();
-    QDesktopServices::openUrl(scheme2);
-    QCOMPARE(callbackSpy.size(), 2);
+    QVERIFY(!rh.isListening());
 }
 
 void tst_QOAuthUriSchemeReplyHandler::authorization_data()
@@ -130,6 +150,29 @@
         << QUrl{"com.example://cb.example.org/a_path"_L1 + stateCodeQuery}
         << true << stateCodeMap;
 
+    QTest::newRow("match_with_empty_path_1")
+        << QUrl{"com.example://cb.example.org/"_L1}
+        << QUrl{"com.example://cb.example.org/"_L1 + stateCodeQuery}
+        << true << stateCodeMap;
+
+    // No path vs empty path
+    QTest::newRow("match_with_empty_path_2")
+        << QUrl{"com.example://cb.example.org"_L1}
+        << QUrl{"com.example://cb.example.org/"_L1 + stateCodeQuery}
+        << true << stateCodeMap;
+
+    // Empty path vs no path
+    QTest::newRow("match_with_empty_path_3")
+        << QUrl{"com.example://cb.example.org/"_L1}
+        << QUrl{"com.example://cb.example.org"_L1 + stateCodeQuery}
+        << true << stateCodeMap;
+
+    // Empty path vs no path, and host mismatch
+    QTest::newRow("match_with_empty_path_4")
+        << QUrl{"com.example://cb.abc.example.org/"_L1}
+        << QUrl{"com.example://cb.def.example.org"_L1 + stateCodeQuery}
+        << false << stateCodeMap;
+
     QVariantMap resultParameters = stateCodeMap;
     resultParameters.insert("lang"_L1, "de");
     QTest::newRow("match_with_path_and_query")
@@ -159,7 +202,8 @@
     QFETCH(const bool, matches);
     QFETCH(const QVariantMap, result_parameters);
 
-    QOAuthUriSchemeReplyHandler rh;
+    UriSchemeReplyHandler rh;
+    rh.setForwardUnhandledUrls(false);
     rh.setRedirectUrl(registered_redirect_uri);
     rh.listen();
 
@@ -216,7 +260,8 @@
 {
     QFETCH(const QUrl, response_redirect_uri);
 
-    QOAuthUriSchemeReplyHandler rh(QUrl{u"io:/path"_s});
+    UriSchemeReplyHandler rh(QUrl{u"io:/path"_s});
+    rh.setForwardUnhandledUrls(false);
     QSignalSpy spy(&rh, &QOAuthUriSchemeReplyHandler::callbackDataReceived);
     QVERIFY(rh.isListening());
 

Reply via email to