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
This commit is contained in:
Serhii Hadzhilov 2022-09-13 18:31:45 +03:00 committed by GitHub
parent a0560e5d87
commit 452c631d6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 525 additions and 90 deletions

View file

@ -10,6 +10,7 @@ Enhancements:
- #7190 Maintenance license serial key support - #7190 Maintenance license serial key support
- #7193 Support for maintenance licenses in China - #7193 Support for maintenance licenses in China
- #7197 Special contributor mentions on the about screen - #7197 Special contributor mentions on the about screen
- #7203 License registration for Business edition
Github Actions: Github Actions:
- #7210 Update macos workflow to use macos-latest - #7210 Update macos workflow to use macos-latest

View file

@ -8,7 +8,7 @@ set (SYNERGY_VERSION_MAJOR 1)
set (SYNERGY_VERSION_MINOR 14) set (SYNERGY_VERSION_MINOR 14)
set (SYNERGY_VERSION_PATCH 5) set (SYNERGY_VERSION_PATCH 5)
set (SYNERGY_VERSION_BUILD 1) set (SYNERGY_VERSION_BUILD 1)
set (SYNERGY_VERSION_STAGE "snapshot") set (SYNERGY_VERSION_STAGE "stable")
# #
# Version from CI # Version from CI

View file

@ -16,80 +16,77 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "AboutDialog.h"
#include "CreditsLoader.h"
#include <QtCore>
#include <QtGui>
#include "OSXHelpers.h" #include "OSXHelpers.h"
#include "AboutDialog.h"
AboutDialog::AboutDialog(MainWindow* parent, const AppConfig& config) : AboutDialog::AboutDialog(MainWindow* parent, const AppConfig& config) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::AboutDialogBase(), Ui::AboutDialogBase()
credits(*parent, config)
{ {
setupUi(this); setupUi(this);
setupCreditsLoader();
QString aboutText(R"(<p> m_versionChecker.setApp(parent->appPath(config.synergycName()));
Keyboard and mouse sharing application. Cross platform and open source since 2001.<br /><br /> QString version = m_versionChecker.getVersion();
Copyright © %%YEAR%% Symless Ltd.<br /><br />
Synergy is released under the GNU General Public License (GPLv2).</p>
<p style="font-size: 14px">Key contributors<br>
<span style="font-size: 11px">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.</span>
</p>)");
m_versionChecker.setApp(parent->appPath(config.synergycName()));
QString version = m_versionChecker.getVersion();
#ifdef SYNERGY_REVISION #ifdef SYNERGY_REVISION
version += '-'; version += '-';
version += SYNERGY_REVISION; version += SYNERGY_REVISION;
#endif #endif
m_pLabelSynergyVersion->setText(version); m_pLabelSynergyVersion->setText(version);
QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified();
QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate)); m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate));
//Sets the current build year into the copyright text textEliteBackers->hide();
label_3->setText(aboutText.replace(QString("%%YEAR%%"), QString::number(buildDate.year()))); 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) #if defined(Q_OS_MAC)
QSize size(600, 490);
setMaximumSize(size);
setMinimumSize(size);
resize(size);
if (isOSXInterfaceStyleDark()) { if (isOSXInterfaceStyleDark()) {
QPixmap logo(":/res/image/about-dark.png"); QPixmap logo(":/res/image/about-dark.png");
if (!logo.isNull()) { if (!logo.isNull()) {
label_Logo->setPixmap(logo); label_Logo->setPixmap(logo);
} }
} }
#elif defined(Q_OS_LINUX)
QSize size(600, 420);
setMaximumSize(size);
setMinimumSize(size);
resize(size);
#endif #endif
} }
void AboutDialog::setupCreditsLoader() QString AboutDialog::getKeyContributors() const
{ {
this->textEliteBackers->setText("Loading..."); return QString(R"(<p style="font-size: 14px">Key contributors<br>
this->textEliteBackers->viewport()->setAutoFillBackground(false); <span style="font-size: 11px">Chris Schoeneman, Nick Bolton, Richard Lee, Adam Feder, Volker Lanz,
this->textEliteBackers->document()->setDocumentMargin(0); Ryan Breen, Guido Poschta, Bertrand Landry Hetu, Tom Chadwick, Brent Priddy, Kyle Bloom,
Daun Chung, Serhii Hadzhylov, Oleksandr Lysytsia, Olena Kutytska, Francisco Magalhães.</span>
connect(&credits, SIGNAL(loaded(const QString&)), this, SLOT(updateEliteBackers(const QString&))); </p>)");
credits.loadEliteBackers();
} }
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"(<p>Keyboard and mouse sharing application.<br /><br />Copyright © %%YEAR%% Symless Ltd.</p>)");
return copyrights.replace(QString("%%YEAR%%"), QString::number(buildDate.year()));
} }

