From 638c53dad6350d7f9c00e7676fe48b44eb07ebe8 Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Fri, 16 Jan 2026 17:12:12 +0100 Subject: [PATCH] sso page to manually cancel sso connection --- Linphone/core/App.cpp | 76 ++++- Linphone/core/App.hpp | 6 + Linphone/core/account/AccountProxy.cpp | 6 + Linphone/core/account/AccountProxy.hpp | 1 + Linphone/core/chat/ChatList.cpp | 4 +- Linphone/data/languages/de.ts | 301 +++++++++--------- Linphone/data/languages/en.ts | 301 +++++++++--------- Linphone/data/languages/fr.ts | 301 +++++++++--------- Linphone/model/auth/OIDCModel.cpp | 32 +- Linphone/model/auth/OIDCModel.hpp | 6 + Linphone/model/core/CoreModel.cpp | 22 +- Linphone/model/core/CoreModel.hpp | 6 + .../Popup/Dialog/AuthenticationDialog.qml | 1 + Linphone/view/Page/Layout/Main/MainLayout.qml | 1 - .../Page/Main/Account/AccountListView.qml | 1 - Linphone/view/Page/Main/Call/CallPage.qml | 1 - Linphone/view/Page/Main/Call/WaitingRoom.qml | 1 - Linphone/view/Page/Main/Chat/ChatPage.qml | 1 - Linphone/view/Page/Window/Main/MainWindow.qml | 44 ++- 19 files changed, 666 insertions(+), 446 deletions(-) diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index f24f06c37..3e41237b1 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -329,6 +329,9 @@ App::App(int &argc, char *argv[]) mEventCountNotifier = new EventCountNotifier(this); mDateUpdateTimer.start(); + mOIDCRefreshTimer.setInterval(1000); + mOIDCRefreshTimer.setSingleShot(false); + #ifdef Q_OS_LINUX exportDesktopFile(); #endif @@ -384,7 +387,29 @@ void App::setSelf(QSharedPointer(me)) { mCoreModelConnection->makeConnectToModel( &CoreModel::globalStateChanged, [this](const std::shared_ptr &core, linphone::GlobalState gstate, const std::string &message) { - mCoreModelConnection->invokeToCore([this, gstate] { setCoreStarted(gstate == linphone::GlobalState::On); }); + mCoreModelConnection->invokeToCore([this, gstate] { + setCoreStarted(gstate == linphone::GlobalState::On); + if (gstate == linphone::GlobalState::Configuring) { + if (mMainWindow) { + QMetaObject::invokeMethod(mMainWindow, "openSSOPage", Qt::DirectConnection); + } else { + connect( + this, &App::mainWindowChanged, this, + [this] { + mCoreModelConnection->invokeToModel([this] { + auto gstate = CoreModel::getInstance()->getCore()->getGlobalState(); + if (gstate == linphone::GlobalState::Configuring) + mCoreModelConnection->invokeToCore([this] { + if (mMainWindow) + QMetaObject::invokeMethod(mMainWindow, "openSSOPage", + Qt::DirectConnection); + }); + }); + }, + Qt::SingleShotConnection); + } + } + }); }); mCoreModelConnection->makeConnectToModel(&CoreModel::authenticationRequested, &App::onAuthenticationRequested); // Config error message @@ -425,7 +450,28 @@ void App::setSelf(QSharedPointer(me)) { // Synchronize state for because linphoneCore was ran before any connections. mCoreModelConnection->invokeToModel([this]() { auto state = CoreModel::getInstance()->getCore()->getGlobalState(); - mCoreModelConnection->invokeToCore([this, state] { setCoreStarted(state == linphone::GlobalState::On); }); + mCoreModelConnection->invokeToCore([this, state] { + setCoreStarted(state == linphone::GlobalState::On); + if (state == linphone::GlobalState::Configuring) { + if (mMainWindow) { + QMetaObject::invokeMethod(mMainWindow, "openSSOPage", Qt::DirectConnection); + } else { + connect( + this, &App::mainWindowChanged, this, + [this] { + mCoreModelConnection->invokeToModel([this] { + auto gstate = CoreModel::getInstance()->getCore()->getGlobalState(); + if (gstate == linphone::GlobalState::Configuring) + mCoreModelConnection->invokeToCore([this] { + if (mMainWindow) + QMetaObject::invokeMethod(mMainWindow, "openSSOPage", Qt::DirectConnection); + }); + }); + }, + Qt::SingleShotConnection); + } + } + }); }); mCoreModelConnection->makeConnectToModel(&CoreModel::unreadNotificationsChanged, [this] { @@ -477,6 +523,30 @@ void App::setSelf(QSharedPointer(me)) { }); }); + mCoreModelConnection->makeConnectToModel(&CoreModel::oidcRemainingTimeBeforeTimeoutChanged, + [this](int remainingTime) { + qDebug() << "App: oidc timeout changed"; + mCoreModelConnection->invokeToCore([this, remainingTime] { + mRemainingTimeBeforeOidcTimeout = remainingTime; + emit remainingTimeBeforeOidcTimeoutChanged(); + }); + }); + mCoreModelConnection->makeConnectToCore(&App::lForceOidcTimeout, [this] { + qDebug() << "App: force oidc timeout"; + mCoreModelConnection->invokeToModel([this] { emit CoreModel::getInstance()->forceOidcTimeout(); }); + }); + mCoreModelConnection->makeConnectToModel(&CoreModel::timeoutTimerStarted, [this]() { + qDebug() << "App: oidc timer started"; + mCoreModelConnection->invokeToCore([this] { mOIDCRefreshTimer.start(); }); + }); + mCoreModelConnection->makeConnectToModel(&CoreModel::timeoutTimerStopped, [this]() { + qDebug() << "App: oidc timer stopped"; + mCoreModelConnection->invokeToCore([this] { mOIDCRefreshTimer.stop(); }); + }); + connect(&mOIDCRefreshTimer, &QTimer::timeout, this, [this]() { + mCoreModelConnection->invokeToModel([this] { CoreModel::getInstance()->refreshOidcRemainingTime(); }); + }); + //--------------------------------------------------------------------------------------------- mCliModelConnection = SafeConnection::create(me, CliModel::getInstance()); mCliModelConnection->makeConnectToCore(&App::receivedMessage, [this](int, const QByteArray &byteArray) { @@ -1090,7 +1160,7 @@ bool App::notify(QObject *receiver, QEvent *event) { } if (event->type() == QEvent::MouseButtonPress) { auto window = findParentWindow(receiver); - if (getMainWindow() == window) { + if (getMainWindow() == window && mAccountList) { auto defaultAccountCore = mAccountList->getDefaultAccountCore(); if (defaultAccountCore && defaultAccountCore->getUnreadCallNotifications() > 0) { emit defaultAccountCore->lResetMissedCalls(); diff --git a/Linphone/core/App.hpp b/Linphone/core/App.hpp index 1c6fc2ec9..25b06e313 100644 --- a/Linphone/core/App.hpp +++ b/Linphone/core/App.hpp @@ -55,6 +55,8 @@ class App : public SingleApplication, public AbstractObject { Q_PROPERTY(QString sdkVersion READ getSdkVersion CONSTANT) Q_PROPERTY(ChatGui *currentChat READ getCurrentChat WRITE setCurrentChat NOTIFY currentChatChanged) Q_PROPERTY(QString localeAsString READ getLocaleAsString CONSTANT) + Q_PROPERTY(int remainingTimeBeforeOidcTimeout MEMBER mRemainingTimeBeforeOidcTimeout NOTIFY + remainingTimeBeforeOidcTimeoutChanged) public: App(int &argc, char *argv[]); @@ -219,6 +221,8 @@ signals: void chatsChanged(); void callHistoryChanged(); void localeChanged(); + void lForceOidcTimeout(); + void remainingTimeBeforeOidcTimeoutChanged(); // void executeCommand(QString command); private: @@ -257,6 +261,8 @@ private: QTimer mDateUpdateTimer; QDate mCurrentDate; float mScreenRatio = 1; + QTimer mOIDCRefreshTimer; + int mRemainingTimeBeforeOidcTimeout = 0; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/account/AccountProxy.cpp b/Linphone/core/account/AccountProxy.cpp index 4b363e191..bcb3acc17 100644 --- a/Linphone/core/account/AccountProxy.cpp +++ b/Linphone/core/account/AccountProxy.cpp @@ -24,6 +24,12 @@ #include "core/App.hpp" AccountProxy::AccountProxy(QObject *parent) : LimitProxy(parent) { + if (!App::getInstance()->getAccountList()) { + mList = AccountList::create(); + App::getInstance()->setAccountList(mList); + } + mList = App::getInstance()->getAccountList(); + setSourceModel(mList.get()); connect(this, &AccountProxy::initializedChanged, this, &AccountProxy::resetDefaultAccount); connect(this, &AccountProxy::initializedChanged, this, &AccountProxy::haveAccountChanged); } diff --git a/Linphone/core/account/AccountProxy.hpp b/Linphone/core/account/AccountProxy.hpp index 69e39db02..2cb2bdf10 100644 --- a/Linphone/core/account/AccountProxy.hpp +++ b/Linphone/core/account/AccountProxy.hpp @@ -59,6 +59,7 @@ signals: protected: bool mInitialized = false; + QSharedPointer mList; QSharedPointer mDefaultAccount; // When null, a new UI object is build from List }; diff --git a/Linphone/core/chat/ChatList.cpp b/Linphone/core/chat/ChatList.cpp index 4c32c990a..44e22befc 100644 --- a/Linphone/core/chat/ChatList.cpp +++ b/Linphone/core/chat/ChatList.cpp @@ -73,7 +73,9 @@ void ChatList::connectItem(QSharedPointer chat) { }; connect(chat.get(), &ChatCore::unreadMessagesCountChanged, this, [this, dataChange] { dataChange(); - auto defaultAccount = App::getInstance()->getAccountList()->getDefaultAccountCore(); + auto defaultAccount = App::getInstance()->getAccountList() + ? App::getInstance()->getAccountList()->getDefaultAccountCore() + : nullptr; if (defaultAccount) emit defaultAccount->lRefreshNotifications(); }); connect(chat.get(), &ChatCore::lastUpdatedTimeChanged, this, dataChange); diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index da99fb9e0..9a14d02d5 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -95,7 +95,7 @@ AccountListView - + add_an_account Add an account Konto hinzufügen @@ -674,141 +674,141 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Möchten Sie die Remote-Konfiguration von dieser Adresse herunterladen und anwenden? - - - + + + info_popup_error_title Error Fehler - - + + info_popup_configuration_failed_message Remote provisioning failed : %1 Remote-Provisionierung fehlgeschlagen: %1 - + info_popup_error_checking_update An error occured while trying to check update. Please try again later or contact support team. Fehler bei der Update-Prüfung. Bitte später erneut versuchen oder Support-Team kontaktieren. - + info_popup_new_version_download_label Herunterladen! - + info_popup_new_version_available_title New version available ! Neue Version verfügbar! - + info_popup_new_version_available_message A new version of Linphone (%1) is available. %2 Eine neue Version von Linphone (%1) ist unter %1 verfügbar - + info_popup_version_up_to_date_title Auf dem neuesten Stand - + info_popup_version_up_to_date_message Your version is up to date Ihre Version ist auf dem neuesten Stand - + configuration_error_detail not reachable nicht erreichbar - + application_description "A free and open source SIP video-phone." Ein kostenloses Open-Source SIP Video-Telefon. - + command_line_arg_order "Send an order to the application towards a command line" Kommandozeilen-Befehl an die Anwendung schicken - + command_line_option_show_help Zeige Hilfe - + command_line_option_show_app_version App-Version anzeigen - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Abzurufende Linphone-Konfigurationsdatei angeben. Sie wird mit der aktuellen Konfiguration zusammengeführt. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, Pfad oder Datei - + command_line_option_minimized Minimieren - + command_line_option_log_to_stdout Debug-Informationen auf der Standardausgabe ausgeben - + command_line_option_print_app_logs_only "Print only logs from the application" Nur Anwendungs-Logs ausgeben - + hide_action "Cacher" "Afficher" Ausblenden - + show_action Zeigen - + quit_action "Quitter" Beenden - + check_for_update Check for update Auf Updates prüfen - + mark_all_read_action Alle als gelesen markieren @@ -833,19 +833,19 @@ Passwort - + cancel "Annuler Abbrechen - + assistant_account_login Connexion Anmelden - + assistant_account_login_missing_password Veuillez saisir un mot de passe Bitte Passwort eingeben @@ -1026,7 +1026,7 @@ CallHistoryListView - + call_name_accessible_button Call %1 Anruf %1 @@ -1236,101 +1236,101 @@ Anrufprotokoll leer - + history_dialog_delete_all_call_logs_title Supprimer l'historique d'appels ? Anrufprotokoll löschen? - + history_dialog_delete_all_call_logs_message "L'ensemble de votre historique d'appels sera définitivement supprimé." Das gesamte Anrufprotokoll wird dauerhaft gelöscht. - + history_dialog_delete_call_logs_title Supprimer l'historique d'appels ? Anrufprotokoll löschen? - + history_dialog_delete_call_logs_message "L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé." Das Anrufprotokoll mit diesem Benutzer wird dauerhaft gelöscht. - + call_history_call_list_title "Appels" Anrufe - + call_history_options_accessible_name Anrufverlaufsoptionen - - + + menu_delete_history "Supprimer l'historique" Verlauf löschen - + call_history_list_options_accessible_name Call history options Anrufverlaufsoptionen - + create_new_call_accessible_name Create new call Neuen Anruf erstellen - + call_search_in_history "Rechercher un appel" Anruf suchen - + call_forward_to_address_info Anrufe weiterleiten an: - + call_forward_to_address_info_voicemail Anrufbeantworter - + list_filter_no_result_found "Aucun résultat…" Kein Ergebnis gefunden… - + history_list_empty_history "Aucun appel dans votre historique" Anrufprotokoll leer - + return_to_call_history_accessible_name Return to call history Zum Anrufverlauf zurückkehren - + call_action_start_new_call "Nouvel appel" Neuer Anruf - + call_start_group_call_title "Appel de groupe" Gruppenanruf @@ -1344,7 +1344,7 @@ - + call_action_start_group_call "Lancer" Starten @@ -1360,74 +1360,74 @@ Erforderlich - - - + + + information_popup_error_title Fehler - + group_call_error_must_have_name "Un nom doit être donné à l'appel de groupe Es muss ein Name für den Anruf angegeben werden - + group_call_error_not_connected "Vous n'etes pas connecté" Sie sind nicht verbunden - + menu_see_existing_contact "Show contact" Kontakt anzeigen - + menu_add_address_to_contacts "Add to contacts" Zu Kontakten hinzufügen - + menu_copy_sip_address "Copier l'adresse SIP" SIP-Adresse kopieren - + sip_address_copied_to_clipboard_toast Adresse copiée SIP-Adresse kopiert - + sip_address_copied_to_clipboard_message L'adresse a été copié dans le presse_papiers Die Adresse wurde in die Zwischenablage kopiert - + sip_address_copy_to_clipboard_error "Erreur lors de la copie de l'adresse" Fehler beim Kopieren der Adresse - + notification_missed_call_title "Appel manqué" Verpasster Anruf - + call_outgoing "Appel sortant" Ausgehender Anruf - + call_audio_incoming "Appel entrant" Eingehender Anruf @@ -2546,91 +2546,91 @@ Stellen Sie sicher, dass Sie keine sensiblen Informationen teilen! Keine Chats - + info_popup_error_title Fehler - + info_popup_chatroom_creation_failed Chat room creation failed ! Chat konnte nicht erstellt werden! - + loading_popup_chatroom_creation_pending_message Chat room is being created... Chat wird erstellt... - + chat_dialog_delete_chat_title Supprimer la conversation ? Chat löschen? - + chat_dialog_delete_chat_message "La conversation et tous ses messages seront supprimés." Dieser Chat und alle seine Nachrichten werden gelöscht. - + chat_list_title "Conversations" Chats - + menu_mark_all_as_read "mark all as read" Alle als gelesen markieren - + chat_search_in_history "Rechercher une conversation" Chat suchen - + list_filter_no_result_found "Aucun résultat…" Kein Ergebnis… - + chat_list_empty_history "Aucune conversation dans votre historique" Keine Chats in der Historie - + chat_action_start_new_chat "New chat" Neuer Chat - + chat_start_group_chat_title "Nouveau groupe" Neuer Gruppenchat - + chat_action_start_group_chat "Créer" Erstellen - - - + + + information_popup_error_title Fehler - + information_popup_chat_creation_failed_message "La création a échoué" Erstellen fehlgeschlagen @@ -2641,25 +2641,25 @@ Stellen Sie sicher, dass Sie keine sensiblen Informationen teilen! Der Codec konnte nicht installiert werden. - + group_chat_error_must_have_name "Un nom doit être donné au groupe Für den Gruppenchat muss ein Name festgelegt werden - + group_chat_error_no_participant "Please select at least one participant Bitte wählen Sie mindestens einen Teilnehmer aus - + group_call_error_not_connected "Vous n'etes pas connecté" Sie sind nicht verbunden - + chat_creation_in_progress Creation de la conversation en cours … Chat-Erstellung ausstehend… @@ -3573,12 +3573,12 @@ Stellen Sie sicher, dass Sie keine sensiblen Informationen teilen! CoreModel - + info_popup_error_title Fehler - + fetching_config_failed_error_message "Remote provisioning cannot be retrieved" Die externe Bereitstellung kann nicht abgerufen werden @@ -4370,144 +4370,144 @@ Ablauf: %1 MainLayout - + bottom_navigation_calls_label "Appels" Anrufe - + open_calls_page_accessible_name "Open calls page" Anrufe öffnen - + bottom_navigation_contacts_label "Contacts" Kontakte - + open_contacts_page_accessible_name "Open contacts page" Kontakte öffnen - + bottom_navigation_conversations_label "Conversations" Chats - + open_conversations_page_accessible_name "Open conversations page" Chats öffnen - + bottom_navigation_meetings_label "Réunions" Besprechungen - + open_contact_page_accessible_name "Open meetings page" Meetings öffnen - + searchbar_placeholder_text "Rechercher un contact, appeler %1" Kontakt suchen, %1 anrufen - + searchbar_placeholder_text_chat_feature_enabled "ou envoyer un message …" oder eine Nachricht senden … - + do_not_disturb_accessible_name "Do not disturb" Nicht stören - - + + contact_presence_status_disable_do_not_disturb "Désactiver ne pas déranger" Nicht stören deaktivieren - + information_popup_error_title Fehler - + no_voicemail_uri_error_message "L'URI de messagerie vocale n'est pas définie." Die Voicemail-URI ist nicht definiert. - + account_list_accessible_name "Account list" Kontoliste - + application_options_accessible_name "Application options" App-Einstellungen - + drawer_menu_manage_account Mon compte Mein Konto - + contact_presence_status_enable_do_not_disturb "Activer ne pas déranger" Nicht stören aktivieren - + settings_title Einstellungen - + recordings_title "Enregistrements" Aufnahmen - + help_title "Aide" Hilfe - + help_quit_title "Quitter l'application" App beenden - + quit_app_question "Quitter %1 ?" %1 beenden? - + drawer_menu_add_account "Ajouter un compte" Konto hinzufügen @@ -4546,42 +4546,54 @@ Ablauf: %1 Ihr Gesprächspartner wurde an den ausgewählten Kontakt weitergeleitet - + information_popup_success_title Gespeichert - + information_popup_changes_saved "Les changements ont été sauvegardés" Änderungen wurden gespeichert - + + oidc_connection_waiting_message + "Trying to connect to single sign on on web page ..." + + + + + cancel + Cancel + Abbrechen + + + captcha_validation_loading_message "Veuillez valider le captcha sur la page web" Bitte das Captcha auf der Webseite bestätigen - + assistant_register_error_title "Erreur lors de la création" Fehler bei der Erstellung - + assistant_register_success_title "Compte créé" Konto erstellt - + assistant_register_success_message "Le compte a été créé. Vous pouvez maintenant vous connecter" Das Konto wurde erstellt. Sie können sich jetzt anmelden. - + assistant_register_error_code "Erreur dans le code de validation" Fehler im Bestätigungscode @@ -5093,108 +5105,109 @@ Ablauf: %1 OAuthHttpServerReplyHandler ist nicht aktiv - + + oidc_authentication_timeout_message Timeout: Not authenticated Zeitüberschreitung: Nicht authentifiziert - + oidc_authentication_granted_message Authentication granted Authentifizierung erfolgreich - + oidc_authentication_not_authenticated_message Not authenticated Nicht authentifiziert - + oidc_authentication_refresh_message Refreshing token Token wird aktualisiert - + oidc_authentication_temporary_credentials_message Temporary credentials received Temporäre Anmeldedaten erhalten - + oidc_authentication_network_error Network error Netzwerkfehler - + oidc_authentication_server_error Server error Serverfehler - + oidc_authentication_token_not_found_error OAuth token not found OAuth-Token nicht gefunden - + oidc_authentication_token_secret_not_found_error OAuth token secret not found OAuth-Token-Geheimnis nicht gefunden - + oidc_authentication_callback_not_verified_error OAuth callback not verified OAuth-Callback nicht verifiziert - + oidc_authentication_request_auth_message Requesting authorization from browser Autorisierung über den Browser anfordern - + oidc_authentication_no_token_found_error Kein Token gefunden - + oidc_authentication_request_token_message Requesting access token Zugriffstoken wird angefordert - + oidc_authentication_refresh_token_message Refreshing access token Zugriffstoken wird aktualisiert - + oidc_authentication_request_authorization_message Requesting authorization Autorisierung wird angefordert - + oidc_authentication_request_temporary_credentials_message Requesting temporary credentials Temporäre Anmeldedaten werden angefordert - + oidc_authentication_no_auth_found_in_config_error No authorization endpoint found in OpenID configuration Kein Autorisierungs-Endpunkt in der OpenID-Konfiguration gefunden - + oidc_authentication_no_token_found_in_config_error No token endpoint found in OpenID configuration Kein Token-Endpunkt in der OpenID-Konfiguration gefunden @@ -6321,32 +6334,32 @@ Um sie in einem kommerziellen Projekt zu aktivieren, kontaktieren Sie uns bitte. WaitingRoom - + meeting_waiting_room_title Participer à : Beitreten : - + meeting_waiting_room_join "Rejoindre" Beitreten - - + + cancel Cancel Abbrechen - + meeting_waiting_room_joining_title "Connexion à la réunion" Verbindung zur Besprechung - + meeting_waiting_room_joining_subtitle "Vous allez rejoindre la réunion dans quelques instants…" Sie werden der Besprechung in wenigen Momenten beitreten... diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index ae74ac5b9..790fe548c 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -95,7 +95,7 @@ AccountListView - + add_an_account Add an account Add an account @@ -655,141 +655,141 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Do you want to download and apply remote provisioning from this address ? - - - + + + info_popup_error_title Error Error - - + + info_popup_configuration_failed_message Remote provisioning failed : %1 Remote provisioning failed : %1 - + info_popup_error_checking_update An error occured while trying to check update. Please try again later or contact support team. An error occured while trying to check update. Please try again later or contact support team. - + info_popup_new_version_download_label Download it ! - + info_popup_new_version_available_title New version available ! New version available ! - + info_popup_new_version_available_message A new version of Linphone (%1) is available. %2 A new version of Linphone (%1) is available at %1 - + info_popup_version_up_to_date_title Up to date - + info_popup_version_up_to_date_message Your version is up to date Up to date Your version is up to date - + configuration_error_detail not reachable not reachable - + application_description "A free and open source SIP video-phone." A free and open source SIP video-phone. - + command_line_arg_order "Send an order to the application towards a command line" Send an order to the application towards a command line - + command_line_option_show_help Show this help - + command_line_option_show_app_version Show app version - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Specify the linphone configuration file to be fetched. It will be merged with the current configuration. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, path or file - + command_line_option_minimized Minimize - + command_line_option_log_to_stdout Log to stdout some debug information while running - + command_line_option_print_app_logs_only "Print only logs from the application" Print only logs from the application - + hide_action "Cacher" "Afficher" Hide - + show_action Show - + quit_action "Quitter" Quit - + check_for_update Check for update Check for update - + mark_all_read_action Marquer tout comme lu @@ -814,19 +814,19 @@ Password - + cancel "Annuler Cancel - + assistant_account_login Connexion Connection - + assistant_account_login_missing_password Veuillez saisir un mot de passe Please enter a password @@ -1007,7 +1007,7 @@ CallHistoryListView - + call_name_accessible_button Call %1 Call %1 @@ -1205,12 +1205,12 @@ CallPage - + call_forward_to_address_info Forward calls to: - + call_forward_to_address_info_voicemail Voicemail @@ -1227,170 +1227,170 @@ Empty call history - + history_dialog_delete_all_call_logs_title Supprimer l'historique d'appels ? Delete call history ? - + history_dialog_delete_all_call_logs_message "L'ensemble de votre historique d'appels sera définitivement supprimé." Call history will be permanently deleted. - + history_dialog_delete_call_logs_title Supprimer l'historique d'appels ? Delete call history ? - + history_dialog_delete_call_logs_message "L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé." Call history with this user will be permanently deleted. - + call_history_call_list_title "Appels" Calls - + call_history_options_accessible_name Call history options - - + + menu_delete_history "Supprimer l'historique" Delete history - + call_history_list_options_accessible_name Call history options Call history options - + create_new_call_accessible_name Create new call Create new call - + call_search_in_history "Rechercher un appel" Find call - + list_filter_no_result_found "Aucun résultat…" No result found… - + history_list_empty_history "Aucun appel dans votre historique" No call in history - + return_to_call_history_accessible_name Return to call history Return to call history - + call_action_start_new_call "Nouvel appel" New call - + call_start_group_call_title "Appel de groupe" Group call - + call_action_start_group_call "Lancer" Start - - - + + + information_popup_error_title Error - + group_call_error_must_have_name "Un nom doit être donné à l'appel de groupe A name must be provided for the call - + group_call_error_not_connected "Vous n'etes pas connecté" You are not connected - + menu_see_existing_contact "Show contact" Show contact - + menu_add_address_to_contacts "Add to contacts" Add to contacts - + menu_copy_sip_address "Copier l'adresse SIP" Copy SIP address - + sip_address_copied_to_clipboard_toast Adresse copiée SIP address copied - + sip_address_copied_to_clipboard_message L'adresse a été copié dans le presse_papiers The address has been copied to the clipboard - + sip_address_copy_to_clipboard_error "Erreur lors de la copie de l'adresse" Error copying address - + notification_missed_call_title "Appel manqué" Missed call - + call_outgoing "Appel sortant" Outgoing call - + call_audio_incoming "Appel entrant" Incoming call @@ -2504,115 +2504,115 @@ Only your correspondent can decrypt them. No conversation - + info_popup_error_title Error - + info_popup_chatroom_creation_failed Chat room creation failed ! Chat room creation failed ! - + loading_popup_chatroom_creation_pending_message Chat room is being created... Chat room is being created... - + chat_dialog_delete_chat_title Supprimer la conversation ? Delete conversation ? - + chat_dialog_delete_chat_message "La conversation et tous ses messages seront supprimés." This conversation and all its messages will be deleted. - + chat_list_title "Conversations" Conversations - + menu_mark_all_as_read "mark all as read" Mark all as read - + chat_search_in_history "Rechercher une conversation" Search for a chat - + list_filter_no_result_found "Aucun résultat…" No result… - + chat_list_empty_history "Aucune conversation dans votre historique" No conversation in history - + chat_action_start_new_chat "New chat" New conversation - + chat_start_group_chat_title "Nouveau groupe" New group - + chat_action_start_group_chat "Créer" Create - - - + + + information_popup_error_title Error - + information_popup_chat_creation_failed_message "La création a échoué" Creation failed - + group_chat_error_must_have_name "Un nom doit être donné au groupe A name must be set for the group - + group_chat_error_no_participant "Please select at least one participant Please select at least one participant - + group_call_error_not_connected "Vous n'etes pas connecté" You are not connected - + chat_creation_in_progress Creation de la conversation en cours … Chat creation pending… @@ -3476,12 +3476,12 @@ Only your correspondent can decrypt them. CoreModel - + info_popup_error_title Error - + fetching_config_failed_error_message "Remote provisioning cannot be retrieved" Remote provisioning cannot be retrieved @@ -4268,144 +4268,144 @@ Expiration : %1 MainLayout - + bottom_navigation_calls_label "Appels" Calls - + open_calls_page_accessible_name "Open calls page" Open calls pages - + bottom_navigation_contacts_label "Contacts" Contacts - + open_contacts_page_accessible_name "Open contacts page" Open contacts page - + bottom_navigation_conversations_label "Conversations" Conversations - + open_conversations_page_accessible_name "Open conversations page" Open conversations page - + bottom_navigation_meetings_label "Réunions" Meetings - + open_contact_page_accessible_name "Open meetings page" Open meetings page - + searchbar_placeholder_text "Rechercher un contact, appeler %1" Find contact, call %1 - + searchbar_placeholder_text_chat_feature_enabled "ou envoyer un message …" or send message … - + do_not_disturb_accessible_name "Do not disturb" Do not disturb - - + + contact_presence_status_disable_do_not_disturb "Désactiver ne pas déranger" Disable do not disturb - + information_popup_error_title Error - + no_voicemail_uri_error_message "L'URI de messagerie vocale n'est pas définie." The voicemail URI is not defined. - + account_list_accessible_name "Account list" account list - + application_options_accessible_name "Application options" Application options - + drawer_menu_manage_account Mon compte My account - + contact_presence_status_enable_do_not_disturb "Activer ne pas déranger" Enable do not disturb - + settings_title Settings - + recordings_title "Enregistrements" Records - + help_title "Aide" Help - + help_quit_title "Quitter l'application" Quit the app - + quit_app_question "Quitter %1 ?" Quit %1 ? - + drawer_menu_add_account "Ajouter un compte" Add an account @@ -4444,42 +4444,54 @@ Expiration : %1 Your correspondent has been transferred to the selected contact - + information_popup_success_title Saved - + information_popup_changes_saved "Les changements ont été sauvegardés" Changes have been saved - + + oidc_connection_waiting_message + "Trying to connect to single sign on on web page ..." + + + + + cancel + Cancel + Cancel + + + captcha_validation_loading_message "Veuillez valider le captcha sur la page web" Please validate the captcha on the web page - + assistant_register_error_title "Erreur lors de la création" Error while creating - + assistant_register_success_title "Compte créé" Account created - + assistant_register_success_message "Le compte a été créé. Vous pouvez maintenant vous connecter" The account has been created. You can now log in. - + assistant_register_error_code "Erreur dans le code de validation" Error in validation code @@ -4982,108 +4994,109 @@ Expiration : %1 OAuthHttpServerReplyHandler is not listening - + + oidc_authentication_timeout_message Timeout: Not authenticated Timeout: Not authenticated - + oidc_authentication_granted_message Authentication granted Authentication granted - + oidc_authentication_not_authenticated_message Not authenticated Not authenticated - + oidc_authentication_refresh_message Refreshing token Refreshing token - + oidc_authentication_temporary_credentials_message Temporary credentials received Temporary credentials received - + oidc_authentication_network_error Network error Network error - + oidc_authentication_server_error Server error Server error - + oidc_authentication_token_not_found_error OAuth token not found OAuth token not found - + oidc_authentication_token_secret_not_found_error OAuth token secret not found OAuth token secret not found - + oidc_authentication_callback_not_verified_error OAuth callback not verified OAuth callback not verified - + oidc_authentication_request_auth_message Requesting authorization from browser Requesting authorization from browser - + oidc_authentication_no_token_found_error No token found - + oidc_authentication_request_token_message Requesting access token Requesting access token - + oidc_authentication_refresh_token_message Refreshing access token Refreshing access token - + oidc_authentication_request_authorization_message Requesting authorization Requesting authorization - + oidc_authentication_request_temporary_credentials_message Requesting temporary credentials Requesting temporary credentials - + oidc_authentication_no_auth_found_in_config_error No authorization endpoint found in OpenID configuration No authorization endpoint found in OpenID configuration - + oidc_authentication_no_token_found_in_config_error No token endpoint found in OpenID configuration No token endpoint found in OpenID configuration @@ -6186,32 +6199,32 @@ To enable them in a commercial project, please contact us. WaitingRoom - + meeting_waiting_room_title Participer à : Join : - + meeting_waiting_room_join "Rejoindre" Join - - + + cancel Cancel Cancel - + meeting_waiting_room_joining_title "Connexion à la réunion" Connection to meeting - + meeting_waiting_room_joining_subtitle "Vous allez rejoindre la réunion dans quelques instants…" You will be joining the meeting in a few moments... diff --git a/Linphone/data/languages/fr.ts b/Linphone/data/languages/fr.ts index fdf129ae9..0c39b3b9c 100644 --- a/Linphone/data/languages/fr.ts +++ b/Linphone/data/languages/fr.ts @@ -95,7 +95,7 @@ AccountListView - + add_an_account Add an account Ajouter un compte @@ -650,141 +650,141 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? - - - + + + info_popup_error_title Error Erreur - - + + info_popup_configuration_failed_message Remote provisioning failed : %1 La configuration distante a échoué : %1 - + info_popup_error_checking_update An error occured while trying to check update. Please try again later or contact support team. Une erreur est survenue lors de la recherche de mise à jour. Merci de réessayer plus tard ou de contacter l'équipe de support. - + info_popup_new_version_download_label Téléchargez-là ! - + info_popup_new_version_available_title New version available ! Nouvelle version disponible ! - + info_popup_new_version_available_message A new version of Linphone (%1) is available. %2 Une nouvelle version de Linphone (%1) est disponible. %2 - + info_popup_version_up_to_date_title À jour - + info_popup_version_up_to_date_message Your version is up to date Votre version est à jour - + configuration_error_detail not reachable indisponible - + application_description "A free and open source SIP video-phone." A free and open source SIP video-phone. - + command_line_arg_order "Send an order to the application towards a command line" Send an order to the application towards a command line - + command_line_option_show_help Show this help - + command_line_option_show_app_version Afficher la version de l'application - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Specify the linphone configuration file to be fetched. It will be merged with the current configuration. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, path or file - + command_line_option_minimized Minimiser - + command_line_option_log_to_stdout Log to stdout some debug information while running - + command_line_option_print_app_logs_only "Print only logs from the application" Print only logs from the application - + hide_action "Cacher" "Afficher" Cacher - + show_action Afficher - + quit_action "Quitter" Quitter - + check_for_update Check for update Rechercher une mise à jour - + mark_all_read_action Marquer tout comme lu @@ -809,19 +809,19 @@ Mot de passe - + cancel "Annuler Annuler - + assistant_account_login Connexion Connexion - + assistant_account_login_missing_password Veuillez saisir un mot de passe Veuillez saisir un mot de passe @@ -982,7 +982,7 @@ CallHistoryListView - + call_name_accessible_button Call %1 Appeler %1 @@ -1192,180 +1192,180 @@ Historique d'appel vide - + history_dialog_delete_all_call_logs_title Supprimer l'historique d'appels ? Supprimer l'historique d'appels ? - + history_dialog_delete_all_call_logs_message "L'ensemble de votre historique d'appels sera définitivement supprimé." L'ensemble de votre historique d'appels sera définitivement supprimé. - + history_dialog_delete_call_logs_title Supprimer l'historique d'appels ? Supprimer l'historique d'appels ? - + history_dialog_delete_call_logs_message "L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé." L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé. - + call_history_call_list_title "Appels" Appels - + call_history_options_accessible_name Options de l' - - + + menu_delete_history "Supprimer l'historique" Supprimer l'historique - + call_history_list_options_accessible_name Call history options Options de la liste de l'historique d'appel - + create_new_call_accessible_name Create new call Créer un nouvel appel - + call_search_in_history "Rechercher un appel" Rechercher un appel - + call_forward_to_address_info Transférer l'appel à : - + call_forward_to_address_info_voicemail Boîte vocale - + list_filter_no_result_found "Aucun résultat…" Aucun résultat… - + history_list_empty_history "Aucun appel dans votre historique" Aucun appel dans votre historique - + return_to_call_history_accessible_name Return to call history Retourner à l'historique d'appels - + call_action_start_new_call "Nouvel appel" Nouvel appel - + call_start_group_call_title "Appel de groupe" Appel de groupe - + call_action_start_group_call "Lancer" Lancer - - - + + + information_popup_error_title Erreur - + group_call_error_must_have_name "Un nom doit être donné à l'appel de groupe Un nom doit être donné à l'appel de groupe - + group_call_error_not_connected "Vous n'etes pas connecté" Vous n'etes pas connecté - + menu_see_existing_contact "Show contact" Voir le contact - + menu_add_address_to_contacts "Add to contacts" Ajouter aux contacts - + menu_copy_sip_address "Copier l'adresse SIP" Copier l'adresse SIP - + sip_address_copied_to_clipboard_toast Adresse copiée Adresse copiée - + sip_address_copied_to_clipboard_message L'adresse a été copié dans le presse_papiers L'adresse a été copié dans le presse-papiers - + sip_address_copy_to_clipboard_error "Erreur lors de la copie de l'adresse" Erreur lors de la copie de l'adresse - + notification_missed_call_title "Appel manqué" Appel manqué - + call_outgoing "Appel sortant" Appel sortant - + call_audio_incoming "Appel entrant" Appel entrant @@ -2479,115 +2479,115 @@ en bout. Seul votre correspondant peut les déchiffrer. Aucune conversation - + info_popup_error_title Erreur - + info_popup_chatroom_creation_failed Chat room creation failed ! La création de la conversation a échoué ! - + loading_popup_chatroom_creation_pending_message Chat room is being created... Création de la conversation en cours... - + chat_dialog_delete_chat_title Supprimer la conversation ? Supprimer la conversation ? - + chat_dialog_delete_chat_message "La conversation et tous ses messages seront supprimés." La conversation et tous ses messages seront supprimés. - + chat_list_title "Conversations" Conversations - + menu_mark_all_as_read "mark all as read" Tout marquer comme lu - + chat_search_in_history "Rechercher une conversation" Rechercher une conversation - + list_filter_no_result_found "Aucun résultat…" Aucun résultat… - + chat_list_empty_history "Aucune conversation dans votre historique" Aucune conversation dans votre historique - + chat_action_start_new_chat "New chat" Nouvelle conversation - + chat_start_group_chat_title "Nouveau groupe" Nouveau groupe - + chat_action_start_group_chat "Créer" Créer - - - + + + information_popup_error_title Erreur - + information_popup_chat_creation_failed_message "La création a échoué" La création a échoué - + group_chat_error_must_have_name "Un nom doit être donné au groupe Un nom doit être donné au groupe - + group_chat_error_no_participant "Please select at least one participant Veuillez sélectionner au moins un participant - + group_call_error_not_connected "Vous n'etes pas connecté" Vous n'êtes pas connecté - + chat_creation_in_progress Creation de la conversation en cours … Création de la conversation en cours… @@ -3451,12 +3451,12 @@ en bout. Seul votre correspondant peut les déchiffrer. CoreModel - + info_popup_error_title Erreur - + fetching_config_failed_error_message "Remote provisioning cannot be retrieved" La configuration distante n'a pas pu être récupérée @@ -4243,144 +4243,144 @@ Expiration : %1 MainLayout - + bottom_navigation_calls_label "Appels" Appels - + open_calls_page_accessible_name "Open calls page" Ouvrir la page des appels - + bottom_navigation_contacts_label "Contacts" Contacts - + open_contacts_page_accessible_name "Open contacts page" Ouvrir la page des contacts - + bottom_navigation_conversations_label "Conversations" Conversations - + open_conversations_page_accessible_name "Open conversations page" Ouvrir la page des conversations - + bottom_navigation_meetings_label "Réunions" Réunions - + open_contact_page_accessible_name "Open meetings page" Ouvrir la page des réunions - + searchbar_placeholder_text "Rechercher un contact, appeler %1" Rechercher un contact, appeler %1 - + searchbar_placeholder_text_chat_feature_enabled "ou envoyer un message …" ou envoyer un message … - + do_not_disturb_accessible_name "Do not disturb" Ne pas déranger - - + + contact_presence_status_disable_do_not_disturb "Désactiver ne pas déranger" Désactiver ne pas déranger - + information_popup_error_title Erreur - + no_voicemail_uri_error_message "L'URI de messagerie vocale n'est pas définie." L'URI de messagerie vocale n'est pas définie. - + account_list_accessible_name "Account list" liste des comptes - + application_options_accessible_name "Application options" Options de l'application - + drawer_menu_manage_account Mon compte Mon compte - + contact_presence_status_enable_do_not_disturb "Activer ne pas déranger" Activer ne pas déranger - + settings_title Paramètres - + recordings_title "Enregistrements" Enregistrements - + help_title "Aide" Aide - + help_quit_title "Quitter l'application" Quitter l'application - + quit_app_question "Quitter %1 ?" Quitter %1 ? - + drawer_menu_add_account "Ajouter un compte" Ajouter un compte @@ -4419,42 +4419,54 @@ Expiration : %1 Votre correspondant a été transféré au contact sélectionné - + information_popup_success_title Enregistré - + information_popup_changes_saved "Les changements ont été sauvegardés" Les changements ont été sauvegardés - + + oidc_connection_waiting_message + "Trying to connect to single sign on on web page ..." + Tentative de connexion distante ... + + + + cancel + Cancel + Annuler + + + captcha_validation_loading_message "Veuillez valider le captcha sur la page web" Veuillez valider le captcha sur la page web - + assistant_register_error_title "Erreur lors de la création" Erreur lors de la création - + assistant_register_success_title "Compte créé" Compte créé - + assistant_register_success_message "Le compte a été créé. Vous pouvez maintenant vous connecter" Le compte a été créé. Vous pouvez maintenant vous connecter - + assistant_register_error_code "Erreur dans le code de validation" Erreur dans le code de validation @@ -4953,108 +4965,109 @@ Expiration : %1 OAuthHttpServerReplyHandler n'est pas disponible - + + oidc_authentication_timeout_message Timeout: Not authenticated Timeout : non authentifié - + oidc_authentication_granted_message Authentication granted Authentification accordée - + oidc_authentication_not_authenticated_message Not authenticated Non authentifié - + oidc_authentication_refresh_message Refreshing token Token en cours de rafraîchissement - + oidc_authentication_temporary_credentials_message Temporary credentials received Identifiants temporaires reçus - + oidc_authentication_network_error Network error Erreur réseau - + oidc_authentication_server_error Server error Erreur de serveur - + oidc_authentication_token_not_found_error OAuth token not found Token OAuth non trouvé - + oidc_authentication_token_secret_not_found_error OAuth token secret not found Token OAuth secret non trouvé - + oidc_authentication_callback_not_verified_error OAuth callback not verified Retour OAuth non vérifié - + oidc_authentication_request_auth_message Requesting authorization from browser En attente d'autorisation du navigateur - + oidc_authentication_no_token_found_error Token non trouvé - + oidc_authentication_request_token_message Requesting access token En attente du token d'accès - + oidc_authentication_refresh_token_message Refreshing access token Token en cours de rafraîchissement - + oidc_authentication_request_authorization_message Requesting authorization Autorisation en cours - + oidc_authentication_request_temporary_credentials_message Requesting temporary credentials En attente d'identifiants temporaires - + oidc_authentication_no_auth_found_in_config_error No authorization endpoint found in OpenID configuration Pas d'autorisation trouvé dans la configuration OpenID - + oidc_authentication_no_token_found_in_config_error No token endpoint found in OpenID configuration Pas de token trouvé dans la configuration OpenID @@ -6157,32 +6170,32 @@ Pour les activer dans un projet commercial, merci de nous contacter. WaitingRoom - + meeting_waiting_room_title Participer à : Participer à : - + meeting_waiting_room_join "Rejoindre" Rejoindre - - + + cancel Cancel Annuler - + meeting_waiting_room_joining_title "Connexion à la réunion" Connexion à la réunion - + meeting_waiting_room_joining_subtitle "Vous allez rejoindre la réunion dans quelques instants…" Vous allez rejoindre la réunion dans quelques instants… diff --git a/Linphone/model/auth/OIDCModel.cpp b/Linphone/model/auth/OIDCModel.cpp index 4f3b04cd9..79e8fc561 100644 --- a/Linphone/model/auth/OIDCModel.cpp +++ b/Linphone/model/auth/OIDCModel.cpp @@ -102,6 +102,7 @@ OIDCModel::OIDCModel(const std::shared_ptr &authInfo, QObjec lWarning() << log().arg("Timeout reached for OpenID connection."); dynamic_cast(mOidc.replyHandler())->close(); CoreModel::getInstance()->getCore()->abortAuthentication(mAuthInfo); + emit timeoutTimerStopped(); //: Timeout: Not authenticated emit statusChanged(tr("oidc_authentication_timeout_message")); emit finished(); @@ -120,14 +121,14 @@ OIDCModel::OIDCModel(const std::shared_ptr &authInfo, QObjec connect(&mOidc, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](QAbstractOAuth::Status status) { switch (status) { case QAbstractOAuth::Status::Granted: { - mTimeout.stop(); + stopTimeoutTimer(); //: Authentication granted emit statusChanged(tr("oidc_authentication_granted_message")); emit authenticated(); break; } case QAbstractOAuth::Status::NotAuthenticated: { - mTimeout.stop(); + stopTimeoutTimer(); //: Not authenticated emit statusChanged(tr("oidc_authentication_not_authenticated_message")); emit finished(); @@ -149,7 +150,7 @@ OIDCModel::OIDCModel(const std::shared_ptr &authInfo, QObjec }); connect(&mOidc, &QOAuth2AuthorizationCodeFlow::requestFailed, [=](QAbstractOAuth::Error error) { - mTimeout.stop(); + stopTimeoutTimer(); const QMetaObject metaObject = QAbstractOAuth::staticMetaObject; int index = metaObject.indexOfEnumerator("Error"); @@ -183,10 +184,12 @@ OIDCModel::OIDCModel(const std::shared_ptr &authInfo, QObjec }); connect(&mOidc, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, [this](const QUrl &url) { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); qDebug() << "Browser authentication url : " << url; //: Requesting authorization from browser emit statusChanged(tr("oidc_authentication_request_auth_message")); mTimeout.start(); + emit timeoutTimerStarted(); QDesktopServices::openUrl(url); }); @@ -261,6 +264,29 @@ OIDCModel::OIDCModel(const std::shared_ptr &authInfo, QObjec connect(reply, &QNetworkReply::finished, this, &OIDCModel::openIdConfigReceived); } +void OIDCModel::forceTimeout() { + lWarning() << log().arg("Froce timeout for OpenID connection."); + stopTimeoutTimer(); + dynamic_cast(mOidc.replyHandler())->close(); + CoreModel::getInstance()->getCore()->abortAuthentication(mAuthInfo); + //: Timeout: Not authenticated + emit statusChanged(tr("oidc_authentication_timeout_message")); + emit finished(); +} + +bool OIDCModel::isTimerRunning() const { + return mTimeout.isActive(); +} + +int OIDCModel::getRemainingTimeBeforeTimeOut() { + return mTimeout.remainingTime(); +} + +void OIDCModel::stopTimeoutTimer() { + mTimeout.stop(); + emit timeoutTimerStopped(); +} + void OIDCModel::openIdConfigReceived() { auto reply = dynamic_cast(sender()); auto document = QJsonDocument::fromJson(reply->readAll()); diff --git a/Linphone/model/auth/OIDCModel.hpp b/Linphone/model/auth/OIDCModel.hpp index 84dcb9ee9..108f61128 100644 --- a/Linphone/model/auth/OIDCModel.hpp +++ b/Linphone/model/auth/OIDCModel.hpp @@ -36,12 +36,18 @@ public: void openIdConfigReceived(); void setBearers(); + void forceTimeout(); + bool isTimerRunning() const; + int getRemainingTimeBeforeTimeOut(); + void stopTimeoutTimer(); signals: void authenticated(); void requestFailed(const QString &error); void statusChanged(const QString &status); void finished(); + void timeoutTimerStarted(); + void timeoutTimerStopped(); private: /** diff --git a/Linphone/model/core/CoreModel.cpp b/Linphone/model/core/CoreModel.cpp index ae2ff00f3..e1b8f2899 100644 --- a/Linphone/model/core/CoreModel.cpp +++ b/Linphone/model/core/CoreModel.cpp @@ -145,6 +145,14 @@ void CoreModel::setConfigPath(QString path) { } } +void CoreModel::refreshOidcRemainingTime() { + for (auto oidc : mOpenIdConnections) { + if (oidc && oidc->isTimerRunning()) { + emit oidcRemainingTimeBeforeTimeoutChanged(oidc->getRemainingTimeBeforeTimeOut()); + } + } +} + //------------------------------------------------------------------------------- // PATHS //------------------------------------------------------------------------------- @@ -402,7 +410,19 @@ void CoreModel::onAuthenticationRequested(const std::shared_ptr << realm << " at " << serverUrl; QString key = username + '@' + realm + ' ' + serverUrl; if (mOpenIdConnections.contains(key)) mOpenIdConnections[key]->deleteLater(); - mOpenIdConnections[key] = new OIDCModel(authInfo, this); + auto oidcModel = new OIDCModel(authInfo, this); + mOpenIdConnections[key] = oidcModel; + connect(oidcModel, &OIDCModel::timeoutTimerStarted, this, [this] { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + emit timeoutTimerStarted(); + qDebug() << "start refresh timer"; + }); + connect(oidcModel, &OIDCModel::timeoutTimerStopped, this, [this] { emit timeoutTimerStopped(); }); + connect(this, &CoreModel::forceOidcTimeout, oidcModel, [this, oidcModel] { + if (oidcModel->isTimerRunning()) { + oidcModel->forceTimeout(); + } + }); } } emit authenticationRequested(core, authInfo, method); diff --git a/Linphone/model/core/CoreModel.hpp b/Linphone/model/core/CoreModel.hpp index 94caad489..139446df8 100644 --- a/Linphone/model/core/CoreModel.hpp +++ b/Linphone/model/core/CoreModel.hpp @@ -61,6 +61,8 @@ public: void start(); void setConfigPath(QString path); + void refreshOidcRemainingTime(); + QString getFetchConfig(QString filePath, bool *error); void useFetchConfig(QString filePath); bool setFetchConfig(QString filePath); @@ -93,6 +95,10 @@ signals: void enabledLdapAddressBookSaved(); void magicSearchResultReceived(QString filter); void messageReadInChatRoom(std::shared_ptr chatRoom); + void oidcRemainingTimeBeforeTimeoutChanged(int remainingTime); + void forceOidcTimeout(); + void timeoutTimerStarted(); + void timeoutTimerStopped(); private: QString mConfigPath; diff --git a/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml b/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml index cd2cf2696..74484fd24 100644 --- a/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml +++ b/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml @@ -72,6 +72,7 @@ Dialog { contentItem: TextField { id: passwordEdit hidden: true + width: parent.width isError: passwordItem.errorTextVisible KeyNavigation.down: cancelButton } diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index 9d3cd9c5d..a80e77a7d 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -87,7 +87,6 @@ Item { AccountProxy { id: accountProxy - sourceModel: AppCpp.accounts onDefaultAccountChanged: if (tabbar.currentIndex === 0 && defaultAccount) defaultAccount.core?.lResetMissedCalls() } diff --git a/Linphone/view/Page/Main/Account/AccountListView.qml b/Linphone/view/Page/Main/Account/AccountListView.qml index 98d80954b..7affd9a22 100644 --- a/Linphone/view/Page/Main/Account/AccountListView.qml +++ b/Linphone/view/Page/Main/Account/AccountListView.qml @@ -67,7 +67,6 @@ ColumnLayout{ Repeater{ model: AccountProxy { id: accountProxy - sourceModel: AppCpp.accounts } delegate: contactDelegate } diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 33b5a63ed..58786d3a1 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -28,7 +28,6 @@ AbstractMainPage { property ConferenceInfoGui confInfoGui property AccountProxy accounts: AccountProxy { id: accountProxy - sourceModel: AppCpp.accounts } property AccountGui account: accountProxy.defaultAccount property var state: account && account.core?.registrationState || 0 diff --git a/Linphone/view/Page/Main/Call/WaitingRoom.qml b/Linphone/view/Page/Main/Call/WaitingRoom.qml index 97911d01e..c6f0f5b1c 100644 --- a/Linphone/view/Page/Main/Call/WaitingRoom.qml +++ b/Linphone/view/Page/Main/Call/WaitingRoom.qml @@ -35,7 +35,6 @@ RowLayout { mutedStatus: microButton.checked AccountProxy { id: accounts - sourceModel: AppCpp.accounts } account: accounts.defaultAccount } diff --git a/Linphone/view/Page/Main/Chat/ChatPage.qml b/Linphone/view/Page/Main/Chat/ChatPage.qml index 58ba9f692..17b8f3f50 100644 --- a/Linphone/view/Page/Main/Chat/ChatPage.qml +++ b/Linphone/view/Page/Main/Chat/ChatPage.qml @@ -18,7 +18,6 @@ AbstractMainPage { property AccountProxy accounts: AccountProxy { id: accountProxy - sourceModel: AppCpp.accounts } property AccountGui account: accountProxy.defaultAccount property var state: account && account.core?.registrationState || 0 diff --git a/Linphone/view/Page/Window/Main/MainWindow.qml b/Linphone/view/Page/Window/Main/MainWindow.qml index e35ded455..964b68add 100644 --- a/Linphone/view/Page/Window/Main/MainWindow.qml +++ b/Linphone/view/Page/Window/Main/MainWindow.qml @@ -91,6 +91,10 @@ AbstractWindow { mainWindowStackView.replace(loginPage) } + function openSSOPage() { + mainWindowStackView.replace(ssoPage) + } + function scheduleMeeting(subject, addresses) { openMainPage() mainWindowStackView.currentItem.scheduleMeeting(subject, addresses) @@ -145,7 +149,6 @@ AbstractWindow { id: accountProxyLoader active: AppCpp.coreStarted sourceComponent: AccountProxy { - sourceModel: AppCpp.accounts onInitializedChanged: if (isInitialized) { mainWindow.accountProxy = this mainWindow.initStackViewItem() @@ -181,6 +184,45 @@ AbstractWindow { } } } + Component { + id: ssoPage + Rectangle { + color: DefaultStyle.grey_0 + Image { + id: logoImage + anchors.centerIn: parent + source: AppIcons.splashscreenLogo + sourceSize.width: Utils.getSizeWithScreenRatio(395) + sourceSize.height: Utils.getSizeWithScreenRatio(395) + width: Utils.getSizeWithScreenRatio(395) + height: Utils.getSizeWithScreenRatio(395) + } + ColumnLayout { + anchors.top: logoImage.bottom + anchors.topMargin: Utils.getSizeWithScreenRatio(24) + anchors.horizontalCenter: parent.horizontalCenter + Text { + Layout.alignment: Qt.AlignHCenter + //: "Trying to connect to single sign on on web page ..." + text: qsTr("oidc_connection_waiting_message") + font: Typography.h2 + horizontalAlignment: Text.AlignHCenter + } + Text { + Layout.alignment: Qt.AlignHCenter + text: UtilsCpp.formatDuration(AppCpp.remainingTimeBeforeOidcTimeout) + font: Typography.h3m + horizontalAlignment: Text.AlignHCenter + } + Button { + Layout.alignment: Qt.AlignHCenter + //: Cancel + text: qsTr("cancel") + onClicked: AppCpp.lForceOidcTimeout() + } + } + } + } Component { id: loginPage LoginPage {