From 452c631d6e1609eeeceb84b74a903c769daa0118 Mon Sep 17 00:00:00 2001 From: Serhii Hadzhilov <71632867+SerhiiGadzhilov@users.noreply.github.com> Date: Tue, 13 Sep 2022 18:31:45 +0300 Subject: [PATCH] Release v1.14.5 (#7219) * Update Version.cmake * Add TLS to Synergy (Lite edition) (#7202) * Add TLS to synergy light * Requested changes * License registration for Business edition (#7203) * License registration for business * Rename register to registry * Add email into the request * Add decoded serial key into the request * Revert "Add decoded serial key into the request" This reverts commit 0e18c8941664e86ae2264bbef072df68cab07751. * Revert "Add email into the request" This reverts commit 8dff01bc242769008897947d66187cb726fb34bf. * Change field guid_generated to guid_type * Update ChangeLog * Update ChangeLog * Fix build issue for ubuntu16 and ubuntu18 (#7204) * Fix issue with settings * Custom about screen for Elite Backers (#7211) * Hide irrelevant information from the About screen for B2B * Fix size for Windows and Linux * Requested changes * Fix Enterprise * Revert "Fix Enterprise" This reverts commit befd8d2ce36b6ca903250bada62293491f0b56a2. * Revert "Requested changes" This reverts commit 5f728e00aaeb4bed3e3c006539d380f74d3aff76. * Change features based on edition (#7212) * Change features based on edition * Fix enterprise build * Update window titles and about screen (#7214) * Fix About screen for Business edition * Change dialog title * Refactored upgrade prompt for TLS and hotkeys (#7215) * Prompt Basic users to upgrade to Pro to access TLS encryption * Fixed Enterprise build * Fix code smells * Fix sonar bug --- ChangeLog | 1 + cmake/Version.cmake | 2 +- src/gui/src/AboutDialog.cpp | 97 +++++++++++----------- src/gui/src/AboutDialog.h | 23 +++--- src/gui/src/AboutDialogEliteBackers.cpp | 73 ++++++++++++++++ src/gui/src/AboutDialogEliteBackers.h | 36 ++++++++ src/gui/src/ActivationDialog.cpp | 2 +- src/gui/src/AppConfig.cpp | 36 +++++++- src/gui/src/AppConfig.h | 15 +++- src/gui/src/LicenseManager.cpp | 10 ++- src/gui/src/LicenseManager.h | 4 + src/gui/src/LicenseRegistry.cpp | 105 ++++++++++++++++++++++++ src/gui/src/LicenseRegistry.h | 44 ++++++++++ src/gui/src/MainWindow.cpp | 13 +++ src/gui/src/ServerConfig.cpp | 16 +++- src/gui/src/ServerConfig.h | 1 + src/gui/src/ServerConfigDialog.cpp | 22 +++-- src/gui/src/SettingsDialog.cpp | 24 ++++-- src/gui/src/UpgradeDialog.cpp | 38 +++++++++ src/gui/src/UpgradeDialog.h | 25 ++++++ src/lib/shared/EditionType.h | 4 +- src/lib/shared/SerialKeyEdition.cpp | 16 +++- src/lib/shared/SerialKeyEdition.h | 2 + src/lib/shared/SerialKeyParser.cpp | 6 ++ 24 files changed, 525 insertions(+), 90 deletions(-) create mode 100644 src/gui/src/AboutDialogEliteBackers.cpp create mode 100644 src/gui/src/AboutDialogEliteBackers.h create mode 100644 src/gui/src/LicenseRegistry.cpp create mode 100644 src/gui/src/LicenseRegistry.h create mode 100644 src/gui/src/UpgradeDialog.cpp create mode 100644 src/gui/src/UpgradeDialog.h diff --git a/ChangeLog b/ChangeLog index 945eaf8cd..6bd74966a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ Enhancements: - #7190 Maintenance license serial key support - #7193 Support for maintenance licenses in China - #7197 Special contributor mentions on the about screen +- #7203 License registration for Business edition Github Actions: - #7210 Update macos workflow to use macos-latest diff --git a/cmake/Version.cmake b/cmake/Version.cmake index 950da25d4..6066f2940 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -8,7 +8,7 @@ set (SYNERGY_VERSION_MAJOR 1) set (SYNERGY_VERSION_MINOR 14) set (SYNERGY_VERSION_PATCH 5) set (SYNERGY_VERSION_BUILD 1) -set (SYNERGY_VERSION_STAGE "snapshot") +set (SYNERGY_VERSION_STAGE "stable") # # Version from CI diff --git a/src/gui/src/AboutDialog.cpp b/src/gui/src/AboutDialog.cpp index 1e0ca91b8..ca03e67f0 100644 --- a/src/gui/src/AboutDialog.cpp +++ b/src/gui/src/AboutDialog.cpp @@ -16,80 +16,77 @@ * along with this program. If not, see . */ -#include "AboutDialog.h" -#include "CreditsLoader.h" - -#include -#include - #include "OSXHelpers.h" +#include "AboutDialog.h" AboutDialog::AboutDialog(MainWindow* parent, const AppConfig& config) : - QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), - Ui::AboutDialogBase(), - credits(*parent, config) + QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), + Ui::AboutDialogBase() { - setupUi(this); - setupCreditsLoader(); + setupUi(this); - QString aboutText(R"(

-Keyboard and mouse sharing application. Cross platform and open source since 2001.

-Copyright © %%YEAR%% Symless Ltd.

-Synergy is released under the GNU General Public License (GPLv2).

-

Key contributors
-Chris Schoeneman, Nick Bolton, Richard Lee, Adam Feder, Volker Lanz, -Ryan Breen, Guido Poschta, Bertrand Landry Hetu, Tom Chadwick, Brent Priddy, Kyle Bloom, -Daun Chung, Serhii Hadzhylov, Oleksandr Lysytsia, Olena Kutytska, Francisco Magalhães. -

)"); - - m_versionChecker.setApp(parent->appPath(config.synergycName())); - QString version = m_versionChecker.getVersion(); + m_versionChecker.setApp(parent->appPath(config.synergycName())); + QString version = m_versionChecker.getVersion(); #ifdef SYNERGY_REVISION version += '-'; version += SYNERGY_REVISION; #endif - m_pLabelSynergyVersion->setText(version); + m_pLabelSynergyVersion->setText(version); - QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); - QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); - m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate)); + QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); + QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); + m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate)); - //Sets the current build year into the copyright text - label_3->setText(aboutText.replace(QString("%%YEAR%%"), QString::number(buildDate.year()))); + textEliteBackers->hide(); + labelEliteBackers->hide(); + labelEliteBackerLink->hide(); + labelCreditsLink->hide(); +} - // change default size based on os +int AboutDialog::exec() +{ + //Sets the current build year into the copyright text + label_3->setText(getCopyrights() + getKeyContributors()); + resizeWindow(); + updateLogo(); + + return QDialog::exec(); +} + +void AboutDialog::resizeWindow() +{ + QSize size(600, 310); + setMaximumSize(size); + setMinimumSize(size); + resize(size); +} + +void AboutDialog::updateLogo() const +{ #if defined(Q_OS_MAC) - QSize size(600, 490); - setMaximumSize(size); - setMinimumSize(size); - resize(size); - if (isOSXInterfaceStyleDark()) { QPixmap logo(":/res/image/about-dark.png"); if (!logo.isNull()) { label_Logo->setPixmap(logo); } } - -#elif defined(Q_OS_LINUX) - QSize size(600, 420); - setMaximumSize(size); - setMinimumSize(size); - resize(size); #endif } -void AboutDialog::setupCreditsLoader() +QString AboutDialog::getKeyContributors() const { - this->textEliteBackers->setText("Loading..."); - this->textEliteBackers->viewport()->setAutoFillBackground(false); - this->textEliteBackers->document()->setDocumentMargin(0); - - connect(&credits, SIGNAL(loaded(const QString&)), this, SLOT(updateEliteBackers(const QString&))); - credits.loadEliteBackers(); + return QString(R"(

Key contributors
+ Chris Schoeneman, Nick Bolton, Richard Lee, Adam Feder, Volker Lanz, + Ryan Breen, Guido Poschta, Bertrand Landry Hetu, Tom Chadwick, Brent Priddy, Kyle Bloom, + Daun Chung, Serhii Hadzhylov, Oleksandr Lysytsia, Olena Kutytska, Francisco Magalhães. +

)"); } -void AboutDialog::updateEliteBackers(const QString& eliteBackers) const +QString AboutDialog::getCopyrights() const { - this->textEliteBackers->setText(eliteBackers); + QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); + QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); + + QString copyrights(R"(

Keyboard and mouse sharing application.

Copyright © %%YEAR%% Symless Ltd.

)"); + return copyrights.replace(QString("%%YEAR%%"), QString::number(buildDate.year())); } diff --git a/src/gui/src/AboutDialog.h b/src/gui/src/AboutDialog.h index 201c5e3aa..951984061 100644 --- a/src/gui/src/AboutDialog.h +++ b/src/gui/src/AboutDialog.h @@ -22,7 +22,6 @@ #include #include "VersionChecker.h" -#include "CreditsLoader.h" #include "MainWindow.h" #include "ui_AboutDialogBase.h" @@ -30,20 +29,18 @@ class QWidget; class QString; -class AboutDialog : public QDialog, public Ui::AboutDialogBase -{ +class AboutDialog : public QDialog, public Ui::AboutDialogBase { Q_OBJECT +public: + AboutDialog(MainWindow* parent, const AppConfig& config); + int exec() override; +private: + VersionChecker m_versionChecker; + void updateLogo() const; - public: - AboutDialog(MainWindow* parent, const AppConfig& config); - public slots: - void updateEliteBackers(const QString& eliteBackers) const; - - private: - CreditsLoader credits; - VersionChecker m_versionChecker; - - void setupCreditsLoader(); + virtual void resizeWindow(); + virtual QString getCopyrights() const; + virtual QString getKeyContributors() const; }; #endif diff --git a/src/gui/src/AboutDialogEliteBackers.cpp b/src/gui/src/AboutDialogEliteBackers.cpp new file mode 100644 index 000000000..f4fad9763 --- /dev/null +++ b/src/gui/src/AboutDialogEliteBackers.cpp @@ -0,0 +1,73 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 Symless Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "CreditsLoader.h" +#include "AboutDialogEliteBackers.h" + +AboutDialogEliteBackers::AboutDialogEliteBackers(MainWindow* parent, const AppConfig& config) : + AboutDialog(parent, config), + credits(*parent, config) +{ + setupCreditsLoader(); + + textEliteBackers->show(); + labelEliteBackers->show(); + labelEliteBackerLink->show(); + labelCreditsLink->show(); +} + +void AboutDialogEliteBackers::setupCreditsLoader() +{ + this->textEliteBackers->setText("Loading..."); + this->textEliteBackers->viewport()->setAutoFillBackground(false); + this->textEliteBackers->document()->setDocumentMargin(0); + + connect(&credits, SIGNAL(loaded(const QString&)), this, SLOT(updateEliteBackers(const QString&))); + credits.loadEliteBackers(); +} + +void AboutDialogEliteBackers::updateEliteBackers(const QString& eliteBackers) const +{ + this->textEliteBackers->setText(eliteBackers); +} + +QString AboutDialogEliteBackers::getCopyrights() const +{ + QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); + QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); + + QString aboutText(R"(

Keyboard and mouse sharing application. Cross platform and open source since 2001.

+ Copyright © %%YEAR%% Symless Ltd.

+ Synergy is released under the GNU General Public License (GPLv2).

)"); + + return aboutText.replace(QString("%%YEAR%%"), QString::number(buildDate.year())); +} + +void AboutDialogEliteBackers::resizeWindow() +{ +// change default size based on os +#if defined(Q_OS_MAC) + QSize size(600, 490); + setMaximumSize(size); + setMinimumSize(size); + resize(size); +#elif defined(Q_OS_LINUX) + QSize size(600, 420); + setMaximumSize(size); + setMinimumSize(size); + resize(size); +#endif +} diff --git a/src/gui/src/AboutDialogEliteBackers.h b/src/gui/src/AboutDialogEliteBackers.h new file mode 100644 index 000000000..8344991d5 --- /dev/null +++ b/src/gui/src/AboutDialogEliteBackers.h @@ -0,0 +1,36 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 Symless Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include "CreditsLoader.h" +#include "AboutDialog.h" + +class AboutDialogEliteBackers : public AboutDialog { + Q_OBJECT +public: + AboutDialogEliteBackers(MainWindow* parent, const AppConfig& config); + +public slots: + void updateEliteBackers(const QString& eliteBackers) const; + +private: + CreditsLoader credits; + + void setupCreditsLoader(); + void resizeWindow() override; + QString getCopyrights() const override; +}; diff --git a/src/gui/src/ActivationDialog.cpp b/src/gui/src/ActivationDialog.cpp index eae123250..f7e0d8a90 100644 --- a/src/gui/src/ActivationDialog.cpp +++ b/src/gui/src/ActivationDialog.cpp @@ -85,7 +85,7 @@ void ActivationDialog::accept() arg ((daysLeft == 1) ? "" : "s"). arg ((daysLeft == 1) ? "s" : ""); - if (edition == kPro || edition == kPro_China || edition == kBusiness) { + if (m_appConfig->isCryptoAvailable()) { m_appConfig->generateCertificate(); thanksMessage = thanksMessage.arg("If you're using SSL, " "remember to activate all of your devices."); diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 8b2d2192f..1b0877329 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -80,7 +80,10 @@ const char* AppConfig::m_SynergySettingsName[] = { "preventSleep", "languageSync", "invertScrollDirection", - "eliteBackersUrl" + "eliteBackersUrl", + "guid", + "licenseRegistryUrl", + "licenseNextCheck" }; static const char* logLevelNames[] = @@ -247,6 +250,9 @@ void AppConfig::loadSettings() m_LanguageSync = loadSetting(kLanguageSync, false).toBool(); m_InvertScrollDirection = loadSetting(kInvertScrollDirection, false).toBool(); m_eliteBackersUrl = loadCommonSetting(kEliteBackersUrl, "https://api2.prod.symless.com/credits/elite-backers").toString(); + m_guid = loadCommonSetting(kGuid, QUuid::createUuid()).toString(); + m_licenseRegistryUrl = loadCommonSetting(kLicenseRegistryUrl, "https://api2.prod.symless.com/license/register").toString(); + m_licenseNextCheck = loadCommonSetting(kLicenseNextCheck, 0).toULongLong(); //only change the serial key if the settings being loaded contains a key bool updateSerial = ConfigWriter::make() @@ -280,6 +286,9 @@ void AppConfig::saveSettings() setCommonSetting(kGroupClientCheck, m_ClientGroupChecked); setCommonSetting(kGroupServerCheck, m_ServerGroupChecked); setCommonSetting(kEliteBackersUrl, m_eliteBackersUrl); + setCommonSetting(kGuid, m_guid); + setCommonSetting(kLicenseRegistryUrl, m_licenseRegistryUrl); + setCommonSetting(kLicenseNextCheck, m_licenseNextCheck); if (isWritable()) { setSetting(kScreenName, m_ScreenName); @@ -408,7 +417,7 @@ void AppConfig::clearSerialKey() m_Serialkey.clear(); } -QString AppConfig::serialKey() { return m_Serialkey; } +QString AppConfig::serialKey() const { return m_Serialkey; } int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; } @@ -439,8 +448,11 @@ void AppConfig::setCryptoEnabled(bool newValue) { bool AppConfig::isCryptoAvailable() const { bool result {true}; -#ifndef SYNERGY_ENTERPRISE - result = (edition() == kPro || edition() == kPro_China || edition() == kBusiness); +#if !defined(SYNERGY_ENTERPRISE) && !defined(SYNERGY_BUSINESS) + result = (edition() == kPro || + edition() == kPro_China || + edition() == kBusiness || + edition() == kUltimate); #endif return result; @@ -468,10 +480,26 @@ void AppConfig::setEliteBackersUrl(const QString& newValue) { setSettingModified(m_eliteBackersUrl, newValue); } +void AppConfig::setLicenseNextCheck(unsigned long long time) { + setSettingModified(m_licenseNextCheck, time); +} + const QString& AppConfig::getEliteBackersUrl() const { return m_eliteBackersUrl; } +const QString& AppConfig::getLicenseRegistryUrl() const { + return m_licenseRegistryUrl; +} + +unsigned long long AppConfig::getLicenseNextCheck() const { + return m_licenseNextCheck; +} + +const QString& AppConfig::getGuid() const { + return m_guid; +} + bool AppConfig::getLanguageSync() const { return m_LanguageSync; } void AppConfig::setInvertScrollDirection(bool newValue) { diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 072cd714e..87e155e35 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -50,6 +50,7 @@ const int kWizardVersion = 8; class QSettings; class SettingsDialog; class ServerConfig; +class LicenseRegister; enum ProcessMode { Service, @@ -93,7 +94,7 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase Edition edition() const; void setSerialKey(const QString& serial); void clearSerialKey(); - QString serialKey(); + QString serialKey() const; int lastExpiringWarningTime() const; void setLastExpiringWarningTime(int t); #endif @@ -115,7 +116,11 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase void setInvertScrollDirection(bool b); bool getInvertScrollDirection() const; void setEliteBackersUrl(const QString&); + void setLicenseNextCheck(unsigned long long); const QString& getEliteBackersUrl() const; + const QString& getLicenseRegistryUrl() const; + unsigned long long getLicenseNextCheck() const; + const QString& getGuid() const; void setLanguageSync(bool b); bool getLanguageSync() const; void setPreventSleep(bool b); @@ -211,7 +216,10 @@ protected: kPreventSleep, kLanguageSync, kInvertScrollDirection, - kEliteBackersUrl + kEliteBackersUrl, + kGuid, + kLicenseRegistryUrl, + kLicenseNextCheck }; void setScreenName(const QString& s); @@ -252,6 +260,9 @@ protected: QString m_Serialkey; QString m_lastVersion; QString m_eliteBackersUrl; + QString m_guid; + QString m_licenseRegistryUrl; + unsigned long long m_licenseNextCheck; int m_LastExpiringWarningTime; bool m_ActivationHasRun; bool m_MinimizeToTray; diff --git a/src/gui/src/LicenseManager.cpp b/src/gui/src/LicenseManager.cpp index 49d66c081..b4c899b36 100644 --- a/src/gui/src/LicenseManager.cpp +++ b/src/gui/src/LicenseManager.cpp @@ -66,7 +66,8 @@ checkSerialKey(const SerialKey& serialKey, bool acceptExpired) LicenseManager::LicenseManager(AppConfig* appConfig) : m_AppConfig(appConfig), - m_serialKey(appConfig->edition()) { + m_serialKey(appConfig->edition()), + m_registry(*appConfig) { } void @@ -82,6 +83,7 @@ LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) emit showLicenseNotice(getLicenseNotice()); validateSerialKey(); + m_registry.scheduleRegistration(); if (m_serialKey.edition() != serialKey.edition()) { m_AppConfig->setEdition(m_serialKey.edition()); @@ -201,6 +203,12 @@ LicenseManager::getLicenseNotice() const return Notice; } +void +LicenseManager::registerLicense() +{ + m_registry.registerLicense(); +} + QString LicenseManager::getTrialNotice() const { diff --git a/src/gui/src/LicenseManager.h b/src/gui/src/LicenseManager.h index 101cb299e..1c9feeefb 100644 --- a/src/gui/src/LicenseManager.h +++ b/src/gui/src/LicenseManager.h @@ -23,6 +23,8 @@ #include #include +#include "LicenseRegistry.h" + class AppConfig; class LicenseManager: public QObject @@ -45,9 +47,11 @@ public: private: AppConfig* m_AppConfig; SerialKey m_serialKey; + LicenseRegistry m_registry; public slots: void validateSerialKey() const; + void registerLicense(); signals: void editionChanged (Edition) const; diff --git a/src/gui/src/LicenseRegistry.cpp b/src/gui/src/LicenseRegistry.cpp new file mode 100644 index 000000000..3549dffd4 --- /dev/null +++ b/src/gui/src/LicenseRegistry.cpp @@ -0,0 +1,105 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 Synergy Seamless Inc. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + +#include "LicenseRegistry.h" +#include "AppConfig.h" +#include + +LicenseRegistry::LicenseRegistry(AppConfig& config) : + m_config(config) +{ + connect(&m_timer, SIGNAL(timeout()), this, SLOT(registerLicense())); +} + +void LicenseRegistry::registerLicense() +{ + m_timer.stop(); + if (m_config.edition() == Edition::kBusiness) { + const auto REGISTER_LICENSE_URL = m_config.getLicenseRegistryUrl(); + const auto url = QUrl(REGISTER_LICENSE_URL); + + auto request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + m_manager.post(request, getRequestData()); + connect(&m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleResponse(QNetworkReply*))); + } +} + +void LicenseRegistry::handleResponse(QNetworkReply *reply) +{ + if (reply) { + const auto HOUR = (60*60); //seconds per hour + const auto DAY = (24*HOUR);//seconds per day + const auto WEEK = (7*DAY); //seconds per week + const auto currentTimestamp = time(nullptr); + + if(reply->error() == QNetworkReply::NoError) { + m_config.setLicenseNextCheck(currentTimestamp + WEEK); + } + else{ + m_config.setLicenseNextCheck(currentTimestamp + HOUR); + } + + scheduleRegistration(); + reply->deleteLater(); + } +} + +QByteArray LicenseRegistry::getRequestData() const +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) + QString guid(QSysInfo::machineUniqueId()); +#else + QString guid; +#endif + + QJsonObject data; + if (!guid.isEmpty()) { + data["guid"] = guid; + data["guid_type"] = "system"; + } + else { + data["guid"] = m_config.getGuid(); + data["guid_type"] = "synergy"; + } + + data["key"] = m_config.serialKey(); + data["is_server"] = m_config.getServerGroupChecked(); + + return QJsonDocument(data).toJson(); +} + +void LicenseRegistry::scheduleRegistration() +{ + const auto nextCheck = m_config.getLicenseNextCheck(); + const auto currentTimestamp = static_cast(time(nullptr)); + + if (currentTimestamp >= nextCheck) { + registerLicense(); + } + else { + const auto interval = (nextCheck - currentTimestamp) * 1000; //interval in milliseconds + m_timer.setInterval(static_cast(interval)); + m_timer.setSingleShot(true); + m_timer.start(); + } +} diff --git a/src/gui/src/LicenseRegistry.h b/src/gui/src/LicenseRegistry.h new file mode 100644 index 000000000..8fa45b00c --- /dev/null +++ b/src/gui/src/LicenseRegistry.h @@ -0,0 +1,44 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 Synergy Seamless Inc. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include +#include +#include + +class QNetworkReply; +class AppConfig; + +class LicenseRegistry : public QObject +{ + Q_OBJECT + +public: + explicit LicenseRegistry(AppConfig& config); + void scheduleRegistration(); + +public slots: + void registerLicense(); + void handleResponse(QNetworkReply *reply); + +private: + AppConfig& m_config; + QNetworkAccessManager m_manager; + QTimer m_timer; + + QByteArray getRequestData() const; +}; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index c6592248c..106681dfe 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -25,6 +25,7 @@ #include "Fingerprint.h" #include "AboutDialog.h" +#include "AboutDialogEliteBackers.h" #include "ServerConfigDialog.h" #include "SettingsDialog.h" #include "ActivationDialog.h" @@ -646,6 +647,7 @@ void MainWindow::startSynergy() return; } } + m_LicenseManager->registerLicense(); #endif bool desktopMode = appConfig().processMode() == Desktop; bool serviceMode = appConfig().processMode() == Service; @@ -1265,8 +1267,19 @@ bool MainWindow::on_m_pActionSave_triggered() void MainWindow::on_m_pActionAbout_triggered() { +#if defined(SYNERGY_ENTERPRISE) || defined(SYNERGY_BUSINESS) AboutDialog dlg(this, appConfig()); dlg.exec(); +#else + if (appConfig().edition() == Edition::kBusiness) { + AboutDialog dlg(this, appConfig()); + dlg.exec(); + } + else { + AboutDialogEliteBackers dlg(this, appConfig()); + dlg.exec(); + } +#endif } void MainWindow::on_m_pActionHelp_triggered() diff --git a/src/gui/src/ServerConfig.cpp b/src/gui/src/ServerConfig.cpp index 9fa9887af..dae75aa39 100644 --- a/src/gui/src/ServerConfig.cpp +++ b/src/gui/src/ServerConfig.cpp @@ -56,12 +56,16 @@ ServerConfig::ServerConfig(int numColumns, int numRows, AppConfig* appConfig, Ma m_pMainWindow(mainWindow) { GUI::Config::ConfigWriter::make()->registerClass(this); - loadSettings(); + ServerConfig::loadSettings(); } ServerConfig::~ServerConfig() { - saveSettings(); + try { + ServerConfig::saveSettings(); + } catch (const std::exception& e) { + m_pMainWindow->appendLogError(e.what()); + } } bool ServerConfig::save(const QString& fileName) const @@ -555,3 +559,11 @@ QSettings &ServerConfig::settings() { return ConfigWriter::make()->settings(); } + +bool ServerConfig::isHotkeysAvailable() const { +#ifndef SYNERGY_ENTERPRISE + return (m_pAppConfig->edition() != Edition::kLite); +#else + return true; +#endif +} diff --git a/src/gui/src/ServerConfig.h b/src/gui/src/ServerConfig.h index 3daa6d03b..d6479e384 100644 --- a/src/gui/src/ServerConfig.h +++ b/src/gui/src/ServerConfig.h @@ -88,6 +88,7 @@ class ServerConfig : public BaseConfig, public GUI::Config::ConfigBase bool isFull() const; bool isScreenExists(const QString& screenName) const; void addClient(const QString& clientName); + bool isHotkeysAvailable() const; protected: QSettings& settings(); diff --git a/src/gui/src/ServerConfigDialog.cpp b/src/gui/src/ServerConfigDialog.cpp index d05bd6d18..b02b93eeb 100644 --- a/src/gui/src/ServerConfigDialog.cpp +++ b/src/gui/src/ServerConfigDialog.cpp @@ -21,6 +21,7 @@ #include "ServerConfig.h" #include "HotkeyDialog.h" #include "ActionDialog.h" +#include "UpgradeDialog.h" #include #include @@ -186,12 +187,21 @@ void ServerConfigDialog::reject() void ServerConfigDialog::on_m_pButtonNewHotkey_clicked() { - Hotkey hotkey; - HotkeyDialog dlg(this, hotkey); - if (dlg.exec() == QDialog::Accepted) { - serverConfig().hotkeys().append(hotkey); - m_pListHotkeys->addItem(hotkey.text()); - onChange(); + if (serverConfig().isHotkeysAvailable()) { + Hotkey hotkey; + HotkeyDialog dlg(this, hotkey); + if (dlg.exec() == QDialog::Accepted) { + serverConfig().hotkeys().append(hotkey); + m_pListHotkeys->addItem(hotkey.text()); + onChange(); + } + } + else { + UpgradeDialog upgradeDialog(this); + upgradeDialog.showDialog( + "Configuring custom hotkeys is a Synergy Ultimate feature.", + "synergy/purchase/purchase-ultimate-upgrade?source=gui" + ); } } diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index bb27499e5..67cc368d2 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -27,6 +27,7 @@ #include "MainWindow.h" #include "BonjourWindows.h" #include "Zeroconf.h" +#include "UpgradeDialog.h" #include #include @@ -264,16 +265,23 @@ void SettingsDialog::on_m_pCheckBoxEnableCrypto_clicked(bool checked) else { m_pCheckBoxEnableCrypto->setChecked(false); - - QMessageBox message(this); - message.addButton(QObject::tr("Close"), QMessageBox::RejectRole); - message.addButton(QObject::tr("Upgrade"), QMessageBox::AcceptRole); - message.setText(QObject::tr("TLS encryption is Synergy Pro feature.\nPlease upgrade if this is important to you")); - - if (message.exec() == QMessageBox::Accepted) +#if !defined(SYNERGY_ENTERPRISE) && !defined(SYNERGY_BUSINESS) + UpgradeDialog upgradeDialog(this); + if (appConfig().edition() == Edition::kLite) { - QDesktopServices::openUrl(QUrl(QCoreApplication::organizationDomain() + "synergy/purchase/upgrade")); + upgradeDialog.showDialog( + "TLS encryption is a Synergy Ultimate feature.", + "synergy/purchase/purchase-ultimate-upgrade?source=gui" + ); } + else + { + upgradeDialog.showDialog( + "TLS encryption is a Synergy Pro feature.", + "synergy/purchase/upgrade?source=gui" + ); + } +#endif } } diff --git a/src/gui/src/UpgradeDialog.cpp b/src/gui/src/UpgradeDialog.cpp new file mode 100644 index 000000000..b41a8e9f7 --- /dev/null +++ b/src/gui/src/UpgradeDialog.cpp @@ -0,0 +1,38 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 Symless Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "UpgradeDialog.h" + +#include +#include + +UpgradeDialog::UpgradeDialog(QWidget* parent) : + QMessageBox(parent) +{ + setWindowTitle(QObject::tr("Upgrade to access this feature")); + addButton(QObject::tr("Close"), QMessageBox::RejectRole); + addButton(QObject::tr("Upgrade"), QMessageBox::AcceptRole); +} + +void UpgradeDialog::showDialog(const QString& text, const QString& link) +{ + setText(QObject::tr(text.toStdString().c_str())); + + if (exec() == QMessageBox::Accepted) + { + QDesktopServices::openUrl(QUrl(QCoreApplication::organizationDomain() + link)); + } +} diff --git a/src/gui/src/UpgradeDialog.h b/src/gui/src/UpgradeDialog.h new file mode 100644 index 000000000..9b119d4b5 --- /dev/null +++ b/src/gui/src/UpgradeDialog.h @@ -0,0 +1,25 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 Symless Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +class UpgradeDialog : public QMessageBox +{ +public: + explicit UpgradeDialog(QWidget *parent = nullptr); + void showDialog(const QString& text, const QString& link); +}; diff --git a/src/lib/shared/EditionType.h b/src/lib/shared/EditionType.h index 701d14575..095a73d8f 100644 --- a/src/lib/shared/EditionType.h +++ b/src/lib/shared/EditionType.h @@ -27,7 +27,9 @@ enum Edition { kUnregistered, kBusiness, kBasic_China, - kPro_China + kPro_China, + kLite, + kUltimate }; #endif // EDITIONTYPE_H diff --git a/src/lib/shared/SerialKeyEdition.cpp b/src/lib/shared/SerialKeyEdition.cpp index a0c5f5055..4862afbe8 100644 --- a/src/lib/shared/SerialKeyEdition.cpp +++ b/src/lib/shared/SerialKeyEdition.cpp @@ -9,6 +9,8 @@ const std::string SerialKeyEdition::BASIC = "basic"; const std::string SerialKeyEdition::BASIC_CHINA = "basic_china"; const std::string SerialKeyEdition::BUSINESS = "business"; const std::string SerialKeyEdition::UNREGISTERED = "unregistered"; +const std::string SerialKeyEdition::ULTIMATE = "ultimate"; +const std::string SerialKeyEdition::LITE = "lite"; namespace { @@ -24,7 +26,9 @@ const std::map& getSerialTypes() {SerialKeyEdition::PRO, kPro}, {SerialKeyEdition::BASIC_CHINA, kBasic_China}, {SerialKeyEdition::PRO_CHINA, kPro_China}, - {SerialKeyEdition::BUSINESS, kBusiness} + {SerialKeyEdition::BUSINESS, kBusiness}, + {SerialKeyEdition::LITE, kLite}, + {SerialKeyEdition::ULTIMATE, kUltimate} }; #endif return serialTypes; @@ -78,6 +82,12 @@ SerialKeyEdition::getName() const case kPro_China: Name = PRO_CHINA; break; + case kLite: + Name = LITE; + break; + case kUltimate: + Name = ULTIMATE; + break; default: break; } @@ -99,6 +109,9 @@ SerialKeyEdition::getDisplayName() const case kPro_China: DisplayName = "Synergy Pro 中文版"; break; + case kLite: + DisplayName = "Synergy 1"; + break; default: std::string EditionName = getName(); if (!EditionName.empty()){ @@ -120,6 +133,7 @@ void SerialKeyEdition::setType(Edition type) { m_Type = type; + setType(getName()); } void diff --git a/src/lib/shared/SerialKeyEdition.h b/src/lib/shared/SerialKeyEdition.h index e9bae4d3b..a69007846 100644 --- a/src/lib/shared/SerialKeyEdition.h +++ b/src/lib/shared/SerialKeyEdition.h @@ -43,6 +43,8 @@ public: static const std::string BASIC_CHINA; static const std::string BUSINESS; static const std::string UNREGISTERED; + static const std::string ULTIMATE; + static const std::string LITE; private: Edition m_Type = kUnregistered; diff --git a/src/lib/shared/SerialKeyParser.cpp b/src/lib/shared/SerialKeyParser.cpp index ca3af10f6..1e96f3844 100644 --- a/src/lib/shared/SerialKeyParser.cpp +++ b/src/lib/shared/SerialKeyParser.cpp @@ -33,6 +33,12 @@ void SerialKeyParser::setEdition(const std::string& edition) { m_data.edition.setType(edition); + if (m_data.keyType.isMaintenance() && m_data.edition.getType() == Edition::kBasic) { + m_data.edition.setType(kLite); + } + else if (m_data.keyType.isMaintenance() && m_data.edition.getType() == Edition::kPro) { + m_data.edition.setType(kUltimate); + } } void