View file

@ -22,7 +22,6 @@
#include <QDialog> #include <QDialog>
#include "VersionChecker.h" #include "VersionChecker.h"
#include "CreditsLoader.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "ui_AboutDialogBase.h" #include "ui_AboutDialogBase.h"
@ -30,20 +29,18 @@
class QWidget; class QWidget;
class QString; class QString;
class AboutDialog : public QDialog, public Ui::AboutDialogBase class AboutDialog : public QDialog, public Ui::AboutDialogBase {
{
Q_OBJECT Q_OBJECT
public:
AboutDialog(MainWindow* parent, const AppConfig& config);
int exec() override;
private:
VersionChecker m_versionChecker;
void updateLogo() const;
public: virtual void resizeWindow();
AboutDialog(MainWindow* parent, const AppConfig& config); virtual QString getCopyrights() const;
public slots: virtual QString getKeyContributors() const;
void updateEliteBackers(const QString& eliteBackers) const;
private:
CreditsLoader credits;
VersionChecker m_versionChecker;
void setupCreditsLoader();
}; };
#endif #endif

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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"(<p>Keyboard and mouse sharing application. Cross platform and open source since 2001.<br /><br />
Copyright © %%YEAR%% Symless Ltd.<br /><br />
Synergy is released under the GNU General Public License (GPLv2).</p>)");
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
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
};

View file

