diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a27348e8..e4570ba0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ if(UNIX AND NOT IOS) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13 CACHE STRING "Required macOS version") endif() -project(AusweisApp2 VERSION 1.22.5 LANGUAGES ${LANGUAGES}) +project(AusweisApp2 VERSION 1.22.6 LANGUAGES ${LANGUAGES}) # Set TWEAK if not defined in PROJECT_VERSION above to # have a valid tweak version without propagating it diff --git a/LICENSE.officially.txt b/LICENSE.officially.txt index 9a9cced9b..6fea5852b 100644 --- a/LICENSE.officially.txt +++ b/LICENSE.officially.txt @@ -352,7 +352,7 @@ Die verwendeten Open-Source-Bibliotheken unterliegen den folgenden Nutzungsbedin OpenSSL Lizenz: OpenSSL license & SSLeay license - Version: 1.1.1n + Version: 1.1.1o Adresse: https://www.openssl.org/ Qt diff --git a/LICENSE.txt b/LICENSE.txt index a3701f333..b57a01545 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -320,7 +320,7 @@ Die verwendeten Open-Source-Bibliotheken unterliegen den folgenden Nutzungsbedin OpenSSL Lizenz: OpenSSL license & SSLeay license - Version: 1.1.1n + Version: 1.1.1o Adresse: https://www.openssl.org/ Qt diff --git a/cmake/Libraries.cmake b/cmake/Libraries.cmake index ecc1dd98b..32274748f 100644 --- a/cmake/Libraries.cmake +++ b/cmake/Libraries.cmake @@ -116,6 +116,7 @@ elseif(MAC) find_path(PCSC_INCLUDE_DIRS WinSCard.h) find_library(PCSC_LIBRARIES NAMES PCSC WinSCard) + find_library(OSX_USERNOTIFICATIONS UserNotifications) find_library(OSX_APPKIT AppKit) find_library(IOKIT NAMES IOKit) find_library(OSX_SECURITY Security) diff --git a/docs/releasenotes/1.22.6.rst b/docs/releasenotes/1.22.6.rst new file mode 100644 index 000000000..4417508dd --- /dev/null +++ b/docs/releasenotes/1.22.6.rst @@ -0,0 +1,31 @@ +AusweisApp2 1.22.6 +^^^^^^^^^^^^^^^^^^ + +**Releasedatum:** 19. Mai 2022 + + +Anwender +"""""""" +- Probleme mit der Kartenkommunikation bei der Funktion + "Smartphone als Kartenleser" im Komfortmodus wurden + behoben. + +- Ab macOS 10.14 werden nun die Systembenachrichtigungen + verwendet. + +- Unter macOS ist das Tray-Icon jetzt standardmäßig + deaktiviert. Dies kann in den Einstellungen wieder + aktiviert werden. + +- Unter iOS war unter bestimmten Umständen ein + neuer NFC-Scan nicht möglich. Dies wurde behoben. + +- Beim Abbrechen einer Authentisierung kam es unter + iOS teilweise zum Absturz. Dies wurde behoben. + +- Kleinere Fehlerbehebungen und Optimierungen. + + +Entwickler +"""""""""" +- Aktualisierung von OpenSSL auf die Version 1.1.1o. diff --git a/docs/releasenotes/appcast.rst b/docs/releasenotes/appcast.rst index 2549376ff..9a6dd8892 100644 --- a/docs/releasenotes/appcast.rst +++ b/docs/releasenotes/appcast.rst @@ -4,6 +4,7 @@ Release Notes .. toctree:: :maxdepth: 1 + 1.22.6 1.22.5 1.22.4 1.22.3 diff --git a/docs/releasenotes/versions.rst b/docs/releasenotes/versions.rst index 4fc49f70f..beb190e44 100644 --- a/docs/releasenotes/versions.rst +++ b/docs/releasenotes/versions.rst @@ -6,6 +6,7 @@ Versionszweig 1.22 .. toctree:: :maxdepth: 1 + 1.22.6 1.22.5 1.22.4 1.22.3 diff --git a/docs/sdk/android.rst b/docs/sdk/android.rst index 0aedc339d..4473f1f20 100644 --- a/docs/sdk/android.rst +++ b/docs/sdk/android.rst @@ -78,11 +78,11 @@ App Bundle The integrated AusweisApp2 uses native libraries which need to be extracted when used in an App Bundle, otherwise the SDK will not work correctly. -Add the following statement to your app's gradle.properties file: +Add the following statement to your app's build.gradle file: .. code-block:: groovy - android.bundle.enableUncompressedNativeLibs=false + android { packagingOptions { jniLibs { useLegacyPackaging = true } } } Logging diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 7f34a1e02..1cca75a0c 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -96,8 +96,8 @@ endif() set(QT 5.15.2) set(QT_HASH 3a530d1b243b5dec00bc54937455471aaa3e56849d2593edb8ded07228202240) -set(OPENSSL 1.1.1n) -set(OPENSSL_HASH 40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a) +set(OPENSSL 1.1.1o) +set(OPENSSL_HASH 9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f) ################################## Files set(QT_FILE qt-everywhere-src-${QT}.tar.xz) diff --git a/resources/packaging/linux/com.governikus.ausweisapp2.desktop.in b/resources/packaging/linux/com.governikus.ausweisapp2.desktop.in index 0add2ad3b..67f79e709 100755 --- a/resources/packaging/linux/com.governikus.ausweisapp2.desktop.in +++ b/resources/packaging/linux/com.governikus.ausweisapp2.desktop.in @@ -9,3 +9,4 @@ Categories=System;Security; GenericName=Authentication App Keywords=nPA,eID,eAT,Personalausweis,Aufenthaltstitel,Identity,Card Name=AusweisApp2 +StartupWMClass=AusweisApp2 diff --git a/resources/packaging/win/WIX.Texts.de-DE.wxl b/resources/packaging/win/WIX.Texts.de-DE.wxl index cd8fe7a97..376c4d14f 100644 --- a/resources/packaging/win/WIX.Texts.de-DE.wxl +++ b/resources/packaging/win/WIX.Texts.de-DE.wxl @@ -38,7 +38,7 @@ Ausweis, Authentisierung Installationspaket für die AusweisApp2 Offizieller eID-Client des Bundes - https://www.ausweisapp.bund.de/fragen-und-antworten/support + https://www.ausweisapp.bund.de/hilfe-und-support https://www.ausweisapp.bund.de https://www.ausweisapp.bund.de/download Eine aktuellere Version der [ProductName] ist bereits installiert. Die Installation wird nun beendet. diff --git a/resources/qml/+desktop/main.qml b/resources/qml/+desktop/main.qml index 58685f6aa..bbaf737c4 100644 --- a/resources/qml/+desktop/main.qml +++ b/resources/qml/+desktop/main.qml @@ -69,6 +69,11 @@ ApplicationWindow { return } + if (Qt.platform.os === "osx" && !SettingsModel.autoStartApp) { + close.accepted = true + return + } + if (SettingsModel.remindUserToClose) { closeWarning.open() close.accepted = false @@ -218,6 +223,8 @@ ApplicationWindow { d.showMainWindow() d.closeOpenDialogs() switch (pModule) { + case UiModule.CURRENT: + break case UiModule.IDENTIFY: if (ApplicationModel.currentWorkflow === "") { d.activeView = UiModule.SELF_AUTHENTICATION @@ -231,11 +238,6 @@ ApplicationWindow { d.activeView = UiModule.PINMANAGEMENT } break - case UiModule.CURRENT: - if (SettingsModel.startupModule == UiModule.TUTORIAL) { - d.activeView = UiModule.TUTORIAL - } - break case UiModule.UPDATEINFORMATION: if (ApplicationModel.currentWorkflow === "" && d.activeView === UiModule.DEFAULT) { d.activeView = UiModule.UPDATEINFORMATION diff --git a/resources/qml/Governikus/Global/GCheckBox.qml b/resources/qml/Governikus/Global/GCheckBox.qml index cba0c0134..62903a572 100644 --- a/resources/qml/Governikus/Global/GCheckBox.qml +++ b/resources/qml/Governikus/Global/GCheckBox.qml @@ -14,6 +14,7 @@ CheckBox { id: control property alias textStyle: description.textStyle + property alias maximumLineCount: description.maximumLineCount padding: 0 diff --git a/resources/qml/Governikus/SettingsView/+desktop/ConnectSacView.qml b/resources/qml/Governikus/SettingsView/+desktop/ConnectSacView.qml index c08c5ea96..79dda323b 100644 --- a/resources/qml/Governikus/SettingsView/+desktop/ConnectSacView.qml +++ b/resources/qml/Governikus/SettingsView/+desktop/ConnectSacView.qml @@ -57,7 +57,7 @@ SectionPage { visible: d.view !== ConnectSacView.SubView.PairingInfo || !d.externalMoreInformation //: LABEL DESKTOP text: qsTr("Pairing") - helpTopic: "readerDeviceTab" + helpTopic: "settingsRemoteReader" rootEnabled: false customSubAction: CancelAction { visible: true diff --git a/resources/qml/Governikus/SettingsView/+desktop/GeneralSettings.qml b/resources/qml/Governikus/SettingsView/+desktop/GeneralSettings.qml index 29e42f806..962d2e092 100644 --- a/resources/qml/Governikus/SettingsView/+desktop/GeneralSettings.qml +++ b/resources/qml/Governikus/SettingsView/+desktop/GeneralSettings.qml @@ -11,6 +11,7 @@ import Governikus.View 1.0 import Governikus.Type.SettingsModel 1.0 ColumnLayout { + readonly property string helpTopic: "settingsGeneral" spacing: Constants.component_spacing @@ -66,10 +67,16 @@ ColumnLayout { } ToggleableOption { + Layout.fillWidth: true + activeFocusOnTab: true - //: LABEL DESKTOP - text: qsTr("Auto start AusweisApp2 after boot") + text: Qt.platform.os === "osx" + //: LABEL MACOS Text for auto-start option + ? qsTr("Auto-start %1 after boot and add to menu bar").arg(Qt.application.name) + //: LABEL WINDOWS Text for auto-start option + : qsTr("Auto-start %1 after boot").arg(Qt.application.name) + maximumLineCount: 2 checked: SettingsModel.autoStartApp enabled: !SettingsModel.autoStartSetByAdmin && SettingsModel.autoStartAvailable onCheckedChanged: SettingsModel.autoStartApp = checked diff --git a/resources/qml/Governikus/TutorialView/+desktop/SetupAssistantView.qml b/resources/qml/Governikus/TutorialView/+desktop/SetupAssistantView.qml index 538e86769..0a9bf1ee0 100644 --- a/resources/qml/Governikus/TutorialView/+desktop/SetupAssistantView.qml +++ b/resources/qml/Governikus/TutorialView/+desktop/SetupAssistantView.qml @@ -22,6 +22,7 @@ SectionPage { enum SubViews { Welcome = 0, + AutoStartSetting, HistorySetting, CardReaderInfo, CardReader, @@ -69,7 +70,44 @@ SectionPage { agreeText: "" agreeButton.iconSource: "qrc:///images/desktop/material_arrow_forward.svg" - onAgree: d.activeView = SetupAssistantView.SubViews.HistorySetting + onAgree: d.activeView = SettingsModel.autoStartAvailable ? SetupAssistantView.SubViews.AutoStartSetting : SetupAssistantView.SubViews.HistorySetting + } + + DecisionView { + visible: d.activeView === SetupAssistantView.SubViews.AutoStartSetting + + Accessible.name: qsTr("Auto-start setup step") + + mainIconSource: "qrc:///images/status_info.svg" + //: INFO DESKTOP Question if the App shall be started automatically after boot + questionText: qsTr("Do you want to automatically start the %1 after boot?").arg(Qt.application.name) + //: INFO DESKTOP Information text why autostart of the App is advisable + questionSubText: { + let subText = qsTr("In order to successfully use the online identification function, %1 has to be running. It is therefore advisable to activate the auto-start after system startup.").arg(Qt.application.name) + if (Qt.platform.os === "osx") { + //: INFO MACOS Additional information that macOS auto-start add a symbol to the menu bar + subText += " " + qsTr("The launch will add an icon to the menu bar.") + } + return subText + } + + titleBarAction: TitleBarAction { + //: LABEL DESKTOP + text: qsTr("Auto-start Setting") + rootEnabled: d.allowNavigation + showSettings: false + helpTopic: "setupAssistant" + } + + onAgree: { + SettingsModel.autoStartApp = true + d.activeView = SetupAssistantView.SubViews.HistorySetting + } + + onDisagree: { + SettingsModel.autoStartApp = false + d.activeView = SetupAssistantView.SubViews.HistorySetting + } } DecisionView { diff --git a/resources/translations/ausweisapp2_de.ts b/resources/translations/ausweisapp2_de.ts index 8441b29a1..da54f1d1f 100644 --- a/resources/translations/ausweisapp2_de.ts +++ b/resources/translations/ausweisapp2_de.ts @@ -1156,11 +1156,6 @@ LABEL ANDROID IOS Button to start a change of the Transport PIN. LABEL DESKTOP Verhalten - - Auto start AusweisApp2 after boot - LABEL DESKTOP - AusweisApp2 automatisch beim Hochfahren starten - Close after authentication LABEL DESKTOP @@ -1186,6 +1181,16 @@ LABEL ANDROID IOS Button to start a change of the Transport PIN. LABEL DESKTOP Benutze den bei der Installation angegebenen Proxy (%1). + + Auto-start %1 after boot and add to menu bar + LABEL MACOS Text for auto-start option + %1 automatisch beim Hochfahren starten und als Eintrag der Menüleiste hinzufügen + + + Auto-start %1 after boot + LABEL WINDOWS Text for auto-start option + %1 automatisch beim Hochfahren starten + GeneralWorkflow @@ -3746,6 +3751,30 @@ LABEL ALL_PLATFORMS LABEL DESKTOP Kartenleser + + Do you want to automatically start the %1 after boot? + INFO DESKTOP Question if the App shall be started automatically after boot + Wollen Sie die %1 automatisch nach dem Hochfahren starten? + + + Auto-start Setting + LABEL DESKTOP + Autostart-Einstellung + + + Auto-start setup step + Einrichtungsschritt zum Autostart + + + In order to successfully use the online identification function, %1 has to be running. It is therefore advisable to activate the auto-start after system startup. + INFO DESKTOP Information text why autostart of the App is advisable + Um die Online-Ausweisfunktion erfolgreich nutzen zu können, muss die %1 gestartet sein. Daher ist es ratsam, dies beim Systemstart zuzulassen. + + + The launch will add an icon to the menu bar. + INFO MACOS Additional information that macOS auto-start add a symbol to the menu bar + Der Start erfolgt hierbei als Eintrag in der Menüleiste. + ShareButton diff --git a/resources/updatable-files/reader/img_Cherry_secure_board.png b/resources/updatable-files/reader/img_Cherry_secure_board.png new file mode 100644 index 000000000..4523e2123 Binary files /dev/null and b/resources/updatable-files/reader/img_Cherry_secure_board.png differ diff --git a/resources/updatable-files/reader/img_Cherry_secure_board_mit_ausweis.png b/resources/updatable-files/reader/img_Cherry_secure_board_mit_ausweis.png new file mode 100644 index 000000000..e83dbe318 Binary files /dev/null and b/resources/updatable-files/reader/img_Cherry_secure_board_mit_ausweis.png differ diff --git a/resources/updatable-files/supported-providers.json b/resources/updatable-files/supported-providers.json index c3194aef2..a58cfaff3 100644 --- a/resources/updatable-files/supported-providers.json +++ b/resources/updatable-files/supported-providers.json @@ -681,10 +681,6 @@ } }, { - "exclude": [ - "ios" - ], - "eidSupport": false, "shortName": { "": "Bürgerservice-Portal Wiesbaden" }, @@ -1399,6 +1395,26 @@ "category": "citizen", "subjectUrlInfo": "Using service from Servicekonto Nordrhein-Westfalen (https://servicekonto.nrw)." }, + { + "shortName": { + "": "Online Services der Stadt Bad Oeynhausen" + }, + "longName": { + "": "Online Services der Stadt Bad Oeynhausen" + }, + "longDescription": { + "": "Wir stellen Online-Dienstleistungen aus Bad Oeynhausen, dem Kreis Minden-Lübbecke, dem Land NRW und den Bundesbehörden zur Verfügung.