@ -85,7 +85,7 @@ void ActivationDialog::accept()
arg ((daysLeft == 1) ? "" : "s"). arg ((daysLeft == 1) ? "" : "s").
arg ((daysLeft == 1) ? "s" : ""); arg ((daysLeft == 1) ? "s" : "");
if (edition == kPro || edition == kPro_China || edition == kBusiness) { if (m_appConfig->isCryptoAvailable()) {
m_appConfig->generateCertificate(); m_appConfig->generateCertificate();
thanksMessage = thanksMessage.arg("If you're using SSL, " thanksMessage = thanksMessage.arg("If you're using SSL, "
"remember to activate all of your devices."); "remember to activate all of your devices.");

View file

@ -80,7 +80,10 @@ const char* AppConfig::m_SynergySettingsName[] = {
"preventSleep", "preventSleep",
"languageSync", "languageSync",
"invertScrollDirection", "invertScrollDirection",
"eliteBackersUrl" "eliteBackersUrl",
"guid",
"licenseRegistryUrl",
"licenseNextCheck"
}; };
static const char* logLevelNames[] = static const char* logLevelNames[] =
@ -247,6 +250,9 @@ void AppConfig::loadSettings()
m_LanguageSync = loadSetting(kLanguageSync, false).toBool(); m_LanguageSync = loadSetting(kLanguageSync, false).toBool();
m_InvertScrollDirection = loadSetting(kInvertScrollDirection, false).toBool(); m_InvertScrollDirection = loadSetting(kInvertScrollDirection, false).toBool();
m_eliteBackersUrl = loadCommonSetting(kEliteBackersUrl, "https://api2.prod.symless.com/credits/elite-backers").toString(); 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 //only change the serial key if the settings being loaded contains a key
bool updateSerial = ConfigWriter::make() bool updateSerial = ConfigWriter::make()
@ -280,6 +286,9 @@ void AppConfig::saveSettings()
setCommonSetting(kGroupClientCheck, m_ClientGroupChecked); setCommonSetting(kGroupClientCheck, m_ClientGroupChecked);
setCommonSetting(kGroupServerCheck, m_ServerGroupChecked); setCommonSetting(kGroupServerCheck, m_ServerGroupChecked);
setCommonSetting(kEliteBackersUrl, m_eliteBackersUrl); setCommonSetting(kEliteBackersUrl, m_eliteBackersUrl);
setCommonSetting(kGuid, m_guid);
setCommonSetting(kLicenseRegistryUrl, m_licenseRegistryUrl);
setCommonSetting(kLicenseNextCheck, m_licenseNextCheck);
if (isWritable()) { if (isWritable()) {
setSetting(kScreenName, m_ScreenName); setSetting(kScreenName, m_ScreenName);
@ -408,7 +417,7 @@ void AppConfig::clearSerialKey()
m_Serialkey.clear(); m_Serialkey.clear();
} }
QString AppConfig::serialKey() { return m_Serialkey; } QString AppConfig::serialKey() const { return m_Serialkey; }
int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; } int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; }
@ -439,8 +448,11 @@ void AppConfig::setCryptoEnabled(bool newValue) {
bool AppConfig::isCryptoAvailable() const { bool AppConfig::isCryptoAvailable() const {
bool result {true}; bool result {true};
#ifndef SYNERGY_ENTERPRISE #if !defined(SYNERGY_ENTERPRISE) && !defined(SYNERGY_BUSINESS)
result = (edition() == kPro || edition() == kPro_China || edition() == kBusiness); result = (edition() == kPro ||
edition() == kPro_China ||
edition() == kBusiness ||
edition() == kUltimate);
#endif #endif
return result; return result;
@ -468,10 +480,26 @@ void AppConfig::setEliteBackersUrl(const QString& newValue) {
setSettingModified(m_eliteBackersUrl, newValue); setSettingModified(m_eliteBackersUrl, newValue);
} }
void AppConfig::setLicenseNextCheck(unsigned long long time) {
setSettingModified(m_licenseNextCheck, time);
}
const QString& AppConfig::getEliteBackersUrl() const { const QString& AppConfig::getEliteBackersUrl() const {
return m_eliteBackersUrl; 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; } bool AppConfig::getLanguageSync() const { return m_LanguageSync; }
void AppConfig::setInvertScrollDirection(bool newValue) { void AppConfig::setInvertScrollDirection(bool newValue) {

View file

@ -50,6 +50,7 @@ const int kWizardVersion = 8;
class QSettings; class QSettings;
class SettingsDialog; class SettingsDialog;
class ServerConfig; class ServerConfig;
class LicenseRegister;
enum ProcessMode { enum ProcessMode {
Service, Service,
@ -93,7 +94,7 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase
Edition edition() const; Edition edition() const;
void setSerialKey(const QString& serial); void setSerialKey(const QString& serial);
void clearSerialKey(); void clearSerialKey();
QString serialKey(); QString serialKey() const;
int lastExpiringWarningTime() const; int lastExpiringWarningTime() const;
void setLastExpiringWarningTime(int t); void setLastExpiringWarningTime(int t);
#endif #endif
@ -115,7 +116,11 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase
void setInvertScrollDirection(bool b); void setInvertScrollDirection(bool b);
bool getInvertScrollDirection() const; bool getInvertScrollDirection() const;
void setEliteBackersUrl(const QString&); void setEliteBackersUrl(const QString&);
void setLicenseNextCheck(unsigned long long);
const QString& getEliteBackersUrl() const; const QString& getEliteBackersUrl() const;
const QString& getLicenseRegistryUrl() const;
unsigned long long getLicenseNextCheck() const;
const QString& getGuid() const;
void setLanguageSync(bool b); void setLanguageSync(bool b);
bool getLanguageSync() const; bool getLanguageSync() const;
void setPreventSleep(bool b); void setPreventSleep(bool b);
@ -211,7 +216,10 @@ protected:
kPreventSleep, kPreventSleep,
kLanguageSync, kLanguageSync,
kInvertScrollDirection, kInvertScrollDirection,
kEliteBackersUrl kEliteBackersUrl,
kGuid,
kLicenseRegistryUrl,
kLicenseNextCheck
}; };
void setScreenName(const QString& s); void setScreenName(const QString& s);
@ -252,6 +260,9 @@ protected:
QString m_Serialkey; QString m_Serialkey;
QString m_lastVersion; QString m_lastVersion;
QString m_eliteBackersUrl; QString m_eliteBackersUrl;
QString m_guid;
QString m_licenseRegistryUrl;
unsigned long long m_licenseNextCheck;
int m_LastExpiringWarningTime; int m_LastExpiringWarningTime;
bool m_ActivationHasRun; bool m_ActivationHasRun;
bool m_MinimizeToTray; bool m_MinimizeToTray;

View file

@ -66,7 +66,8 @@ checkSerialKey(const SerialKey& serialKey, bool acceptExpired)
LicenseManager::LicenseManager(AppConfig* appConfig) : LicenseManager::LicenseManager(AppConfig* appConfig) :
m_AppConfig(appConfig), m_AppConfig(appConfig),
m_serialKey(appConfig->edition()) { m_serialKey(appConfig->edition()),
m_registry(*appConfig) {
} }
void void
@ -82,6 +83,7 @@ LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired)
emit showLicenseNotice(getLicenseNotice()); emit showLicenseNotice(getLicenseNotice());
validateSerialKey(); validateSerialKey();
m_registry.scheduleRegistration();
if (m_serialKey.edition() != serialKey.edition()) { if (m_serialKey.edition() != serialKey.edition()) {
m_AppConfig->setEdition(m_serialKey.edition()); m_AppConfig->setEdition(m_serialKey.edition());
@ -201,6 +203,12 @@ LicenseManager::getLicenseNotice() const
return Notice; return Notice;
} }
void
LicenseManager::registerLicense()
{
m_registry.registerLicense();
}
QString QString
LicenseManager::getTrialNotice() const LicenseManager::getTrialNotice() const
{ {

View file

@ -23,6 +23,8 @@
#include <ActivationNotifier.h> #include <ActivationNotifier.h>
#include <utility> #include <utility>
#include "LicenseRegistry.h"
class AppConfig; class AppConfig;
class LicenseManager: public QObject class LicenseManager: public QObject
@ -45,9 +47,11 @@ public:
private: private:
AppConfig* m_AppConfig; AppConfig* m_AppConfig;
SerialKey m_serialKey; SerialKey m_serialKey;
LicenseRegistry m_registry;
public slots: public slots:
void validateSerialKey() const; void validateSerialKey() const;
void registerLicense();
signals: signals:
void editionChanged (Edition) const; void editionChanged (Edition) const;

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <QNetworkReply>
#include <QJsonObject>
#include <QJsonDocument>
#include <QTimer>
#include "LicenseRegistry.h"
#include "AppConfig.h"
#include <QSysInfo>
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<unsigned long long>(time(nullptr));
if (currentTimestamp >= nextCheck) {
registerLicense();
}
else {
const auto interval = (nextCheck - currentTimestamp) * 1000; //interval in milliseconds
m_timer.setInterval(static_cast<int>(interval));
m_timer.setSingleShot(true);
m_timer.start();
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QObject>
#include <QTimer>
#include <QNetworkAccessManager>
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;
};

View file

@ -25,6 +25,7 @@
#include "Fingerprint.h" #include "Fingerprint.h"
#include "AboutDialog.h" #include "AboutDialog.h"
#include "AboutDialogEliteBackers.h"
#include "ServerConfigDialog.h" #include "ServerConfigDialog.h"
#include "SettingsDialog.h" #include "SettingsDialog.h"
#include "ActivationDialog.h" #include "ActivationDialog.h"
@ -646,6 +647,7 @@ void MainWindow::startSynergy()
return; return;
} }
} }
m_LicenseManager->registerLicense();
#endif #endif
bool desktopMode = appConfig().processMode() == Desktop; bool desktopMode = appConfig().processMode() == Desktop;
bool serviceMode = appConfig().processMode() == Service; bool serviceMode = appConfig().processMode() == Service;
@ -1265,8 +1267,19 @@ bool MainWindow::on_m_pActionSave_triggered()
void MainWindow::on_m_pActionAbout_triggered() void MainWindow::on_m_pActionAbout_triggered()
{ {
#if defined(SYNERGY_ENTERPRISE) || defined(SYNERGY_BUSINESS)
AboutDialog dlg(this, appConfig()); AboutDialog dlg(this, appConfig());
dlg.exec(); 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() void MainWindow::on_m_pActionHelp_triggered()

View file

@ -56,12 +56,16 @@ ServerConfig::ServerConfig(int numColumns, int numRows, AppConfig* appConfig, Ma
m_pMainWindow(mainWindow) m_pMainWindow(mainWindow)
{ {
GUI::Config::ConfigWriter::make()->registerClass(this); GUI::Config::ConfigWriter::make()->registerClass(this);
loadSettings(); ServerConfig::loadSettings();
} }
ServerConfig::~ServerConfig() ServerConfig::~ServerConfig()
{ {
saveSettings(); try {
ServerConfig::saveSettings();
} catch (const std::exception& e) {
m_pMainWindow->appendLogError(e.what());
}
} }
bool ServerConfig::save(const QString& fileName) const bool ServerConfig::save(const QString& fileName) const
@ -555,3 +559,11 @@ QSettings &ServerConfig::settings() {
return ConfigWriter::make()->settings(); return ConfigWriter::make()->settings();
} }
bool ServerConfig::isHotkeysAvailable() const {
#ifndef SYNERGY_ENTERPRISE
return (m_pAppConfig->edition() != Edition::kLite);
#else
return true;
#endif
}

View file

@ -88,6 +88,7 @@ class ServerConfig : public BaseConfig, public GUI::Config::ConfigBase
bool isFull() const; bool isFull() const;
bool isScreenExists(const QString& screenName) const; bool isScreenExists(const QString& screenName) const;
void addClient(const QString& clientName); void addClient(const QString& clientName);
bool isHotkeysAvailable() const;
protected: protected:
QSettings& settings(); QSettings& settings();

View file

@ -21,6 +21,7 @@
#include "ServerConfig.h" #include "ServerConfig.h"
#include "HotkeyDialog.h" #include "HotkeyDialog.h"
#include "ActionDialog.h" #include "ActionDialog.h"
#include "UpgradeDialog.h"
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
@ -186,12 +187,21 @@ void ServerConfigDialog::reject()
void ServerConfigDialog::on_m_pButtonNewHotkey_clicked() void ServerConfigDialog::on_m_pButtonNewHotkey_clicked()
{ {
Hotkey hotkey; if (serverConfig().isHotkeysAvailable()) {
HotkeyDialog dlg(this, hotkey); Hotkey hotkey;
if (dlg.exec() == QDialog::Accepted) { HotkeyDialog dlg(this, hotkey);
serverConfig().hotkeys().append(hotkey); if (dlg.exec() == QDialog::Accepted) {
m_pListHotkeys->addItem(hotkey.text()); serverConfig().hotkeys().append(hotkey);
onChange(); 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"
);
} }
} }

View file

@ -27,6 +27,7 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "BonjourWindows.h" #include "BonjourWindows.h"
#include "Zeroconf.h" #include "Zeroconf.h"
#include "UpgradeDialog.h"
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
@ -264,16 +265,23 @@ void SettingsDialog::on_m_pCheckBoxEnableCrypto_clicked(bool checked)
else else
{ {
m_pCheckBoxEnableCrypto->setChecked(false); m_pCheckBoxEnableCrypto->setChecked(false);
#if !defined(SYNERGY_ENTERPRISE) && !defined(SYNERGY_BUSINESS)
QMessageBox message(this); UpgradeDialog upgradeDialog(this);
message.addButton(QObject::tr("Close"), QMessageBox::RejectRole); if (appConfig().edition() == Edition::kLite)
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)
{ {
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
} }
} }

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "UpgradeDialog.h"
#include <QtCore>
#include <QtGui>
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));
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QMessageBox>
class UpgradeDialog : public QMessageBox
{
public:
explicit UpgradeDialog(QWidget *parent = nullptr);
void showDialog(const QString& text, const QString& link);
};

View file

@ -27,7 +27,9 @@ enum Edition {
kUnregistered, kUnregistered,
kBusiness, kBusiness,
kBasic_China, kBasic_China,
kPro_China kPro_China,
kLite,
kUltimate
}; };
#endif // EDITIONTYPE_H #endif // EDITIONTYPE_H