Sie können unseren Service ohne Anmeldung oder mit einer Anmeldung über das Servicekonto.NRW nutzen. Für die Nutzung von ePayment ist eine Anmeldung mit dem Servicekonto Voraussetzung." + }, + "address": "https://portal.kommunale.it/bad-oeynhausen/login", + "homepage": "https://portal.kommunale.it/bad-oeynhausen/services", + "phone": "+49 5731 14 0", + "email": "egov@badoeynhausen.de", + "postalAddress": "Stadt Bad Oeynhausen
Der Bürgermeister
Ostkorso 8
32545 Bad Oeynhausen", + "image": "StadtBadOeynhausen_image.jpg", + "icon": "StadtBadOeynhausen_icon.png", + "category": "citizen", + "subjectUrlInfo": "Using service from Servicekonto Nordrhein-Westfalen (https://servicekonto.nrw)." + }, { "shortName": { "": "Online-Service der Stadt Bonn" diff --git a/resources/updatable-files/supported-readers.json b/resources/updatable-files/supported-readers.json index 3c15b75f0..a5f7ebd69 100644 --- a/resources/updatable-files/supported-readers.json +++ b/resources/updatable-files/supported-readers.json @@ -395,7 +395,7 @@ { "VendorId": "0x04E6", "ProductId": "0x512B", - "Name": "SDI011 Contactless Reader", + "Name": "Identiv SDI011 Dual Interface Smart Card Reader", "Pattern": "^(SCM Microsystems Inc. )?SDI011G? ((Contactless Reader( 0)?)|((USB Smart Card|Contactless) Reader\\([12]\\)))$", "Icon": "img_Identive_SDI011.png", "IconWithNPA": "img_Identive_SDI011_mit_ausweis.png", @@ -444,7 +444,7 @@ { "VendorId": "0x04E6", "ProductId": "0x5292", - "Name": "SCL01x Contactless Reader", + "Name": "Identiv SCL01x Contactless Smart Card Reader", "Pattern": "^(SCM Microsystems Inc. )?SCL011G? Contactless Reader( 0)?$", "Icon": "img_Identive_SCL011.png", "IconWithNPA": "img_Identive_SCL011_mit_ausweis.png", @@ -838,7 +838,7 @@ { "VendorId": "0x076B", "ProductId": "0x5340", - "Name": "OMNIKEY 5021-CL", + "Name": "HID OMNIKEY 5021-CL", "Pattern": "OMNIKEY CardMan 5x21-CL 0|OMNIKEY CardMan \\(076B:5340\\) 5021 CL", "Icon": "img_HID_Omnikey_Mobile_Reader_502X_CL.png", "IconWithNPA": "img_HID_Omnikey_Mobile_Reader_502X_CL_mit_ausweis.png", @@ -882,7 +882,7 @@ { "VendorId": "0x076B", "ProductId": "0x5022", - "Name": "OMNIKEY 5022-CL", + "Name": "HID OMNIKEY 5022-CL", "Pattern": "HID Global OMNIKEY 5022 Smart Card Reader( 0)?$", "Icon": "img_HID_Omnikey_Mobile_Reader_502X_CL.png", "IconWithNPA": "img_HID_Omnikey_Mobile_Reader_502X_CL_mit_ausweis.png", @@ -923,7 +923,7 @@ { "VendorId": "0x076B", "ProductId": "0x5321", - "Name": "OMNIKEY 5321 v2", + "Name": "HID OMNIKEY 5321 v2", "Pattern": "OMNIKEY CardMan 5x21-CL 0|OMNIKEY CardMan \\(076B:5321\\) 5321(\\(1\\)|\\(2\\))", "Icon": "img_HID_Global_OMNIKEY_5321_V2.png", "IconWithNPA": "img_HID_Global_OMNIKEY_5321_V2_mit_ausweis.png", @@ -958,7 +958,7 @@ { "VendorId": "0x076B", "ProductId": "0x5421", - "Name": "OMNIKEY 5421", + "Name": "HID OMNIKEY 5421", "Pattern": "OMNIKEY CardMan 5x21-CL 0|OMNIKEY Smart Card Reader USB 0|OMNIKEY CardMan \\(076B:5421\\) 5421(\\(1\\)|\\(2\\))", "Icon": "img_HID_Omnikey_542x.png", "IconWithNPA": "img_HID_Omnikey_542x_mit_ausweis.png", @@ -1002,7 +1002,7 @@ { "VendorId": "0x076B", "ProductId": "0x5422", - "Name": "OMNIKEY 5422", + "Name": "HID OMNIKEY 5422", "Pattern": "HID Global OMNIKEY 5422CL Smartcard Reader 0|HID Global OMNIKEY Smartcard Reader (\\(1\\)|\\(2\\))", "Icon": "img_HID_Omnikey_542x.png", "IconWithNPA": "img_HID_Omnikey_542x_mit_ausweis.png", @@ -1131,7 +1131,7 @@ { "VendorId": "0x08E6", "ProductId": "0x5503", - "Name": "Prox-DU HID", + "Name": "Gemalto Prox-DU HID", "Pattern": "Gemalto .*Prox(-DU| Dual)( Contactless_| USB PC Link(Reader| Reader)(\\(2\\)|\\(1\\)))", "Icon": "img_Gemalto_Prox_DU.png", "IconWithNPA": "img_Gemalto_Prox_DU_mit_ausweis.png", diff --git a/src/card/ios/IosCard.h b/src/card/ios/IosCard.h index e69f8e442..31a071842 100644 --- a/src/card/ios/IosCard.h +++ b/src/card/ios/IosCard.h @@ -22,8 +22,6 @@ class IosCard IosCardPointer* const mCard; bool mConnected; - void waitForRequestCompleted(const bool& pCondition); - public: explicit IosCard(IosCardPointer* pTag); ~IosCard() override; diff --git a/src/card/ios/IosCard.mm b/src/card/ios/IosCard.mm index fd8bde6bd..c6e23272f 100644 --- a/src/card/ios/IosCard.mm +++ b/src/card/ios/IosCard.mm @@ -8,6 +8,8 @@ #include #include +#include +#include #import #import @@ -35,25 +37,6 @@ } -void IosCard::waitForRequestCompleted(const bool& pCondition) -{ - QElapsedTimer timer; - timer.start(); - do - { - if (pCondition) - { - return; - } - - QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 1); - } - while (timer.elapsed() <= 2000); - - invalidateTarget(); -} - - bool IosCard::isValid() const { if (@available(iOS 13, *)) @@ -85,33 +68,45 @@ return CardReturnCode::OK; } + const auto resultValue = QSharedPointer::create(false); // Don't use this inside of the Block + const QWeakPointer weakValue = resultValue; + if (@available(iOS 13, *)) { - __block bool callbackDone = false; + const auto locker = QSharedPointer::create(); NFCTagReaderSession* session = mCard->mNfcTag.session; [session connectToTag: mCard->mNfcTag completionHandler: ^(NSError* error){ - if (error != nil) + // By referencing weakValue here, it will be copied into the Block. If the handler outlives the caller, resultValue won't exist anymore. + const auto recvValue = weakValue.lock(); + if (!recvValue) { - invalidateTarget(); - qCDebug(card_nfc) << "Error during connect:" << error; + qCDebug(card_nfc) << "Caller doesn't exist anymore."; + return; + } + + if (error == nil) + { + *recvValue = true; } else { - mConnected = true; + qCDebug(card_nfc) << "Error during connect:" << error; } - callbackDone = true; + locker->release(); }]; - waitForRequestCompleted(callbackDone); + locker->tryAcquire(1, 2000); } - if (!mConnected) + if (!*resultValue) { + invalidateTarget(); return CardReturnCode::COMMAND_FAILED; } + mConnected = true; return CardReturnCode::OK; } @@ -167,41 +162,41 @@ if (@available(iOS 13, *)) { - __block bool callbackDone = false; + const auto locker = QSharedPointer::create(); Q_ASSERT([mCard->mNfcTag conformsToProtocol:@protocol(NFCISO7816Tag)]); const auto tag = static_cast>(mCard->mNfcTag); auto* apdu = [[NFCISO7816APDU alloc] initWithData: pCmd.getBuffer().toNSData()]; [tag sendCommandAPDU: apdu completionHandler: ^(NSData* responseData, uint8_t sw1, uint8_t sw2, NSError* error){ // By referencing weakBuffer here, it will be copied into the Block. If the handler outlives the caller, resultBuffer won't exist anymore. - if (const auto recvBuffer = weakBuffer.lock()) + const auto recvBuffer = weakBuffer.lock(); + if (!recvBuffer) + { + qCDebug(card_nfc) << "Caller doesn't exist anymore."; + return; + } + + if (error == nil) { - if (error == nil) - { - *recvBuffer = QByteArray::fromNSData(responseData); - *recvBuffer += static_cast(sw1); - *recvBuffer += static_cast(sw2); - qCDebug(card_nfc) << "Transmit response APDU:" << recvBuffer->toHex(); - } - else - { - invalidateTarget(); - qCDebug(card_nfc) << "Error during transmit:" << error; - } - - callbackDone = true; + *recvBuffer = QByteArray::fromNSData(responseData); + *recvBuffer += static_cast(sw1); + *recvBuffer += static_cast(sw2); + qCDebug(card_nfc) << "Transmit response APDU:" << recvBuffer->toHex(); } else { - qCDebug(card_nfc) << "Caller doesn't exist anymore."; + qCDebug(card_nfc) << "Error during transmit:" << error; } + + locker->release(); }]; - waitForRequestCompleted(callbackDone); + locker->tryAcquire(1, 2000); } if (resultBuffer->isEmpty()) { + invalidateTarget(); return {CardReturnCode::COMMAND_FAILED}; } diff --git a/src/card/ios/IosReaderDelegate.mm b/src/card/ios/IosReaderDelegate.mm index ee0197280..7936d063c 100644 --- a/src/card/ios/IosReaderDelegate.mm +++ b/src/card/ios/IosReaderDelegate.mm @@ -33,16 +33,17 @@ - (instancetype)initWithListener: (governikus::IosReader*)pListener { - (void)startSession { - if (self.mSessionStoppedByApplication) + if (self.mSession && !self.mSessionStoppedByApplication) { - Q_EMIT self.mListener->fireDidInvalidateWithError(true); - return; + qCDebug(card_nfc) << "Invalidate session" << self.mSession; + [self.mSession invalidateSession]; + self.mSessionStoppedByApplication = true; } - if (self.mSession) + if (self.mSessionStoppedByApplication) { - qCDebug(card_nfc) << "Restart session" << self.mSession; - [self.mSession restartPolling]; + qCDebug(card_nfc) << "Waiting for session to invalidate"; + Q_EMIT self.mListener->fireDidInvalidateWithError(true); return; } @@ -68,24 +69,18 @@ - (void)startSession { - (void)stopSession: (QString)message { qCDebug(card_nfc) << "Stop session" << self.mSession; - if (self.mSession) + if (self.mSession && !self.mSessionStoppedByApplication) { - if (self.mSession.ready) + if (message.isNull()) { - if (message.isNull()) - { - [self.mSession invalidateSession]; - } - else - { - [self.mSession invalidateSessionWithErrorMessage:message.toNSString()]; - } - self.mSessionStoppedByApplication = true; + [self.mSession invalidateSession]; } else { - self.mSession = nil; + [self.mSession invalidateSessionWithErrorMessage:message.toNSString()]; } + qCDebug(card_nfc) << "Invalidate session" << self.mSession; + self.mSessionStoppedByApplication = true; } } @@ -107,7 +102,7 @@ - (void)tagReaderSessionDidBecomeActive: (NFCTagReaderSession*)session { if (session != self.mSession) { - qCWarning(card_nfc) << "An unexpected session became active; mSession" << self.mSession; + qCWarning(card_nfc) << "An unexpected session became active. Invalidate session" << session << "mSession" << self.mSession; [session invalidateSession]; return; } diff --git a/src/settings/GeneralSettings.h b/src/settings/GeneralSettings.h index 57f2904f1..3e9ad78a9 100644 --- a/src/settings/GeneralSettings.h +++ b/src/settings/GeneralSettings.h @@ -18,7 +18,7 @@ class test_GeneralSettings; namespace governikus { -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) +#if defined(Q_OS_WIN) #define GENERAL_SETTINGS_DEFAULT_AUTOSTART true #else #define GENERAL_SETTINGS_DEFAULT_AUTOSTART false diff --git a/src/ui/common/CMakeLists.txt b/src/ui/common/CMakeLists.txt index 744163cd4..7e3e064b2 100644 --- a/src/ui/common/CMakeLists.txt +++ b/src/ui/common/CMakeLists.txt @@ -11,5 +11,5 @@ if(DESKTOP) endif() if(MAC) - target_link_libraries(AusweisAppUiCommon ${OSX_APPKIT}) + target_link_libraries(AusweisAppUiCommon ${OSX_APPKIT} ${OSX_USERNOTIFICATIONS}) endif() diff --git a/src/ui/common/HelpAction.cpp b/src/ui/common/HelpAction.cpp index 9c9be509b..3a6dadcfe 100644 --- a/src/ui/common/HelpAction.cpp +++ b/src/ui/common/HelpAction.cpp @@ -32,6 +32,7 @@ const QMap HelpAction::mQmlHelpMapping = { {QStringLiteral("providerDetails"), QStringLiteral("provider-list.html#provider-details")}, {QStringLiteral("history"), QStringLiteral("history.html")}, {QStringLiteral("settings"), QStringLiteral("settings.html")}, + {QStringLiteral("settingsGeneral"), QStringLiteral("settings-general.html")}, {QStringLiteral("settingsRemoteReader"), QStringLiteral("settings-remote-reader.html")}, {QStringLiteral("settingsPcscReader"), QStringLiteral("settings-pcsc-reader.html")}, {QStringLiteral("settingsSecurityPrivacy"), QStringLiteral("settings-security-privacy.html")}, diff --git a/src/ui/common/PlatformTools.h b/src/ui/common/PlatformTools.h index 4f4b85fbc..82e1495ef 100644 --- a/src/ui/common/PlatformTools.h +++ b/src/ui/common/PlatformTools.h @@ -4,6 +4,7 @@ #pragma once +#include namespace governikus { @@ -13,6 +14,7 @@ class PlatformTools public: static void hideFromTaskbar(); static void restoreToTaskbar(); + static void postNotification(const QString& pTitle, const QString& pMessage); }; } // namespace governikus diff --git a/src/ui/common/PlatformTools_generic.cpp b/src/ui/common/PlatformTools_generic.cpp index 372a4dbc2..0001efbe0 100644 --- a/src/ui/common/PlatformTools_generic.cpp +++ b/src/ui/common/PlatformTools_generic.cpp @@ -16,3 +16,10 @@ void PlatformTools::hideFromTaskbar() void PlatformTools::restoreToTaskbar() { } + + +void PlatformTools::postNotification(const QString& pTitle, const QString& pMessage) +{ + Q_UNUSED(pTitle) + Q_UNUSED(pMessage) +} diff --git a/src/ui/common/PlatformTools_osx.mm b/src/ui/common/PlatformTools_osx.mm index 4e1574cd5..c12a52153 100644 --- a/src/ui/common/PlatformTools_osx.mm +++ b/src/ui/common/PlatformTools_osx.mm @@ -4,8 +4,15 @@ #include "PlatformTools.h" +#include +#include + +#include + #import +#import +Q_DECLARE_LOGGING_CATEGORY(gui) using namespace governikus; @@ -27,3 +34,64 @@ TransformProcessType(&psn, kProcessTransformToForegroundApplication); [NSApp activateIgnoringOtherApps: YES]; } + + +void ensureNotificationPermission(const std::function& pCallback) +{ +#ifdef QT_NO_DEBUG + if (@available(macOS 10.14, *)) + { + UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; + [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* _Nonnull settings){ + if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) + { + pCallback(); + return; + } + + const auto& requestedOptions = UNAuthorizationOptionProvidesAppNotificationSettings & UNAuthorizationOptionAlert; + [center requestAuthorizationWithOptions:requestedOptions completionHandler:^(BOOL granted, NSError* _Nullable error){ + if (error != nil) + { + qCDebug(gui) << "Error when requesting authorization:" << error.localizedDescription; + } + + if (granted) + { + pCallback(); + } + }]; + }]; + } +#else + Q_UNUSED(pCallback) +#endif +} + + +void PlatformTools::postNotification(const QString& pTitle, const QString& pMessage) +{ +#ifdef QT_NO_DEBUG + if (@available(macOS 10.14, *)) + { + ensureNotificationPermission([pTitle, pMessage]{ + UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; + + UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init]; + content.title = pTitle.toNSString(); + content.body = pMessage.toNSString(); + UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"AA2Notification" content:content trigger:nil]; + + [center addNotificationRequest:request withCompletionHandler:^(NSError* _Nullable error){ + if (error != nil) + { + qCDebug(gui) << "Failed to post notification:" << error.localizedDescription; + } + }]; + }); + } +#else + Q_UNUSED(pTitle) + Q_UNUSED(pMessage) +#endif +} diff --git a/src/ui/common/TrayIcon.cpp b/src/ui/common/TrayIcon.cpp index b59a2b0ef..c8b40d830 100644 --- a/src/ui/common/TrayIcon.cpp +++ b/src/ui/common/TrayIcon.cpp @@ -78,7 +78,12 @@ void TrayIcon::create() mTrayIcon->setToolTip(QCoreApplication::applicationName()); - mTrayIcon->show(); +#ifdef Q_OS_MACOS + if (Env::getSingleton()->getGeneralSettings().isAutoStart()) +#endif + { + mTrayIcon->show(); + } //: LABEL DESKTOP showMessage(QCoreApplication::applicationName(), tr("Application was started.")); #endif @@ -138,14 +143,28 @@ void TrayIcon::shutdown() } -void TrayIcon::hide() +void TrayIcon::setVisible(bool pVisible) +{ +#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) + if (mTrayIcon) + { + mTrayIcon->setVisible(pVisible); + } +#else + Q_UNUSED(pVisible) +#endif +} + + +bool TrayIcon::isVisible() const { #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) if (mTrayIcon) { - mTrayIcon->hide(); + mTrayIcon->isVisible(); } #endif + return false; } diff --git a/src/ui/common/TrayIcon.h b/src/ui/common/TrayIcon.h index c4ac1875e..f70246d48 100644 --- a/src/ui/common/TrayIcon.h +++ b/src/ui/common/TrayIcon.h @@ -39,7 +39,8 @@ class TrayIcon [[nodiscard]] const QIcon& getIcon() const; void create(); void shutdown(); - void hide(); + void setVisible(bool pVisible); + [[nodiscard]] bool isVisible() const; void showMessage(const QString& pTitle, const QString& pMessage); diff --git a/src/ui/qml/UIPlugInQml.cpp b/src/ui/qml/UIPlugInQml.cpp index 9d2fd2cb3..2aec7a0cb 100644 --- a/src/ui/qml/UIPlugInQml.cpp +++ b/src/ui/qml/UIPlugInQml.cpp @@ -406,6 +406,7 @@ void UIPlugInQml::onApplicationInitialized() connect(Env::getSingleton(), &SelfAuthModel::fireStartWorkflow, this, &UIPlugIn::fireSelfAuthenticationRequested); connect(Env::getSingleton(), &RemoteServiceModel::fireStartWorkflow, this, &UIPlugIn::fireRemoteServiceRequested); connect(Env::getSingleton()->getEventHandler(), &LogEventHandler::fireRawLog, this, &UIPlugInQml::onRawLog, Qt::QueuedConnection); + connect(Env::getSingleton(), &SettingsModel::fireAutoStartChanged, this, &UIPlugInQml::onAutoStartChanged); const auto* service = Env::getSingleton(); connect(service, &Service::fireAppcastFinished, this, &UIPlugInQml::onUpdateAvailable); @@ -420,9 +421,14 @@ void UIPlugInQml::onApplicationStarted() mTrayIcon.create(); #if defined(Q_OS_WIN) || (defined(Q_OS_BSD4) && !defined(Q_OS_IOS)) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) - bool showSetupAssistant = Enum::fromString(Env::getSingleton()->getGeneralSettings().getStartupModule(), UiModule::TUTORIAL) == UiModule::TUTORIAL; - bool developerMode = Env::getSingleton()->getGeneralSettings().isDeveloperMode(); - if (!QSystemTrayIcon::isSystemTrayAvailable() || showSetupAssistant || developerMode) + const auto& generalSettings = Env::getSingleton()->getGeneralSettings(); + const bool showSetupAssistant = Enum::fromString(generalSettings.getStartupModule(), UiModule::TUTORIAL) == UiModule::TUTORIAL; + const bool developerMode = generalSettings.isDeveloperMode(); + bool missingTrayIcon = !QSystemTrayIcon::isSystemTrayAvailable(); +#ifdef Q_OS_MACOS + missingTrayIcon |= !Env::getSingleton()->getGeneralSettings().isAutoStart(); +#endif + if (missingTrayIcon || showSetupAssistant || developerMode) #endif { QMetaObject::invokeMethod(this, &UIPlugInQml::show, Qt::QueuedConnection); @@ -437,6 +443,13 @@ void UIPlugInQml::onApplicationStarted() void UIPlugInQml::onShowUi(UiModule pModule) { PlatformTools::restoreToTaskbar(); +#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) + const auto& startupModule = Enum::fromString(Env::getSingleton()->getGeneralSettings().getStartupModule(), UiModule::TUTORIAL); + if (pModule == UiModule::CURRENT && startupModule == UiModule::TUTORIAL) + { + pModule = UiModule::TUTORIAL; + } +#endif if (isDominated()) { pModule = UiModule::CURRENT; @@ -674,6 +687,14 @@ void UIPlugInQml::onRawLog(const QString& pMessage, const QString& pCategoryName { if (pCategoryName == QLatin1String("developermode") || pCategoryName == QLatin1String("feedback")) { +#ifdef Q_OS_MACOS + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) + { + PlatformTools::postNotification(QCoreApplication::applicationName(), pMessage); + return; + } + +#endif mTrayIcon.showMessage(QCoreApplication::applicationName(), pMessage); } } @@ -824,6 +845,14 @@ void UIPlugInQml::onWindowPaletteChanged() } +void UIPlugInQml::onAutoStartChanged() +{ +#ifdef Q_OS_MACOS + mTrayIcon.setVisible(Env::getSingleton()->getGeneralSettings().isAutoStart()); +#endif +} + + void UIPlugInQml::applyPlatformStyle(const QString& pPlatformStyle) { if (mExplicitPlatformStyle != pPlatformStyle) diff --git a/src/ui/qml/UIPlugInQml.h b/src/ui/qml/UIPlugInQml.h index 34e9329f0..b464a53d6 100644 --- a/src/ui/qml/UIPlugInQml.h +++ b/src/ui/qml/UIPlugInQml.h @@ -113,6 +113,7 @@ class UIPlugInQml void onRawLog(const QString& pMessage, const QString& pCategoryName); void onWindowPaletteChanged(); + void onAutoStartChanged(); public Q_SLOTS: void doRefresh(); diff --git a/src/workflows/remote_device/states/StateProcessRemoteMessages.cpp b/src/workflows/remote_device/states/StateProcessRemoteMessages.cpp index ce3e2c4b5..41253d6f2 100644 --- a/src/workflows/remote_device/states/StateProcessRemoteMessages.cpp +++ b/src/workflows/remote_device/states/StateProcessRemoteMessages.cpp @@ -150,7 +150,5 @@ void StateProcessRemoteMessages::onExit(QEvent* pEvent) disconnect(connection); } - stopScanIfNecessary(); - AbstractState::onExit(pEvent); } diff --git a/src/workflows/remote_device/states/StateStopRemoteService.cpp b/src/workflows/remote_device/states/StateStopRemoteService.cpp index e742f0312..a3a1c5d66 100644 --- a/src/workflows/remote_device/states/StateStopRemoteService.cpp +++ b/src/workflows/remote_device/states/StateStopRemoteService.cpp @@ -39,5 +39,7 @@ void StateStopRemoteService::onExit(QEvent* pEvent) // Request an asynchronous update of all retry counters Env::getSingleton()->updateRetryCounters(); + stopScanIfNecessary(); + AbstractState::onExit(pEvent); } diff --git a/test/qt/configuration/test_ProviderConfigurationParser.cpp b/test/qt/configuration/test_ProviderConfigurationParser.cpp index 1497d0f05..270c51bfb 100644 --- a/test/qt/configuration/test_ProviderConfigurationParser.cpp +++ b/test/qt/configuration/test_ProviderConfigurationParser.cpp @@ -222,8 +222,8 @@ class test_ProviderConfigurationParser QTest::addColumn("majorVersion"); QTest::addColumn("count"); - const int all = 94; - const int withEidSupport = 70; + const int all = 95; + const int withEidSupport = 72; QTest::newRow("win") << QOperatingSystemVersion::Windows << -1 << all; QTest::newRow("mac") << QOperatingSystemVersion::MacOS << -1 << all; QTest::newRow("linux") << QOperatingSystemVersion::Unknown << -1 << all; diff --git a/test/qt/configuration/test_ReaderConfiguration.cpp b/test/qt/configuration/test_ReaderConfiguration.cpp index 1d493592a..a9c8a1c42 100644 --- a/test/qt/configuration/test_ReaderConfiguration.cpp +++ b/test/qt/configuration/test_ReaderConfiguration.cpp @@ -115,21 +115,21 @@ class test_ReaderConfiguration QTest::newRow("KOBIL IDToken") << UsbId(0x0D46, 0x301D) << "KOBIL Systems IDToken" << "KOBIL IDToken" << "img_KOBIL_ID_Token" << "^KOBIL (Systems )?IDToken( 0)?$"; - QTest::newRow("SCM SDI011") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader" << "SDI011 Contactless Reader" << "img_Identive_SDI011" << "^(SCM Microsystems Inc. )?SDI011G? ((Contactless Reader( 0)?)|((USB Smart Card|Contactless) Reader\\([12]\\)))$"; - QTest::newRow("SCM SCL011") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011 Contactless Reader" << "SCL01x Contactless Reader" << "img_Identive_SCL011" << "^(SCM Microsystems Inc. )?SCL011G? Contactless Reader( 0)?$"; + QTest::newRow("Identiv SDI011") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader" << "Identiv SDI011 Dual Interface Smart Card Reader" << "img_Identive_SDI011" << "^(SCM Microsystems Inc. )?SDI011G? ((Contactless Reader( 0)?)|((USB Smart Card|Contactless) Reader\\([12]\\)))$"; + QTest::newRow("Identiv SCL011") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011 Contactless Reader" << "Identiv SCL01x Contactless Smart Card Reader" << "img_Identive_SCL011" << "^(SCM Microsystems Inc. )?SCL011G? Contactless Reader( 0)?$"; QTest::newRow("ACS-ACR1281U") << UsbId(0x072F, 0x0901) << "ACS ACR1281 PICC Reader" << "ACS ACR1281U" << "img_ACS_ACR1281U" << "ACS ACR1281 PICC Reader( 0)?"; QTest::newRow("ACS-ACR1252U") << UsbId(0x072F, 0x223B) << "ACS ACR1252 1S CL Reader PICC 0" << "ACS ACR1252U" << "img_ACS_ACR1252U" << "^ACS ACR1252 (1S CL|Dual)? Reader(( PICC 0)|\\(1\\))?$"; - QTest::newRow("OMNIKEY 5021") << UsbId(0x076B, 0x5340) << "OMNIKEY CardMan 5x21-CL 0" << "OMNIKEY 5021-CL" << "img_HID_Omnikey_Mobile_Reader_502X_CL" << "OMNIKEY CardMan 5x21-CL 0|OMNIKEY CardMan \\(076B:5340\\) 5021 CL"; - QTest::newRow("OMNIKEY 5022") << UsbId(0x076B, 0x5022) << "HID Global OMNIKEY 5022 Smart Card Reader 0" << "OMNIKEY 5022-CL" << "img_HID_Omnikey_Mobile_Reader_502X_CL" << "HID Global OMNIKEY 5022 Smart Card Reader( 0)?$"; - QTest::newRow("OMNIKEY 5321 v2") << UsbId(0x076B, 0x5321) << "OOMNIKEY CardMan 5x21-CL 0" << "OMNIKEY 5321 v2" << "img_HID_Global_OMNIKEY_5321_V2" << R"(OMNIKEY CardMan 5x21-CL 0|OMNIKEY CardMan \(076B:5321\) 5321(\(1\)|\(2\)))"; - QTest::newRow("OMNIKEY 5421") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan 5x21-CL 0" << "OMNIKEY 5421" << "img_HID_Omnikey_542x" << R"(OMNIKEY CardMan 5x21-CL 0|OMNIKEY Smart Card Reader USB 0|OMNIKEY CardMan \(076B:5421\) 5421(\(1\)|\(2\)))"; - QTest::newRow("OMNIKEY 5422") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY 5422CL Smartcard Reader 0" << "OMNIKEY 5422" << "img_HID_Omnikey_542x" << R"(HID Global OMNIKEY 5422CL Smartcard Reader 0|HID Global OMNIKEY Smartcard Reader (\(1\)|\(2\)))"; + QTest::newRow("HID OMNIKEY 5021") << UsbId(0x076B, 0x5340) << "OMNIKEY CardMan 5x21-CL 0" << "HID OMNIKEY 5021-CL" << "img_HID_Omnikey_Mobile_Reader_502X_CL" << "OMNIKEY CardMan 5x21-CL 0|OMNIKEY CardMan \\(076B:5340\\) 5021 CL"; + QTest::newRow("HID OMNIKEY 5022") << UsbId(0x076B, 0x5022) << "HID Global OMNIKEY 5022 Smart Card Reader 0" << "HID OMNIKEY 5022-CL" << "img_HID_Omnikey_Mobile_Reader_502X_CL" << "HID Global OMNIKEY 5022 Smart Card Reader( 0)?$"; + QTest::newRow("HID OMNIKEY 5321 v2") << UsbId(0x076B, 0x5321) << "OOMNIKEY CardMan 5x21-CL 0" << "HID OMNIKEY 5321 v2" << "img_HID_Global_OMNIKEY_5321_V2" << R"(OMNIKEY CardMan 5x21-CL 0|OMNIKEY CardMan \(076B:5321\) 5321(\(1\)|\(2\)))"; + QTest::newRow("HID OMNIKEY 5421") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan 5x21-CL 0" << "HID OMNIKEY 5421" << "img_HID_Omnikey_542x" << R"(OMNIKEY CardMan 5x21-CL 0|OMNIKEY Smart Card Reader USB 0|OMNIKEY CardMan \(076B:5421\) 5421(\(1\)|\(2\)))"; + QTest::newRow("HID OMNIKEY 5422") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY 5422CL Smartcard Reader 0" << "HID OMNIKEY 5422" << "img_HID_Omnikey_542x" << R"(HID Global OMNIKEY 5422CL Smartcard Reader 0|HID Global OMNIKEY Smartcard Reader (\(1\)|\(2\)))"; QTest::newRow("FEIG OBID myAXXESS RFID-Reader") << UsbId(0x0AB1, 0x0003) << "FEIG ELECTRONIC GmbH OBID myAXXESS basic Slot:CL 358334430" << "OBID RFID-Reader" << "img_FEIG_myAXXES_basic" << "FEIG ELECTRONIC GmbH OBID myAXXESS basic Slot:CL 358334430"; - QTest::newRow("Gemalto-Prox-DU") << UsbId(0x08E6, 0x5503) << "Gemalto Prox-DU Contactless_" << "Prox-DU HID" << "img_Gemalto_Prox_DU" << R"(Gemalto .*Prox(-DU| Dual)( Contactless_| USB PC Link(Reader| Reader)(\(2\)|\(1\))))"; + QTest::newRow("Gemalto-Prox-DU") << UsbId(0x08E6, 0x5503) << "Gemalto Prox-DU Contactless_" << "Gemalto Prox-DU HID" << "img_Gemalto_Prox_DU" << R"(Gemalto .*Prox(-DU| Dual)( Contactless_| USB PC Link(Reader| Reader)(\(2\)|\(1\))))"; QTest::newRow("Gemalto-Prox-SU") << UsbId(0x08E6, 0x5504) << "Gemalto Prox-SU Contactless_" << "Gemalto Prox-SU Contactless" << "img_Gemalto_Prox_SU" << R"(Gemalto Prox( |-)SU( Contactless_| USB PC LinkReader(\(1\)|\(2\))))"; QTest::newRow("Identiv-SCL-3711") << UsbId(0x04E6, 0x5591) << "SCM Microsystems SCL3711 reader & NFC device 0" << "Identiv SCL3711" << "img_Identive_SCL3711" << "(SCM Microsystems SCL3711 reader & NFC device 0|SCL3711 Reader and NFC device)"; @@ -204,22 +204,22 @@ class test_ReaderConfiguration QTest::newRow("KOBIL IDToken-windows-7-10") << UsbId(0x0D46, 0x301D) << "KOBIL IDToken 0" << "KOBIL IDToken"; QTest::newRow("KOBIL IDToken-macosx-10.13-11.0") << UsbId(0x0D46, 0x301D) << "KOBIL Systems IDToken" << "KOBIL IDToken"; - QTest::newRow("SCM SDI011-windows-7-10-1") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader 0" << "SDI011 Contactless Reader"; - QTest::newRow("SCM SDI011-windows-7-10-2") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Smart Card Reader 0" << "SCM Microsystems Inc. SDI011 Smart Card Reader 0"; - QTest::newRow("SCM SDI011-windows-7-10-3") << UsbId(0x04E6, 0x512B) << "SDI011 Contactless Reader" << "SDI011 Contactless Reader"; - QTest::newRow("SCM SDI011-windows-7-10-4") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011G Contactless Reader 0" << "SDI011 Contactless Reader"; - QTest::newRow("SCM SDI011-windows-7-10-5") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011G Smart Card Reader 0" << "SCM Microsystems Inc. SDI011G Smart Card Reader 0"; - QTest::newRow("SCM SDI011-macosx-10.13-11.0") << UsbId(0x04E6, 0x512B) << "SDI011 USB Smart Card Reader(1)" << "SDI011 Contactless Reader"; - QTest::newRow("SCM SDI011-macosx-10.13-11.0") << UsbId(0x04E6, 0x512B) << "SDI011 USB Smart Card Reader(2)" << "SDI011 Contactless Reader"; - QTest::newRow("SCM SDI011-macosx-10.13-10.15-1") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader(1)" << "SDI011 Contactless Reader"; - QTest::newRow("SCM SDI011-macosx-10.13-10.15-2") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader(2)" << "SDI011 Contactless Reader"; - - QTest::newRow("SCM SCL011-windows-7-10-1") << UsbId(0x04E6, 0x5292) << "SCL011 Contactless Reader" << "SCL01x Contactless Reader"; - QTest::newRow("SCM SCL011-windows-7-10-1") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL010 Contactless Reader" << "SCM Microsystems Inc. SCL010 Contactless Reader"; - QTest::newRow("SCM SCL011-windows-7-10-2") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011 Contactless Reader 0" << "SCL01x Contactless Reader"; - QTest::newRow("SCM SCL011-windows-7-10-3") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011G Contactless Reader 0" << "SCL01x Contactless Reader"; - QTest::newRow("SCM SCL011-macosx-10.13-11.0-1") << UsbId(0x04E6, 0x5292) << "SCL011 Contactless Reader" << "SCL01x Contactless Reader"; - QTest::newRow("SCM SCL011-macosx-10.13-11.0-2") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011 Contactless Reader" << "SCL01x Contactless Reader"; + QTest::newRow("Identiv SDI011-windows-7-10-1") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader 0" << "Identiv SDI011 Dual Interface Smart Card Reader"; + QTest::newRow("Identiv SDI011-windows-7-10-2") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Smart Card Reader 0" << "SCM Microsystems Inc. SDI011 Smart Card Reader 0"; + QTest::newRow("Identiv SDI011-windows-7-10-3") << UsbId(0x04E6, 0x512B) << "SDI011 Contactless Reader" << "Identiv SDI011 Dual Interface Smart Card Reader"; + QTest::newRow("Identiv SDI011-windows-7-10-4") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011G Contactless Reader 0" << "Identiv SDI011 Dual Interface Smart Card Reader"; + QTest::newRow("Identiv SDI011-windows-7-10-5") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011G Smart Card Reader 0" << "SCM Microsystems Inc. SDI011G Smart Card Reader 0"; + QTest::newRow("Identiv SDI011-macosx-10.13-11.0") << UsbId(0x04E6, 0x512B) << "SDI011 USB Smart Card Reader(1)" << "Identiv SDI011 Dual Interface Smart Card Reader"; + QTest::newRow("Identiv SDI011-macosx-10.13-11.0") << UsbId(0x04E6, 0x512B) << "SDI011 USB Smart Card Reader(2)" << "Identiv SDI011 Dual Interface Smart Card Reader"; + QTest::newRow("Identiv SDI011-macosx-10.13-10.15-1") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader(1)" << "Identiv SDI011 Dual Interface Smart Card Reader"; + QTest::newRow("Identiv SDI011-macosx-10.13-10.15-2") << UsbId(0x04E6, 0x512B) << "SCM Microsystems Inc. SDI011 Contactless Reader(2)" << "Identiv SDI011 Dual Interface Smart Card Reader"; + + QTest::newRow("Identiv SCL011-windows-7-10-1") << UsbId(0x04E6, 0x5292) << "SCL011 Contactless Reader" << "Identiv SCL01x Contactless Smart Card Reader"; + QTest::newRow("Identiv SCL011-windows-7-10-2") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL010 Contactless Reader" << "SCM Microsystems Inc. SCL010 Contactless Reader"; + QTest::newRow("Identiv SCL011-windows-7-10-3") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011 Contactless Reader 0" << "Identiv SCL01x Contactless Smart Card Reader"; + QTest::newRow("Identiv SCL011-windows-7-10-4") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011G Contactless Reader 0" << "Identiv SCL01x Contactless Smart Card Reader"; + QTest::newRow("Identiv SCL011-macosx-10.13-11.0-1") << UsbId(0x04E6, 0x5292) << "SCL011 Contactless Reader" << "Identiv SCL01x Contactless Smart Card Reader"; + QTest::newRow("Identiv SCL011-macosx-10.13-11.0-2") << UsbId(0x04E6, 0x5292) << "SCM Microsystems Inc. SCL011 Contactless Reader" << "Identiv SCL01x Contactless Smart Card Reader"; QTest::newRow("ACS-ACR1281U-windows-7-10") << UsbId(0x072F, 0x0901) << "ACS ACR1281 PICC Reader 0" << "ACS ACR1281U"; QTest::newRow("ACS-ACR1281U-macosx-10.13-11.0") << UsbId(0x072F, 0x0901) << "ACS ACR1281 PICC Reader" << "ACS ACR1281U"; @@ -234,34 +234,34 @@ class test_ReaderConfiguration QTest::newRow("ACS-ACR1252U-macosx-10.13-11.0-4") << UsbId(0x072F, 0x223B) << "ACS ACR1252 1S CL Reader(2)" << "ACS ACR1252 1S CL Reader(2)"; QTest::newRow("ACS-ACR1252U-macosx-10.13-11.0-5") << UsbId(0x072F, 0x223B) << "ACS ACR1252 Dual Reader" << "ACS ACR1252U"; - QTest::newRow("OMNIKEY 5021-windows-7-10") << UsbId(0x076B, 0x5340) << "OMNIKEY CardMan 5x21-CL 0" << "OMNIKEY 5021-CL"; - QTest::newRow("OMNIKEY 5021-macosx-10.13-11.0") << UsbId(0x076B, 0x5340) << "OMNIKEY CardMan (076B:5340) 5021 CL" << "OMNIKEY 5021-CL"; + QTest::newRow("HID OMNIKEY 5021-windows-7-10") << UsbId(0x076B, 0x5340) << "OMNIKEY CardMan 5x21-CL 0" << "HID OMNIKEY 5021-CL"; + QTest::newRow("HID OMNIKEY 5021-macosx-10.13-11.0") << UsbId(0x076B, 0x5340) << "OMNIKEY CardMan (076B:5340) 5021 CL" << "HID OMNIKEY 5021-CL"; - QTest::newRow("OMNIKEY 5022-windows-7-10") << UsbId(0x076B, 0x5022) << "HID Global OMNIKEY 5022 Smart Card Reader 0" << "OMNIKEY 5022-CL"; - QTest::newRow("OMNIKEY 5022-macosx-10.13-11.0") << UsbId(0x076B, 0x5022) << "HID Global OMNIKEY 5022 Smart Card Reader" << "OMNIKEY 5022-CL"; + QTest::newRow("HID OMNIKEY 5022-windows-7-10") << UsbId(0x076B, 0x5022) << "HID Global OMNIKEY 5022 Smart Card Reader 0" << "HID OMNIKEY 5022-CL"; + QTest::newRow("HID OMNIKEY 5022-macosx-10.13-11.0") << UsbId(0x076B, 0x5022) << "HID Global OMNIKEY 5022 Smart Card Reader" << "HID OMNIKEY 5022-CL"; - QTest::newRow("OMNIKEY 5321 v2-windows-7-10-1") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan 5x21 0" << "OMNIKEY CardMan 5x21 0"; - QTest::newRow("OMNIKEY 5321 v2-windows-7-10-2") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan 5x21-CL 0" << "OMNIKEY 5321 v2"; - QTest::newRow("OMNIKEY 5321 v2-macosx-10.13-11.0-1") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan (076B:5321) 5321(1)" << "OMNIKEY 5321 v2"; - QTest::newRow("OMNIKEY 5321 v2-macosx-10.13-11.0-2") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan (076B:5321) 5321(2)" << "OMNIKEY 5321 v2"; + QTest::newRow("HID OMNIKEY 5321 v2-windows-7-10-1") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan 5x21 0" << "OMNIKEY CardMan 5x21 0"; + QTest::newRow("HID OMNIKEY 5321 v2-windows-7-10-2") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan 5x21-CL 0" << "HID OMNIKEY 5321 v2"; + QTest::newRow("HID OMNIKEY 5321 v2-macosx-10.13-11.0-1") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan (076B:5321) 5321(1)" << "HID OMNIKEY 5321 v2"; + QTest::newRow("HID OMNIKEY 5321 v2-macosx-10.13-11.0-2") << UsbId(0x076B, 0x5321) << "OMNIKEY CardMan (076B:5321) 5321(2)" << "HID OMNIKEY 5321 v2"; - QTest::newRow("OMNIKEY 5421-windows-7-10-1") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan 5x21 0" << "OMNIKEY CardMan 5x21 0"; - QTest::newRow("OMNIKEY 5421-windows-7-10-2") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan 5x21-CL 0" << "OMNIKEY 5421"; - QTest::newRow("OMNIKEY 5421-windows-7-10-3") << UsbId(0x076B, 0x5421) << "OMNIKEY Smart Card Reader USB 0" << "OMNIKEY 5421"; - QTest::newRow("OMNIKEY 5421-macosx-10.13-11.0-1") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan (076B:5421) 5421(1)" << "OMNIKEY 5421"; - QTest::newRow("OMNIKEY 5421-macosx-10.13-11.0-2") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan (076B:5421) 5421(2)" << "OMNIKEY 5421"; + QTest::newRow("HID OMNIKEY 5421-windows-7-10-1") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan 5x21 0" << "OMNIKEY CardMan 5x21 0"; + QTest::newRow("HID OMNIKEY 5421-windows-7-10-2") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan 5x21-CL 0" << "HID OMNIKEY 5421"; + QTest::newRow("HID OMNIKEY 5421-windows-7-10-3") << UsbId(0x076B, 0x5421) << "OMNIKEY Smart Card Reader USB 0" << "HID OMNIKEY 5421"; + QTest::newRow("HID OMNIKEY 5421-macosx-10.13-11.0-1") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan (076B:5421) 5421(1)" << "HID OMNIKEY 5421"; + QTest::newRow("HID OMNIKEY 5421-macosx-10.13-11.0-2") << UsbId(0x076B, 0x5421) << "OMNIKEY CardMan (076B:5421) 5421(2)" << "HID OMNIKEY 5421"; - QTest::newRow("OMNIKEY 5422-windows-7-10-1") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY 5422 Smartcard Reader 0" << "HID Global OMNIKEY 5422 Smartcard Reader 0"; - QTest::newRow("OMNIKEY 5422-windows-7-10-2") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY 5422CL Smartcard Reader 0" << "OMNIKEY 5422"; - QTest::newRow("OMNIKEY 5422-macosx-10.13-11.0-1") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY Smartcard Reader (1)" << "OMNIKEY 5422"; - QTest::newRow("OMNIKEY 5422-macosx-10.13-11.0-2") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY Smartcard Reader (2)" << "OMNIKEY 5422"; + QTest::newRow("HID OMNIKEY 5422-windows-7-10-1") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY 5422 Smartcard Reader 0" << "HID Global OMNIKEY 5422 Smartcard Reader 0"; + QTest::newRow("HID OMNIKEY 5422-windows-7-10-2") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY 5422CL Smartcard Reader 0" << "HID OMNIKEY 5422"; + QTest::newRow("HID OMNIKEY 5422-macosx-10.13-11.0-1") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY Smartcard Reader (1)" << "HID OMNIKEY 5422"; + QTest::newRow("HID OMNIKEY 5422-macosx-10.13-11.0-2") << UsbId(0x076B, 0x5422) << "HID Global OMNIKEY Smartcard Reader (2)" << "HID OMNIKEY 5422"; QTest::newRow("FEIG OBID myAXXESS RFID-Reader-windows-7-10") << UsbId(0x0AB1, 0x0003) << "FEIG ELECTRONIC GmbH OBID myAXXESS basic Slot:CL 358334430" << "OBID RFID-Reader"; - QTest::newRow("Gemalto-Prox-DU-windows-7-10-1") << UsbId(0x08E6, 0x5503) << "Gemalto Prox-DU Contactless_10900383 0" << "Prox-DU HID"; + QTest::newRow("Gemalto-Prox-DU-windows-7-10-1") << UsbId(0x08E6, 0x5503) << "Gemalto Prox-DU Contactless_10900383 0" << "Gemalto Prox-DU HID"; QTest::newRow("Gemalto-Prox-DU-windows-7-10-2") << UsbId(0x08E6, 0x5503) << "Gemalto Prox-DU Contact_10900383 0" << "Gemalto Prox-DU Contact_10900383 0"; - QTest::newRow("Gemalto-Prox-DU-windows-macosx-10.13-11.0-1") << UsbId(0x08E6, 0x5503) << "Gemalto Prox Dual USB PC Link Reader(1)" << "Prox-DU HID"; - QTest::newRow("Gemalto-Prox-DU-windows-macosx-10.13-11.0-2") << UsbId(0x08E6, 0x5503) << "Gemalto Prox Dual USB PC Link Reader(2)" << "Prox-DU HID"; + QTest::newRow("Gemalto-Prox-DU-windows-macosx-10.13-11.0-1") << UsbId(0x08E6, 0x5503) << "Gemalto Prox Dual USB PC Link Reader(1)" << "Gemalto Prox-DU HID"; + QTest::newRow("Gemalto-Prox-DU-windows-macosx-10.13-11.0-2") << UsbId(0x08E6, 0x5503) << "Gemalto Prox Dual USB PC Link Reader(2)" << "Gemalto Prox-DU HID"; QTest::newRow("Gemalto-Prox-SU-windows-7-10-1") << UsbId(0x08E6, 0x5504) << "Gemalto Prox-SU Contactless_10800004 0" << "Gemalto Prox-SU Contactless"; QTest::newRow("Gemalto-Prox-SU-windows-7-10-2") << UsbId(0x08E6, 0x5504) << "Gemalto Prox-SU Contact_10800004 0" << "Gemalto Prox-SU Contact_10800004 0";