View file

@ -9,6 +9,8 @@ const std::string SerialKeyEdition::BASIC = "basic";
const std::string SerialKeyEdition::BASIC_CHINA = "basic_china"; const std::string SerialKeyEdition::BASIC_CHINA = "basic_china";
const std::string SerialKeyEdition::BUSINESS = "business"; const std::string SerialKeyEdition::BUSINESS = "business";
const std::string SerialKeyEdition::UNREGISTERED = "unregistered"; const std::string SerialKeyEdition::UNREGISTERED = "unregistered";
const std::string SerialKeyEdition::ULTIMATE = "ultimate";
const std::string SerialKeyEdition::LITE = "lite";
namespace { namespace {
@ -24,7 +26,9 @@ const std::map<std::string, Edition>& getSerialTypes()
{SerialKeyEdition::PRO, kPro}, {SerialKeyEdition::PRO, kPro},
{SerialKeyEdition::BASIC_CHINA, kBasic_China}, {SerialKeyEdition::BASIC_CHINA, kBasic_China},
{SerialKeyEdition::PRO_CHINA, kPro_China}, {SerialKeyEdition::PRO_CHINA, kPro_China},
{SerialKeyEdition::BUSINESS, kBusiness} {SerialKeyEdition::BUSINESS, kBusiness},
{SerialKeyEdition::LITE, kLite},
{SerialKeyEdition::ULTIMATE, kUltimate}
}; };
#endif #endif
return serialTypes; return serialTypes;
@ -78,6 +82,12 @@ SerialKeyEdition::getName() const
case kPro_China: case kPro_China:
Name = PRO_CHINA; Name = PRO_CHINA;
break; break;
case kLite:
Name = LITE;
break;
case kUltimate:
Name = ULTIMATE;
break;
default: default:
break; break;
} }
@ -99,6 +109,9 @@ SerialKeyEdition::getDisplayName() const
case kPro_China: case kPro_China:
DisplayName = "Synergy Pro 中文版"; DisplayName = "Synergy Pro 中文版";
break; break;
case kLite:
DisplayName = "Synergy 1";
break;
default: default:
std::string EditionName = getName(); std::string EditionName = getName();
if (!EditionName.empty()){ if (!EditionName.empty()){
@ -120,6 +133,7 @@ void
SerialKeyEdition::setType(Edition type) SerialKeyEdition::setType(Edition type)
{ {
m_Type = type; m_Type = type;
setType(getName());
} }
void void

View file

@ -43,6 +43,8 @@ public:
static const std::string BASIC_CHINA; static const std::string BASIC_CHINA;
static const std::string BUSINESS; static const std::string BUSINESS;
static const std::string UNREGISTERED; static const std::string UNREGISTERED;
static const std::string ULTIMATE;
static const std::string LITE;
private: private:
Edition m_Type = kUnregistered; Edition m_Type = kUnregistered;

View file

@ -33,6 +33,12 @@ void
SerialKeyParser::setEdition(const std::string& edition) SerialKeyParser::setEdition(const std::string& edition)
{ {
m_data.edition.setType(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 void