Merge changes from v1.8.5
This commit is contained in:
commit
96efe5fb73
|
@ -1,8 +1,7 @@
|
||||||
### Operating Systems ###
|
### Operating Systems ###
|
||||||
|
|
||||||
Client: Applesoft Windy OS 10
|
|
||||||
|
|
||||||
Server: microOS Tiara
|
Server: microOS Tiara
|
||||||
|
Client: Applesoft Windy OS 10
|
||||||
|
|
||||||
**READ ME, DELETE ME**: On Windows, hold the Windows key and press 'r', type 'winver' and hit return to get your OS version. On Mac, hit the Apple menu (top left of the screen) and check 'About this Mac'. Linux users... you know what you're using ;)
|
**READ ME, DELETE ME**: On Windows, hold the Windows key and press 'r', type 'winver' and hit return to get your OS version. On Mac, hit the Apple menu (top left of the screen) and check 'About this Mac'. Linux users... you know what you're using ;)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
config.h
|
config.h
|
||||||
|
.DS_Store
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*.o
|
||||||
*~
|
*~
|
||||||
\.*.swp
|
\.*.swp
|
||||||
|
*build-gui-Desktop_Qt*
|
||||||
/bin
|
/bin
|
||||||
/lib
|
/lib
|
||||||
/build
|
/build
|
||||||
|
|
28
ChangeLog
28
ChangeLog
|
@ -1,16 +1,22 @@
|
||||||
|
v1.8.5-stable
|
||||||
|
=============
|
||||||
|
Bug #5680 - Server crashes when disconnecting SSL clients
|
||||||
|
Bug #5626 - Build fails using Xcode 8 and macOS SDK 10.12
|
||||||
|
Feature #5657 - Trial version support
|
||||||
|
Feature #5707 - User upgrade statistics
|
||||||
|
|
||||||
v1.8.4-stable
|
v1.8.4-stable
|
||||||
=============
|
=============
|
||||||
|
Bug #5183 - Slowly moving the cursor has no effect on high DPI clients
|
||||||
Bug #4041 UHD/4K DPI scaling broken on Windows servers
|
Bug #4041 - UHD/4K DPI scaling broken on Windows servers
|
||||||
Bug #4420 When XRandR adds a screen, it is inaccessible
|
Bug #4420 - When XRandR adds a screen, it is inaccessible
|
||||||
Bug #5603 Activation notification depends on existence of /etc/os-release
|
Bug #5603 - Activation notification depends on existence of /etc/os-release
|
||||||
Bug #5624 Update notification sometimes requests a downgrade
|
Bug #5624 - Update notification sometimes requests a downgrade
|
||||||
Bug #5329 Current date is shown for build date in the about dialog
|
Bug #5329 - Current date is shown for build date in the about dialog
|
||||||
Bug #5640 Synergy branding is inconsistent across platforms
|
Enhancement #5617 - Remove redundant plugin infrastructure
|
||||||
Enhancement #5617 Remove redundant plugin infrastructure
|
Enhancement #5627 - Move SSL certificate generation to main window
|
||||||
Enhancement #5627 Move SSL certificate generation to main window
|
Enhancement #5628 - Move SSL implementation into core binary
|
||||||
Enhancement #5628 Move SSL implementation into core binary
|
Enhancement #5629 - Move activation from wizard into new dialog window
|
||||||
Enhancement #5629 Move activation from wizard into new dialog window
|
|
||||||
|
|
||||||
v1.8.3-stable
|
v1.8.3-stable
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -435,14 +435,16 @@ class InternalCommands:
|
||||||
if generator.cmakeName.find('Unix Makefiles') != -1:
|
if generator.cmakeName.find('Unix Makefiles') != -1:
|
||||||
cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize()
|
cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize()
|
||||||
|
|
||||||
elif sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
macSdkMatch = re.match("(\d+)\.(\d+)", self.macSdk)
|
macSdkMatch = re.match("(\d+)\.(\d+)", self.macSdk)
|
||||||
if not macSdkMatch:
|
if not macSdkMatch:
|
||||||
raise Exception("unknown osx version: " + self.macSdk)
|
raise Exception("unknown osx version: " + self.macSdk)
|
||||||
|
|
||||||
sdkDir = self.getMacSdkDir()
|
if generator.cmakeName.find('Unix Makefiles') == -1:
|
||||||
cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir
|
sdkDir = self.getMacSdkDir()
|
||||||
cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macSdk
|
cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir
|
||||||
|
cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macSdk
|
||||||
|
|
||||||
cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1)
|
cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1)
|
||||||
cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2)
|
cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2)
|
||||||
|
|
||||||
|
@ -558,6 +560,7 @@ class InternalCommands:
|
||||||
if os.path.exists(sdkPath):
|
if os.path.exists(sdkPath):
|
||||||
return sdkPath
|
return sdkPath
|
||||||
|
|
||||||
|
# return os.popen('xcodebuild -version -sdk macosx' + self.macSdk + ' Path').read().strip()
|
||||||
return "/Developer/SDKs/" + sdkDirName + ".sdk"
|
return "/Developer/SDKs/" + sdkDirName + ".sdk"
|
||||||
|
|
||||||
# http://tinyurl.com/cs2rxxb
|
# http://tinyurl.com/cs2rxxb
|
||||||
|
|
BIN
res/synergy.ico
BIN
res/synergy.ico
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 281 KiB |
|
@ -35,7 +35,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(synergyd
|
target_link_libraries(synergyd
|
||||||
arch base common io ipc mt net platform synergy ${libs} ${OPENSSL_LIBS})
|
arch base common io ipc mt net platform synergy shared ${libs} ${OPENSSL_LIBS})
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
|
|
|
@ -7,7 +7,8 @@ DEFINES += VERSION_REVISION=\\\"$$QMAKE_VERSION_REVISION\\\"
|
||||||
DEPENDPATH += . \
|
DEPENDPATH += . \
|
||||||
res
|
res
|
||||||
INCLUDEPATH += . \
|
INCLUDEPATH += . \
|
||||||
src
|
src \
|
||||||
|
../lib/shared/
|
||||||
FORMS += res/MainWindowBase.ui \
|
FORMS += res/MainWindowBase.ui \
|
||||||
res/AboutDialogBase.ui \
|
res/AboutDialogBase.ui \
|
||||||
res/ServerConfigDialogBase.ui \
|
res/ServerConfigDialogBase.ui \
|
||||||
|
@ -60,11 +61,12 @@ SOURCES += src/main.cpp \
|
||||||
src/Fingerprint.cpp \
|
src/Fingerprint.cpp \
|
||||||
src/SslCertificate.cpp \
|
src/SslCertificate.cpp \
|
||||||
src/WebClient.cpp \
|
src/WebClient.cpp \
|
||||||
src/SubscriptionManager.cpp \
|
|
||||||
src/ActivationNotifier.cpp \
|
src/ActivationNotifier.cpp \
|
||||||
src/ActivationDialog.cpp \
|
src/ActivationDialog.cpp \
|
||||||
src/CancelActivationDialog.cpp \
|
src/CancelActivationDialog.cpp \
|
||||||
src/FailedLoginDialog.cpp
|
src/FailedLoginDialog.cpp \
|
||||||
|
../lib/shared/SerialKey.cpp \
|
||||||
|
src/LicenseManager.cpp
|
||||||
HEADERS += src/MainWindow.h \
|
HEADERS += src/MainWindow.h \
|
||||||
src/AboutDialog.h \
|
src/AboutDialog.h \
|
||||||
src/ServerConfig.h \
|
src/ServerConfig.h \
|
||||||
|
@ -101,18 +103,19 @@ HEADERS += src/MainWindow.h \
|
||||||
src/DataDownloader.h \
|
src/DataDownloader.h \
|
||||||
src/AddClientDialog.h \
|
src/AddClientDialog.h \
|
||||||
src/CommandProcess.h \
|
src/CommandProcess.h \
|
||||||
src/EditionType.h \
|
|
||||||
src/ProcessorArch.h \
|
src/ProcessorArch.h \
|
||||||
src/CoreInterface.h \
|
src/CoreInterface.h \
|
||||||
src/Fingerprint.h \
|
src/Fingerprint.h \
|
||||||
src/SslCertificate.h \
|
src/SslCertificate.h \
|
||||||
src/WebClient.h \
|
src/WebClient.h \
|
||||||
src/SubscriptionManager.h \
|
|
||||||
src/ActivationNotifier.h \
|
src/ActivationNotifier.h \
|
||||||
src/ElevateMode.h \
|
src/ElevateMode.h \
|
||||||
src/ActivationDialog.h \
|
src/ActivationDialog.h \
|
||||||
src/CancelActivationDialog.h \
|
src/CancelActivationDialog.h \
|
||||||
src/FailedLoginDialog.h
|
src/FailedLoginDialog.h \
|
||||||
|
../lib/shared/EditionType.h \
|
||||||
|
../lib/shared/SerialKey.h \
|
||||||
|
src/LicenseManager.h
|
||||||
RESOURCES += res/Synergy.qrc
|
RESOURCES += res/Synergy.qrc
|
||||||
RC_FILE = res/win/Synergy.rc
|
RC_FILE = res/win/Synergy.rc
|
||||||
macx {
|
macx {
|
||||||
|
|
|
@ -13,19 +13,25 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>450</width>
|
<width>450</width>
|
||||||
<height>378</height>
|
<height>300</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>450</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>450</width>
|
<width>450</width>
|
||||||
<height>378</height>
|
<height>300</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -35,20 +41,48 @@
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout">
|
<layout class="QGridLayout">
|
||||||
<item row="0" column="1">
|
<item row="2" column="1" colspan="2">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="text">
|
||||||
|
<string><p>
|
||||||
|
Keyboard and mouse sharing application. Cross platform and open source.<br /><br />
|
||||||
|
Copyright © 2012-2016 Symless Ltd.<br />
|
||||||
|
Copyright © 2002-2012 Chris Schoeneman, Nick Bolton, Volker Lanz.<br /><br />
|
||||||
|
Synergy is released under the GNU General Public License (GPLv2).<br /><br />
|
||||||
|
Synergy is based on CosmoSynergy by Richard Lee and Adam Feder.<br />
|
||||||
|
The Synergy GUI is based on QSynergy by Volker Lanz.<br /><br />
|
||||||
|
Visit our website for help and info (symless.com).
|
||||||
|
</p></string>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1" colspan="2">
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Preferred</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>450</width>
|
<width>20</width>
|
||||||
<height>16777215</height>
|
<height>100</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
@ -163,41 +197,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string><html><head/><body><p>Keyboard and mouse sharing application. <br/><br/>Copyright © 2012-2016 Symless Ltd.<br/>Copyright © 2002-2012 Chris Schoeneman, Nick Bolton, Volker Lanz.</p><p>Synergy is based on CosmoSynergy by Richard Lee and Adam Feder.<br/>The Synergy GUI is based on QSynergy by Volker Lanz. </p><p>Synergy is released under the GNU General Public License (GPLv2).</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1" colspan="2">
|
|
||||||
<spacer>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Preferred</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>100</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>440</width>
|
<width>410</width>
|
||||||
<height>314</height>
|
<height>211</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="m_pRadioButtonActivate">
|
<widget class="QLabel" name="label">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
|
@ -23,83 +23,14 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Account login</string>
|
<string>Serial key</string>
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QFormLayout" name="formLayout_2">
|
|
||||||
<property name="fieldGrowthPolicy">
|
|
||||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalSpacing">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalSpacing">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="m_pLabelEmail">
|
|
||||||
<property name="text">
|
|
||||||
<string>Email:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="m_pLineEditEmail">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="echoMode">
|
|
||||||
<enum>QLineEdit::Normal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Password:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="m_pLineEditPassword">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="echoMode">
|
|
||||||
<enum>QLineEdit::Password</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="m_pRadioButtonSubscription">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Serial key</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Found on your <a href="https://symless.com/account/?source=gui">account</a> page.</string>
|
<string><html><head/><body><p>This can be found on your <a href="https://symless.com/account/?source=gui"><span style=" text-decoration: underline; color:#0000ff;">account</span></a> page.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="openExternalLinks">
|
<property name="openExternalLinks">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -109,7 +40,10 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTextEdit" name="m_pTextEditSerialKey">
|
<widget class="QTextEdit" name="m_pTextEditSerialKey">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="tabChangesFocus">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="html">
|
<property name="html">
|
||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
@ -123,6 +57,57 @@ p, li { white-space: pre-wrap; }
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="m_trialWidget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="Synergy.qrc">:/res/icons/16x16/money.png</pixmap>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_trialLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p>Your trial has expired. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -135,7 +120,12 @@ p, li { white-space: pre-wrap; }
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<tabstops>
|
||||||
|
<tabstop>m_pTextEditSerialKey</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources>
|
||||||
|
<include location="Synergy.qrc"/>
|
||||||
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Are you sure?
|
<string>Are you sure?
|
||||||
|
|
||||||
If you don't activate Synergy you'll be missing out on some great features</string>
|
If you don't activate Synergy you'll be missing out on some great features.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
|
@ -27,6 +27,57 @@
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="m_trialWidget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_trialLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-weight:600;">%1</span> days of your Synergy Pro trial remain. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="m_pWidgetUpdate" native="true">
|
<widget class="QWidget" name="m_pWidgetUpdate" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
@ -40,7 +91,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>7</number>
|
<number>8</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="m_pIconUpdate">
|
<widget class="QLabel" name="m_pIconUpdate">
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="m_pTabWidget">
|
<widget class="QTabWidget" name="m_pTabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="m_pTabScreens">
|
<widget class="QWidget" name="m_pTabScreens">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 281 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 4.8 KiB |
|
@ -7,159 +7,116 @@
|
||||||
#include "ActivationNotifier.h"
|
#include "ActivationNotifier.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "QUtility.h"
|
#include "QUtility.h"
|
||||||
#include "SubscriptionManager.h"
|
#include "LicenseManager.h"
|
||||||
#include "FailedLoginDialog.h"
|
#include "FailedLoginDialog.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig) :
|
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig,
|
||||||
|
LicenseManager& licenseManager) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::ActivationDialog),
|
ui(new Ui::ActivationDialog),
|
||||||
m_appConfig (&appConfig)
|
m_appConfig(&appConfig),
|
||||||
|
m_LicenseManager (&licenseManager)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
refreshSerialKey();
|
||||||
ui->m_pLineEditEmail->setText(appConfig.activateEmail());
|
time_t currentTime = ::time(0);
|
||||||
ui->m_pTextEditSerialKey->setText(appConfig.serialKey());
|
if (!m_LicenseManager->serialKey().isExpired(currentTime)) {
|
||||||
|
ui->m_trialWidget->hide();
|
||||||
if (!appConfig.serialKey().isEmpty()) {
|
|
||||||
ui->m_pRadioButtonActivate->setAutoExclusive(false);
|
|
||||||
ui->m_pRadioButtonSubscription->setAutoExclusive(false);
|
|
||||||
ui->m_pRadioButtonActivate->setChecked(false);
|
|
||||||
ui->m_pRadioButtonSubscription->setChecked(true);
|
|
||||||
ui->m_pRadioButtonActivate->setAutoExclusive(true);
|
|
||||||
ui->m_pRadioButtonSubscription->setAutoExclusive(true);
|
|
||||||
ui->m_pTextEditSerialKey->setFocus();
|
|
||||||
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
|
|
||||||
} else {
|
|
||||||
if (ui->m_pLineEditEmail->text().isEmpty()) {
|
|
||||||
ui->m_pLineEditEmail->setFocus();
|
|
||||||
} else {
|
|
||||||
ui->m_pLineEditPassword->setFocus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActivationDialog::refreshSerialKey()
|
||||||
|
{
|
||||||
|
ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey());
|
||||||
|
ui->m_pTextEditSerialKey->setFocus();
|
||||||
|
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
|
||||||
|
ui->m_trialLabel->setText(tr("<html><head/><body><p>Your trial has "
|
||||||
|
"expired. <a href=\"https://symless.com/"
|
||||||
|
"synergy/trial/thanks?id=%1\"><span "
|
||||||
|
"style=\"text-decoration: underline; "
|
||||||
|
"color:#0000ff;\">Buy now!</span></a>"
|
||||||
|
"</p></body></html>")
|
||||||
|
.arg (m_appConfig->serialKey()));
|
||||||
|
}
|
||||||
|
|
||||||
ActivationDialog::~ActivationDialog()
|
ActivationDialog::~ActivationDialog()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivationDialog::notifyActivation(QString identity)
|
|
||||||
{
|
|
||||||
ActivationNotifier* notifier = new ActivationNotifier();
|
|
||||||
notifier->setIdentity(identity);
|
|
||||||
|
|
||||||
QThread* thread = new QThread();
|
|
||||||
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
|
|
||||||
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
|
|
||||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
|
||||||
|
|
||||||
notifier->moveToThread(thread);
|
|
||||||
thread->start();
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivationDialog::reject()
|
void ActivationDialog::reject()
|
||||||
{
|
{
|
||||||
CancelActivationDialog cancelActivationDialog(this);
|
if (m_LicenseManager->activeEdition() == kUnregistered) {
|
||||||
if (QDialog::Accepted == cancelActivationDialog.exec()) {
|
CancelActivationDialog cancelActivationDialog(this);
|
||||||
notifyActivation("skip:unknown");
|
if (QDialog::Accepted == cancelActivationDialog.exec()) {
|
||||||
m_appConfig->activationHasRun(true);
|
m_LicenseManager->skipActivation();
|
||||||
m_appConfig->saveSettings();
|
m_appConfig->activationHasRun(true);
|
||||||
QDialog::reject();
|
m_appConfig->saveSettings();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivationDialog::on_m_pRadioButtonSubscription_toggled(bool checked)
|
|
||||||
{
|
|
||||||
if (checked) {
|
|
||||||
ui->m_pLineEditEmail->setEnabled(false);
|
|
||||||
ui->m_pLineEditPassword->setEnabled(false);
|
|
||||||
ui->m_pTextEditSerialKey->setEnabled(true);
|
|
||||||
ui->m_pTextEditSerialKey->setFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivationDialog::on_m_pRadioButtonActivate_toggled(bool checked)
|
|
||||||
{
|
|
||||||
if (checked) {
|
|
||||||
ui->m_pLineEditEmail->setEnabled(true);
|
|
||||||
ui->m_pLineEditPassword->setEnabled(true);
|
|
||||||
ui->m_pTextEditSerialKey->setEnabled(false);
|
|
||||||
if (ui->m_pLineEditEmail->text().isEmpty()) {
|
|
||||||
ui->m_pLineEditEmail->setFocus();
|
|
||||||
} else {
|
} else {
|
||||||
ui->m_pLineEditPassword->setFocus();
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QDialog::reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivationDialog::accept()
|
void ActivationDialog::accept()
|
||||||
{
|
{
|
||||||
QMessageBox message;
|
QMessageBox message;
|
||||||
QString error;
|
|
||||||
int edition = Unregistered;
|
|
||||||
|
|
||||||
m_appConfig->activationHasRun(true);
|
m_appConfig->activationHasRun(true);
|
||||||
m_appConfig->saveSettings();
|
m_appConfig->saveSettings();
|
||||||
|
|
||||||
|
std::pair<bool, QString> result;
|
||||||
try {
|
try {
|
||||||
if (ui->m_pRadioButtonActivate->isChecked()) {
|
QString serialKey = ui->m_pTextEditSerialKey->toPlainText().trimmed();
|
||||||
WebClient webClient;
|
result = m_LicenseManager->setSerialKey(serialKey);
|
||||||
QString email = ui->m_pLineEditEmail->text();
|
|
||||||
QString password = ui->m_pLineEditPassword->text();
|
|
||||||
|
|
||||||
if (!webClient.setEmail (email, error)) {
|
|
||||||
message.critical (this, "Invalid Email Address", tr("%1").arg(error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!webClient.setPassword (password, error)) {
|
|
||||||
message.critical (this, "Invalid Password", tr("%1").arg(error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!webClient.getEdition (edition, error)) {
|
|
||||||
FailedLoginDialog failedLoginDialog (this, error);
|
|
||||||
failedLoginDialog.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_appConfig->setActivateEmail (email);
|
|
||||||
m_appConfig->clearSerialKey();
|
|
||||||
ui->m_pTextEditSerialKey->clear();
|
|
||||||
notifyActivation ("login:" + m_appConfig->activateEmail());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
|
|
||||||
|
|
||||||
if (!m_appConfig->setSerialKey (serialKey, error)) {
|
|
||||||
message.critical (this, "Invalid Serial Key", tr("%1").arg(error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SubscriptionManager subscriptionManager (this, *m_appConfig, edition);
|
|
||||||
if (!subscriptionManager.activateSerial (serialKey)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_appConfig->setActivateEmail("");
|
|
||||||
notifyActivation ("serial:" + m_appConfig->serialKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
message.critical (this, "Unknown Error",
|
message.critical(this, "Unknown Error",
|
||||||
tr("An error occurred while trying to activate Synergy. "
|
tr("An error occurred while trying to activate Synergy. "
|
||||||
"Please contact the helpdesk, and provide the "
|
"Please contact the helpdesk, and provide the "
|
||||||
"following details.\n\n%1").arg(e.what()));
|
"following information:\n\n%1").arg(e.what()));
|
||||||
|
refreshSerialKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_appConfig->setEdition(edition);
|
if (!result.first) {
|
||||||
m_appConfig->saveSettings();
|
message.critical(this, "Activation failed",
|
||||||
|
tr("%1").arg(result.second));
|
||||||
|
refreshSerialKey();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LicenseManager->notifyActivation("serial:" + m_appConfig->serialKey());
|
||||||
|
Edition edition = m_LicenseManager->activeEdition();
|
||||||
|
time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
|
||||||
|
if (edition != kUnregistered) {
|
||||||
|
QString thanksMessage = tr("Thanks for trying %1! %5\n\n%2 day%3 of "
|
||||||
|
"your trial remain%4").
|
||||||
|
arg (m_LicenseManager->getEditionName(edition)).
|
||||||
|
arg (daysLeft).
|
||||||
|
arg ((daysLeft == 1) ? "" : "s").
|
||||||
|
arg ((daysLeft == 1) ? "s" : "");
|
||||||
|
|
||||||
|
if (edition == kPro) {
|
||||||
|
thanksMessage = thanksMessage.arg("If you're using SSL, "
|
||||||
|
"remember to activate all of your devices.");
|
||||||
|
} else {
|
||||||
|
thanksMessage = thanksMessage.arg("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_LicenseManager->serialKey().isTrial()) {
|
||||||
|
message.information(this, "Thanks!", thanksMessage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message.information(this, "Activated!",
|
||||||
|
tr("Thanks for activating %1!").arg
|
||||||
|
(m_LicenseManager->getEditionName(edition)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message.information (this, "Activated!",
|
|
||||||
tr("Thanks for activating %1!").arg (getEditionName (edition)));
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define ACTIVATIONDIALOG_H
|
#define ACTIVATIONDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <LicenseManager.h>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ActivationDialog;
|
class ActivationDialog;
|
||||||
|
@ -14,7 +15,8 @@ class ActivationDialog : public QDialog
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ActivationDialog(QWidget *parent, AppConfig& appConfig);
|
ActivationDialog(QWidget *parent, AppConfig& appConfig,
|
||||||
|
LicenseManager& licenseManager);
|
||||||
~ActivationDialog();
|
~ActivationDialog();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -22,15 +24,12 @@ public slots:
|
||||||
void accept();
|
void accept();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void notifyActivation (QString identity);
|
void refreshSerialKey();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ActivationDialog *ui;
|
Ui::ActivationDialog *ui;
|
||||||
AppConfig* m_appConfig;
|
AppConfig* m_appConfig;
|
||||||
|
LicenseManager* m_LicenseManager;
|
||||||
private slots:
|
|
||||||
void on_m_pRadioButtonSubscription_toggled(bool checked);
|
|
||||||
void on_m_pRadioButtonActivate_toggled(bool checked);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ACTIVATIONDIALOG_H
|
#endif // ACTIVATIONDIALOG_H
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "CoreInterface.h"
|
#include "CoreInterface.h"
|
||||||
|
|
||||||
ActivationNotifier::ActivationNotifier(QObject *parent) :
|
ActivationNotifier::ActivationNotifier(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,15 @@ void ActivationNotifier::setIdentity(QString identity)
|
||||||
m_Identity = identity;
|
m_Identity = identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActivationNotifier::setUpdateInfo(QString const& fromVersion,
|
||||||
|
QString const& toVersion,
|
||||||
|
QString const& serialKey)
|
||||||
|
{
|
||||||
|
m_fromVersion = fromVersion;
|
||||||
|
m_toVersion = toVersion;
|
||||||
|
m_serialKey = serialKey;
|
||||||
|
}
|
||||||
|
|
||||||
void ActivationNotifier::notify()
|
void ActivationNotifier::notify()
|
||||||
{
|
{
|
||||||
CoreInterface coreInterface;
|
CoreInterface coreInterface;
|
||||||
|
@ -39,3 +48,13 @@ void ActivationNotifier::notify()
|
||||||
// catch all exceptions and fails silently
|
// catch all exceptions and fails silently
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActivationNotifier::notifyUpdate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
CoreInterface coreInterface;
|
||||||
|
coreInterface.notifyUpdate(m_fromVersion, m_toVersion,
|
||||||
|
m_serialKey);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,18 +24,24 @@ class ActivationNotifier : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ActivationNotifier(QObject *parent = 0);
|
explicit ActivationNotifier(QObject *parent = 0);
|
||||||
|
|
||||||
void setIdentity(QString identity);
|
void setIdentity(QString identity);
|
||||||
|
void setUpdateInfo(QString const& fromVersion,
|
||||||
|
QString const& toVersion, QString const& serialKey);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void notify();
|
void notify();
|
||||||
|
void notifyUpdate();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_Identity;
|
QString m_Identity;
|
||||||
|
QString m_fromVersion;
|
||||||
|
QString m_toVersion;
|
||||||
|
QString m_serialKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ACTIVATIONNOTIFIER_H
|
#endif // ACTIVATIONNOTIFIER_H
|
||||||
|
|
|
@ -153,15 +153,16 @@ void AppConfig::loadSettings()
|
||||||
QVariant elevateMode = settings().value("elevateModeEnum");
|
QVariant elevateMode = settings().value("elevateModeEnum");
|
||||||
if (!elevateMode.isValid()) {
|
if (!elevateMode.isValid()) {
|
||||||
elevateMode = settings().value ("elevateMode",
|
elevateMode = settings().value ("elevateMode",
|
||||||
QVariant(static_cast<int>(defaultElevateMode)));
|
QVariant(static_cast<int>(defaultElevateMode)));
|
||||||
}
|
}
|
||||||
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
||||||
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
|
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
|
||||||
m_Edition = settings().value("edition", Unregistered).toInt();
|
m_Edition = static_cast<Edition>(settings().value("edition", kUnregistered).toInt());
|
||||||
m_ActivateEmail = settings().value("activateEmail", "").toString();
|
m_ActivateEmail = settings().value("activateEmail", "").toString();
|
||||||
m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool();
|
m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool();
|
||||||
m_AutoHide = settings().value("autoHide", false).toBool();
|
m_AutoHide = settings().value("autoHide", false).toBool();
|
||||||
m_Serialkey = settings().value("serialKey", "").toString();
|
m_Serialkey = settings().value("serialKey", "").toString();
|
||||||
|
m_lastVersion = settings().value("lastVersion", "Unknown").toString();
|
||||||
m_LastExpiringWarningTime = settings().value("lastExpiringWarningTime", 0).toInt();
|
m_LastExpiringWarningTime = settings().value("lastExpiringWarningTime", 0).toInt();
|
||||||
m_ActivationHasRun = settings().value("activationHasRun", false).toBool();
|
m_ActivationHasRun = settings().value("activationHasRun", false).toBool();
|
||||||
}
|
}
|
||||||
|
@ -178,16 +179,16 @@ void AppConfig::saveSettings()
|
||||||
settings().setValue("language", m_Language);
|
settings().setValue("language", m_Language);
|
||||||
settings().setValue("startedBefore", m_StartedBefore);
|
settings().setValue("startedBefore", m_StartedBefore);
|
||||||
settings().setValue("autoConfig", m_AutoConfig);
|
settings().setValue("autoConfig", m_AutoConfig);
|
||||||
// Refer to enum ElevateMode declaration for insight in to why this
|
// Refer to enum ElevateMode declaration for insight in to why this
|
||||||
// flag is mapped this way
|
// flag is mapped this way
|
||||||
settings().setValue("elevateMode", m_ElevateMode == ElevateAlways);
|
settings().setValue("elevateMode", m_ElevateMode == ElevateAlways);
|
||||||
settings().setValue("elevateModeEnum", static_cast<int>(m_ElevateMode));
|
settings().setValue("elevateModeEnum", static_cast<int>(m_ElevateMode));
|
||||||
settings().setValue("autoConfigPrompted", m_AutoConfigPrompted);
|
settings().setValue("autoConfigPrompted", m_AutoConfigPrompted);
|
||||||
settings().setValue("edition", m_Edition);
|
settings().setValue("edition", m_Edition);
|
||||||
settings().setValue("activateEmail", m_ActivateEmail);
|
|
||||||
settings().setValue("cryptoEnabled", m_CryptoEnabled);
|
settings().setValue("cryptoEnabled", m_CryptoEnabled);
|
||||||
settings().setValue("autoHide", m_AutoHide);
|
settings().setValue("autoHide", m_AutoHide);
|
||||||
settings().setValue("serialKey", m_Serialkey);
|
settings().setValue("serialKey", m_Serialkey);
|
||||||
|
settings().setValue("lastVersion", m_lastVersion);
|
||||||
settings().setValue("lastExpiringWarningTime", m_LastExpiringWarningTime);
|
settings().setValue("lastExpiringWarningTime", m_LastExpiringWarningTime);
|
||||||
settings().setValue("activationHasRun", m_ActivationHasRun);
|
settings().setValue("activationHasRun", m_ActivationHasRun);
|
||||||
settings().sync();
|
settings().sync();
|
||||||
|
@ -204,6 +205,15 @@ AppConfig& AppConfig::activationHasRun(bool value)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString AppConfig::lastVersion() const
|
||||||
|
{
|
||||||
|
return m_lastVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppConfig::setLastVersion(QString version) {
|
||||||
|
m_lastVersion = version;
|
||||||
|
}
|
||||||
|
|
||||||
QSettings &AppConfig::settings() { return *m_pSettings; }
|
QSettings &AppConfig::settings() { return *m_pSettings; }
|
||||||
|
|
||||||
void AppConfig::setScreenName(const QString &s) { m_ScreenName = s; }
|
void AppConfig::setScreenName(const QString &s) { m_ScreenName = s; }
|
||||||
|
@ -238,27 +248,16 @@ void AppConfig::setAutoConfigPrompted(bool prompted)
|
||||||
m_AutoConfigPrompted = prompted;
|
m_AutoConfigPrompted = prompted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setEdition(int e) {
|
void AppConfig::setEdition(Edition e) {
|
||||||
m_Edition = e;
|
m_Edition = e;
|
||||||
emit editionSet (e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AppConfig::edition() const { return m_Edition; }
|
Edition AppConfig::edition() const { return m_Edition; }
|
||||||
|
|
||||||
bool AppConfig::setActivateEmail(QString e) {
|
QString AppConfig::setSerialKey(QString serial) {
|
||||||
m_ActivateEmail = e;
|
using std::swap;
|
||||||
return true;
|
swap (serial, m_Serialkey);
|
||||||
}
|
return serial;
|
||||||
|
|
||||||
QString AppConfig::activateEmail() { return m_ActivateEmail; }
|
|
||||||
|
|
||||||
bool AppConfig::setSerialKey(QString serial, QString& errorOut) {
|
|
||||||
if (serial.isEmpty()) {
|
|
||||||
errorOut = "Your serial key cannot be blank.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_Serialkey = serial;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::clearSerialKey()
|
void AppConfig::clearSerialKey()
|
||||||
|
@ -287,7 +286,7 @@ void AppConfig::setCryptoEnabled(bool e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppConfig::getCryptoEnabled() const {
|
bool AppConfig::getCryptoEnabled() const {
|
||||||
return (edition() == Pro) && m_CryptoEnabled;
|
return (edition() == kPro) && m_CryptoEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setAutoHide(bool b) { m_AutoHide = b; }
|
void AppConfig::setAutoHide(bool b) { m_AutoHide = b; }
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "ElevateMode.h"
|
#include "ElevateMode.h"
|
||||||
|
#include <EditionType.h>
|
||||||
|
|
||||||
// this should be incremented each time a new page is added. this is
|
// this should be incremented each time a new page is added. this is
|
||||||
// saved to settings when the user finishes running the wizard. if
|
// saved to settings when the user finishes running the wizard. if
|
||||||
|
@ -78,11 +79,9 @@ class AppConfig: public QObject
|
||||||
void setAutoConfig(bool autoConfig);
|
void setAutoConfig(bool autoConfig);
|
||||||
bool autoConfigPrompted();
|
bool autoConfigPrompted();
|
||||||
void setAutoConfigPrompted(bool prompted);
|
void setAutoConfigPrompted(bool prompted);
|
||||||
void setEdition(int e);
|
void setEdition(Edition);
|
||||||
int edition() const;
|
Edition edition() const;
|
||||||
bool setActivateEmail(QString e);
|
QString setSerialKey(QString serial);
|
||||||
QString activateEmail();
|
|
||||||
bool setSerialKey(QString serial, QString& error);
|
|
||||||
void clearSerialKey();
|
void clearSerialKey();
|
||||||
QString serialKey();
|
QString serialKey();
|
||||||
int lastExpiringWarningTime() const;
|
int lastExpiringWarningTime() const;
|
||||||
|
@ -106,9 +105,12 @@ class AppConfig: public QObject
|
||||||
bool activationHasRun() const;
|
bool activationHasRun() const;
|
||||||
AppConfig& activationHasRun(bool value);
|
AppConfig& activationHasRun(bool value);
|
||||||
|
|
||||||
void saveSettings();
|
QString lastVersion() const;
|
||||||
|
|
||||||
protected:
|
void saveSettings();
|
||||||
|
void setLastVersion(QString version);
|
||||||
|
|
||||||
|
protected:
|
||||||
QSettings& settings();
|
QSettings& settings();
|
||||||
void setScreenName(const QString& s);
|
void setScreenName(const QString& s);
|
||||||
void setPort(int i);
|
void setPort(int i);
|
||||||
|
@ -137,11 +139,12 @@ class AppConfig: public QObject
|
||||||
bool m_AutoConfig;
|
bool m_AutoConfig;
|
||||||
ElevateMode m_ElevateMode;
|
ElevateMode m_ElevateMode;
|
||||||
bool m_AutoConfigPrompted;
|
bool m_AutoConfigPrompted;
|
||||||
int m_Edition;
|
Edition m_Edition;
|
||||||
QString m_ActivateEmail;
|
QString m_ActivateEmail;
|
||||||
bool m_CryptoEnabled;
|
bool m_CryptoEnabled;
|
||||||
bool m_AutoHide;
|
bool m_AutoHide;
|
||||||
QString m_Serialkey;
|
QString m_Serialkey;
|
||||||
|
QString m_lastVersion;
|
||||||
int m_LastExpiringWarningTime;
|
int m_LastExpiringWarningTime;
|
||||||
bool m_ActivationHasRun;
|
bool m_ActivationHasRun;
|
||||||
|
|
||||||
|
@ -150,7 +153,6 @@ class AppConfig: public QObject
|
||||||
static const char m_SynergyLogDir[];
|
static const char m_SynergyLogDir[];
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void editionSet(int);
|
|
||||||
void sslToggled(bool enabled);
|
void sslToggled(bool enabled);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,20 +22,22 @@
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QDir>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
static const char kCoreBinary[] = "syntool";
|
static const char kCoreBinary[] = "syntool";
|
||||||
|
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
static const char kSerialKeyFilename[] = "Synergy.subkey";
|
||||||
|
#else
|
||||||
|
static const char kSerialKeyFilename[] = ".synergy.subkey";
|
||||||
|
#endif
|
||||||
|
|
||||||
CoreInterface::CoreInterface()
|
CoreInterface::CoreInterface()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CoreInterface::getPluginDir()
|
|
||||||
{
|
|
||||||
QStringList args("--get-plugin-dir");
|
|
||||||
return run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::getProfileDir()
|
QString CoreInterface::getProfileDir()
|
||||||
{
|
{
|
||||||
QStringList args("--get-profile-dir");
|
QStringList args("--get-profile-dir");
|
||||||
|
@ -54,24 +56,19 @@ QString CoreInterface::getArch()
|
||||||
return run(args);
|
return run(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CoreInterface::getSubscriptionFilename()
|
QString CoreInterface::getSerialKeyFilePath()
|
||||||
{
|
{
|
||||||
QStringList args("--get-subscription-filename");
|
QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
|
||||||
return run(args);
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CoreInterface::activateSerial(const QString& serial)
|
QString CoreInterface::notifyUpdate (QString const& fromVersion,
|
||||||
{
|
QString const& toVersion,
|
||||||
QStringList args("--subscription-serial");
|
QString const& serialKey) {
|
||||||
args << serial;
|
QStringList args("--notify-update");
|
||||||
|
QString input(fromVersion + ":" + toVersion + ":" + serialKey);
|
||||||
return run(args);
|
input.append("\n");
|
||||||
}
|
return run(args, input);
|
||||||
|
|
||||||
QString CoreInterface::checkSubscription()
|
|
||||||
{
|
|
||||||
QStringList args("--check-subscription");
|
|
||||||
return run(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CoreInterface::notifyActivation(const QString& identity)
|
QString CoreInterface::notifyActivation(const QString& identity)
|
||||||
|
|
|
@ -24,13 +24,13 @@ class CoreInterface
|
||||||
public:
|
public:
|
||||||
CoreInterface();
|
CoreInterface();
|
||||||
|
|
||||||
QString getPluginDir();
|
|
||||||
QString getProfileDir();
|
QString getProfileDir();
|
||||||
QString getInstalledDir();
|
QString getInstalledDir();
|
||||||
QString getArch();
|
QString getArch();
|
||||||
QString getSubscriptionFilename();
|
QString getSerialKeyFilePath();
|
||||||
QString activateSerial(const QString& serial);
|
|
||||||
QString checkSubscription();
|
|
||||||
QString notifyActivation(const QString& identity);
|
QString notifyActivation(const QString& identity);
|
||||||
|
QString notifyUpdate (QString const& fromVersion,
|
||||||
|
QString const& toVersion,
|
||||||
|
QString const& serialKey);
|
||||||
QString run(const QStringList& args, const QString& input = "");
|
QString run(const QStringList& args, const QString& input = "");
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2015 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 "LicenseManager.h"
|
||||||
|
#include "EditionType.h"
|
||||||
|
#include "AppConfig.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
LicenseManager::LicenseManager(AppConfig* appConfig) :
|
||||||
|
m_AppConfig(appConfig),
|
||||||
|
m_serialKey(appConfig->edition()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, QString>
|
||||||
|
LicenseManager::setSerialKey(QString serialKeyString, bool acceptExpired)
|
||||||
|
{
|
||||||
|
std::pair<bool, QString> ret (true, "");
|
||||||
|
time_t currentTime = ::time(0);
|
||||||
|
SerialKey serialKey (serialKeyString.toStdString());
|
||||||
|
|
||||||
|
if (!acceptExpired && serialKey.isExpired(currentTime)) {
|
||||||
|
ret.first = false;
|
||||||
|
ret.second = "Serial key expired";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serialKey != m_serialKey) {
|
||||||
|
using std::swap;
|
||||||
|
swap (serialKey, m_serialKey);
|
||||||
|
m_AppConfig->setSerialKey(serialKeyString);
|
||||||
|
emit serialKeyChanged(m_serialKey);
|
||||||
|
|
||||||
|
if (serialKey.isTrial()) {
|
||||||
|
emit endTrial(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_serialKey.edition() != serialKey.edition()) {
|
||||||
|
m_AppConfig->setEdition(m_serialKey.edition());
|
||||||
|
emit editionChanged(m_serialKey.edition());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_serialKey.isTrial()) {
|
||||||
|
if (m_serialKey.isExpired(currentTime)) {
|
||||||
|
emit endTrial(true);
|
||||||
|
} else {
|
||||||
|
emit beginTrial(m_serialKey.isExpiring(currentTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AppConfig->saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LicenseManager::notifyUpdate(QString fromVersion, QString toVersion) {
|
||||||
|
if ((fromVersion == "Unknown")
|
||||||
|
&& (m_serialKey == SerialKey(kUnregistered))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivationNotifier* notifier = new ActivationNotifier();
|
||||||
|
notifier->setUpdateInfo (fromVersion, toVersion,
|
||||||
|
QString::fromStdString(m_serialKey.toString()));
|
||||||
|
|
||||||
|
QThread* thread = new QThread();
|
||||||
|
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
|
||||||
|
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
|
||||||
|
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
notifier->moveToThread(thread);
|
||||||
|
thread->start();
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(notifier, "notifyUpdate",
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Edition
|
||||||
|
LicenseManager::activeEdition() const
|
||||||
|
{
|
||||||
|
return m_serialKey.edition();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
LicenseManager::activeEditionName() const
|
||||||
|
{
|
||||||
|
return getEditionName(activeEdition(), m_serialKey.isTrial());
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialKey
|
||||||
|
LicenseManager::serialKey() const
|
||||||
|
{
|
||||||
|
return m_serialKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LicenseManager::refresh()
|
||||||
|
{
|
||||||
|
if (!m_AppConfig->serialKey().isEmpty()) {
|
||||||
|
setSerialKey(m_AppConfig->serialKey(), true);
|
||||||
|
}
|
||||||
|
if (m_serialKey.isExpired(::time(0))) {
|
||||||
|
emit endTrial(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LicenseManager::skipActivation()
|
||||||
|
{
|
||||||
|
notifyActivation ("skip:unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
LicenseManager::getEditionName(Edition const edition, bool trial)
|
||||||
|
{
|
||||||
|
std::string name ("Synergy");
|
||||||
|
switch (edition) {
|
||||||
|
case kUnregistered:
|
||||||
|
name += " (UNREGISTERED)";
|
||||||
|
return QString::fromUtf8 (name.c_str(), name.size());
|
||||||
|
case kBasic:
|
||||||
|
name += " Basic";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
name += " Pro";
|
||||||
|
}
|
||||||
|
if (trial) {
|
||||||
|
name += " (Trial)";
|
||||||
|
}
|
||||||
|
return QString::fromUtf8 (name.c_str(), name.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LicenseManager::notifyActivation(QString identity)
|
||||||
|
{
|
||||||
|
ActivationNotifier* notifier = new ActivationNotifier();
|
||||||
|
notifier->setIdentity(identity);
|
||||||
|
|
||||||
|
QThread* thread = new QThread();
|
||||||
|
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
|
||||||
|
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
|
||||||
|
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
notifier->moveToThread(thread);
|
||||||
|
thread->start();
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2015 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 <SerialKey.h>
|
||||||
|
#include <ActivationNotifier.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
class AppConfig;
|
||||||
|
|
||||||
|
class LicenseManager: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
LicenseManager(AppConfig* appConfig);
|
||||||
|
std::pair<bool, QString> setSerialKey(QString serialKey, bool acceptExpired = false);
|
||||||
|
void refresh();
|
||||||
|
Edition activeEdition() const;
|
||||||
|
QString activeEditionName() const;
|
||||||
|
SerialKey serialKey() const;
|
||||||
|
void skipActivation();
|
||||||
|
void notifyUpdate(QString fromVersion, QString toVersion);
|
||||||
|
static QString getEditionName(Edition edition, bool trial = false);
|
||||||
|
void notifyActivation(QString identity);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AppConfig* m_AppConfig;
|
||||||
|
SerialKey m_serialKey;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void serialKeyChanged (SerialKey) const;
|
||||||
|
void editionChanged (Edition) const;
|
||||||
|
void beginTrial (bool expiring) const;
|
||||||
|
void endTrial (bool expired) const;
|
||||||
|
};
|
|
@ -30,7 +30,7 @@
|
||||||
#include "ZeroconfService.h"
|
#include "ZeroconfService.h"
|
||||||
#include "DataDownloader.h"
|
#include "DataDownloader.h"
|
||||||
#include "CommandProcess.h"
|
#include "CommandProcess.h"
|
||||||
#include "SubscriptionManager.h"
|
#include "LicenseManager.h"
|
||||||
#include "EditionType.h"
|
#include "EditionType.h"
|
||||||
#include "QUtility.h"
|
#include "QUtility.h"
|
||||||
#include "ProcessorArch.h"
|
#include "ProcessorArch.h"
|
||||||
|
@ -76,12 +76,14 @@ static const char* synergyIconFiles[] =
|
||||||
":/res/icons/16x16/synergy-transfering.png"
|
":/res/icons/16x16/synergy-transfering.png"
|
||||||
};
|
};
|
||||||
|
|
||||||
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||||
|
LicenseManager& licenseManager) :
|
||||||
m_Settings(settings),
|
m_Settings(settings),
|
||||||
m_AppConfig(appConfig),
|
m_AppConfig(&appConfig),
|
||||||
|
m_LicenseManager(&licenseManager),
|
||||||
m_pSynergy(NULL),
|
m_pSynergy(NULL),
|
||||||
m_SynergyState(synergyDisconnected),
|
m_SynergyState(synergyDisconnected),
|
||||||
m_ServerConfig(&m_Settings, 5, 3, m_AppConfig.screenName(), this),
|
m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this),
|
||||||
m_pTempConfigFile(NULL),
|
m_pTempConfigFile(NULL),
|
||||||
m_pTrayIcon(NULL),
|
m_pTrayIcon(NULL),
|
||||||
m_pTrayIconMenu(NULL),
|
m_pTrayIconMenu(NULL),
|
||||||
|
@ -99,7 +101,8 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
||||||
m_BonjourInstall(NULL),
|
m_BonjourInstall(NULL),
|
||||||
m_SuppressEmptyServerWarning(false),
|
m_SuppressEmptyServerWarning(false),
|
||||||
m_ExpectedRunningState(kStopped),
|
m_ExpectedRunningState(kStopped),
|
||||||
m_pSslCertificate(NULL)
|
m_pSslCertificate(NULL),
|
||||||
|
m_ActivationDialogRunning(false)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
|
@ -134,13 +137,34 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
||||||
m_SuppressAutoConfigWarning = false;
|
m_SuppressAutoConfigWarning = false;
|
||||||
|
|
||||||
m_pComboServerList->hide();
|
m_pComboServerList->hide();
|
||||||
|
|
||||||
setEdition(m_AppConfig.edition());
|
|
||||||
|
|
||||||
m_pLabelPadlock->hide();
|
m_pLabelPadlock->hide();
|
||||||
connect (this, SIGNAL(windowShown()), this, SLOT(on_windowShown()), Qt::QueuedConnection);
|
m_trialWidget->hide();
|
||||||
connect (&m_AppConfig, SIGNAL(editionSet(int)), this, SLOT(setEdition(int)), Qt::QueuedConnection);
|
|
||||||
connect (&m_AppConfig, SIGNAL(sslToggled(bool)), this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
|
connect (this, SIGNAL(windowShown()),
|
||||||
|
this, SLOT(on_windowShown()), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect (m_LicenseManager, SIGNAL(editionChanged(Edition)),
|
||||||
|
this, SLOT(setEdition(Edition)), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect (m_LicenseManager, SIGNAL(beginTrial(bool)),
|
||||||
|
this, SLOT(beginTrial(bool)), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect (m_LicenseManager, SIGNAL(endTrial(bool)),
|
||||||
|
this, SLOT(endTrial(bool)), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect (m_AppConfig, SIGNAL(sslToggled(bool)),
|
||||||
|
this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
setWindowTitle (m_LicenseManager->activeEditionName());
|
||||||
|
m_LicenseManager->refresh();
|
||||||
|
|
||||||
|
QString lastVersion = m_AppConfig->lastVersion();
|
||||||
|
QString currentVersion = m_VersionChecker.getVersion();
|
||||||
|
if (lastVersion != currentVersion) {
|
||||||
|
m_AppConfig->setLastVersion (currentVersion);
|
||||||
|
m_AppConfig->saveSettings();
|
||||||
|
m_LicenseManager->notifyUpdate (lastVersion, currentVersion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
@ -397,15 +421,17 @@ void MainWindow::appendLogRaw(const QString& text)
|
||||||
foreach(QString line, text.split(QRegExp("\r|\n|\r\n"))) {
|
foreach(QString line, text.split(QRegExp("\r|\n|\r\n"))) {
|
||||||
if (!line.isEmpty()) {
|
if (!line.isEmpty()) {
|
||||||
m_pLogOutput->append(line);
|
m_pLogOutput->append(line);
|
||||||
updateStateFromLogLine(line);
|
updateFromLogLine(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateStateFromLogLine(const QString &line)
|
void MainWindow::updateFromLogLine(const QString &line)
|
||||||
{
|
{
|
||||||
|
// TODO: this code makes Andrew cry
|
||||||
checkConnected(line);
|
checkConnected(line);
|
||||||
checkFingerprint(line);
|
checkFingerprint(line);
|
||||||
|
checkLicense(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::checkConnected(const QString& line)
|
void MainWindow::checkConnected(const QString& line)
|
||||||
|
@ -430,6 +456,14 @@ void MainWindow::checkConnected(const QString& line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::checkLicense(const QString &line)
|
||||||
|
{
|
||||||
|
if (line.contains("trial has expired")) {
|
||||||
|
licenseManager().refresh();
|
||||||
|
raiseActivationDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::checkFingerprint(const QString& line)
|
void MainWindow::checkFingerprint(const QString& line)
|
||||||
{
|
{
|
||||||
QRegExp fingerprintRegex(".*server fingerprint: ([A-F0-9:]+)");
|
QRegExp fingerprintRegex(".*server fingerprint: ([A-F0-9:]+)");
|
||||||
|
@ -498,7 +532,7 @@ void MainWindow::restartSynergy()
|
||||||
|
|
||||||
void MainWindow::proofreadInfo()
|
void MainWindow::proofreadInfo()
|
||||||
{
|
{
|
||||||
setEdition(m_AppConfig.edition()); // Why is this here?
|
setEdition(m_AppConfig->edition()); // Why is this here?
|
||||||
|
|
||||||
int oldState = m_SynergyState;
|
int oldState = m_SynergyState;
|
||||||
m_SynergyState = synergyDisconnected;
|
m_SynergyState = synergyDisconnected;
|
||||||
|
@ -518,6 +552,14 @@ void MainWindow::clearLog()
|
||||||
|
|
||||||
void MainWindow::startSynergy()
|
void MainWindow::startSynergy()
|
||||||
{
|
{
|
||||||
|
SerialKey serialKey = m_LicenseManager->serialKey();
|
||||||
|
time_t currentTime = ::time(0);
|
||||||
|
if (serialKey.isExpired(currentTime)) {
|
||||||
|
if (QDialog::Rejected == raiseActivationDialog()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool desktopMode = appConfig().processMode() == Desktop;
|
bool desktopMode = appConfig().processMode() == Desktop;
|
||||||
bool serviceMode = appConfig().processMode() == Service;
|
bool serviceMode = appConfig().processMode() == Service;
|
||||||
|
|
||||||
|
@ -566,7 +608,7 @@ void MainWindow::startSynergy()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_AppConfig.getCryptoEnabled()) {
|
if (m_AppConfig->getCryptoEnabled()) {
|
||||||
args << "--enable-crypto";
|
args << "--enable-crypto";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,19 +776,6 @@ QString MainWindow::appPath(const QString& name)
|
||||||
|
|
||||||
bool MainWindow::serverArgs(QStringList& args, QString& app)
|
bool MainWindow::serverArgs(QStringList& args, QString& app)
|
||||||
{
|
{
|
||||||
int edition;
|
|
||||||
SubscriptionManager subscriptionManager(this, appConfig(), edition);
|
|
||||||
if (subscriptionManager.fileExists())
|
|
||||||
{
|
|
||||||
if (!subscriptionManager.checkSubscription()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setEdition(edition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
app = appPath(appConfig().synergysName());
|
app = appPath(appConfig().synergysName());
|
||||||
|
|
||||||
if (!QFile::exists(app))
|
if (!QFile::exists(app))
|
||||||
|
@ -775,6 +804,10 @@ bool MainWindow::serverArgs(QStringList& args, QString& app)
|
||||||
#endif
|
#endif
|
||||||
args << "-c" << configFilename << "--address" << address();
|
args << "-c" << configFilename << "--address" << address();
|
||||||
|
|
||||||
|
if (!appConfig().serialKey().isEmpty()) {
|
||||||
|
args << "--serial-key" << appConfig().serialKey();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
// pass in physical resolution and primary screen center
|
// pass in physical resolution and primary screen center
|
||||||
// TODO: get this information in the core binary even when
|
// TODO: get this information in the core binary even when
|
||||||
|
@ -895,7 +928,7 @@ void MainWindow::setSynergyState(qSynergyState state)
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case synergyConnected: {
|
case synergyConnected: {
|
||||||
if (m_AppConfig.getCryptoEnabled()) {
|
if (m_AppConfig->getCryptoEnabled()) {
|
||||||
m_pLabelPadlock->show();
|
m_pLabelPadlock->show();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1010,13 +1043,13 @@ void MainWindow::updateZeroconfService()
|
||||||
QMutexLocker locker(&m_UpdateZeroconfMutex);
|
QMutexLocker locker(&m_UpdateZeroconfMutex);
|
||||||
|
|
||||||
if (isBonjourRunning()) {
|
if (isBonjourRunning()) {
|
||||||
if (!m_AppConfig.wizardShouldRun()) {
|
if (!m_AppConfig->wizardShouldRun()) {
|
||||||
if (m_pZeroconfService) {
|
if (m_pZeroconfService) {
|
||||||
delete m_pZeroconfService;
|
delete m_pZeroconfService;
|
||||||
m_pZeroconfService = NULL;
|
m_pZeroconfService = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_AppConfig.autoConfig() || synergyType() == synergyServer) {
|
if (m_AppConfig->autoConfig() || synergyType() == synergyServer) {
|
||||||
m_pZeroconfService = new ZeroconfService(this);
|
m_pZeroconfService = new ZeroconfService(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1035,10 +1068,10 @@ void MainWindow::serverDetected(const QString name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setEdition(int edition)
|
void MainWindow::setEdition(Edition edition)
|
||||||
{
|
{
|
||||||
setWindowTitle(getEditionName(edition));
|
setWindowTitle(m_LicenseManager->getEditionName (edition));
|
||||||
if (m_AppConfig.getCryptoEnabled()) {
|
if (m_AppConfig->getCryptoEnabled()) {
|
||||||
m_pSslCertificate = new SslCertificate(this);
|
m_pSslCertificate = new SslCertificate(this);
|
||||||
m_pSslCertificate->generateCertificate();
|
m_pSslCertificate->generateCertificate();
|
||||||
}
|
}
|
||||||
|
@ -1046,9 +1079,60 @@ void MainWindow::setEdition(int edition)
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::beginTrial(bool isExpiring)
|
||||||
|
{
|
||||||
|
//Hack
|
||||||
|
//if (isExpiring) {
|
||||||
|
time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
|
||||||
|
QString expiringNotice ("<html><head/><body><p><span style=\""
|
||||||
|
"font-weight:600;\">%1</span> day%3 of "
|
||||||
|
"your %2 trial remain%5. <a href="
|
||||||
|
"\"https://symless.com/synergy/trial/thanks?id=%4\">"
|
||||||
|
"<span style=\"text-decoration: underline;"
|
||||||
|
" color:#0000ff;\">Buy now!</span></a>"
|
||||||
|
"</p></body></html>");
|
||||||
|
expiringNotice = expiringNotice
|
||||||
|
.arg (daysLeft)
|
||||||
|
.arg (LicenseManager::getEditionName
|
||||||
|
(m_LicenseManager->activeEdition()))
|
||||||
|
.arg ((daysLeft == 1) ? "" : "s")
|
||||||
|
.arg (QString::fromStdString
|
||||||
|
(m_LicenseManager->serialKey().toString()))
|
||||||
|
.arg ((daysLeft == 1) ? "s" : "");
|
||||||
|
this->m_trialLabel->setText(expiringNotice);
|
||||||
|
this->m_trialWidget->show();
|
||||||
|
//}
|
||||||
|
setWindowTitle (m_LicenseManager->activeEditionName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::endTrial(bool isExpired)
|
||||||
|
{
|
||||||
|
if (isExpired) {
|
||||||
|
QString expiredNotice (
|
||||||
|
"<html><head/><body><p>Your %1 trial has expired. <a href="
|
||||||
|
"\"https://symless.com/synergy/trial/thanks?id=%2\">"
|
||||||
|
"<span style=\"text-decoration: underline;color:#0000ff;\">"
|
||||||
|
"Buy now!</span></a></p></body></html>"
|
||||||
|
);
|
||||||
|
expiredNotice = expiredNotice
|
||||||
|
.arg(LicenseManager::getEditionName
|
||||||
|
(m_LicenseManager->activeEdition()))
|
||||||
|
.arg(QString::fromStdString
|
||||||
|
(m_LicenseManager->serialKey().toString()));
|
||||||
|
|
||||||
|
this->m_trialLabel->setText(expiredNotice);
|
||||||
|
this->m_trialWidget->show();
|
||||||
|
stopSynergy();
|
||||||
|
m_AppConfig->activationHasRun(false);
|
||||||
|
} else {
|
||||||
|
this->m_trialWidget->hide();
|
||||||
|
}
|
||||||
|
setWindowTitle (m_LicenseManager->activeEditionName());
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::updateLocalFingerprint()
|
void MainWindow::updateLocalFingerprint()
|
||||||
{
|
{
|
||||||
if (m_AppConfig.getCryptoEnabled() && Fingerprint::local().fileExists()) {
|
if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists()) {
|
||||||
m_pLabelFingerprint->setVisible(true);
|
m_pLabelFingerprint->setVisible(true);
|
||||||
m_pLabelLocalFingerprint->setVisible(true);
|
m_pLabelLocalFingerprint->setVisible(true);
|
||||||
m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst());
|
m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst());
|
||||||
|
@ -1059,6 +1143,12 @@ void MainWindow::updateLocalFingerprint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LicenseManager&
|
||||||
|
MainWindow::licenseManager() const
|
||||||
|
{
|
||||||
|
return *m_LicenseManager;
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pGroupClient_toggled(bool on)
|
void MainWindow::on_m_pGroupClient_toggled(bool on)
|
||||||
{
|
{
|
||||||
m_pGroupServer->setChecked(!on);
|
m_pGroupServer->setChecked(!on);
|
||||||
|
@ -1123,6 +1213,14 @@ void MainWindow::on_m_pActionSettings_triggered()
|
||||||
void MainWindow::autoAddScreen(const QString name)
|
void MainWindow::autoAddScreen(const QString name)
|
||||||
{
|
{
|
||||||
if (!m_ServerConfig.ignoreAutoConfigClient()) {
|
if (!m_ServerConfig.ignoreAutoConfigClient()) {
|
||||||
|
if (m_ActivationDialogRunning) {
|
||||||
|
// TODO: refactor this code
|
||||||
|
// add this screen to the pending list and check this list until
|
||||||
|
// users finish activation dialog
|
||||||
|
m_PendingClientNames.append(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int r = m_ServerConfig.autoAddScreen(name);
|
int r = m_ServerConfig.autoAddScreen(name);
|
||||||
if (r != kAutoAddScreenOk) {
|
if (r != kAutoAddScreenOk) {
|
||||||
switch (r) {
|
switch (r) {
|
||||||
|
@ -1160,8 +1258,7 @@ void MainWindow::on_m_pButtonConfigureServer_clicked()
|
||||||
|
|
||||||
void MainWindow::on_m_pActivate_triggered()
|
void MainWindow::on_m_pActivate_triggered()
|
||||||
{
|
{
|
||||||
ActivationDialog activationDialog (this, this->appConfig());
|
raiseActivationDialog();
|
||||||
activationDialog.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pButtonApply_clicked()
|
void MainWindow::on_m_pButtonApply_clicked()
|
||||||
|
@ -1325,16 +1422,16 @@ void MainWindow::promptAutoConfig()
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
if (r == QMessageBox::Yes) {
|
if (r == QMessageBox::Yes) {
|
||||||
m_AppConfig.setAutoConfig(true);
|
m_AppConfig->setAutoConfig(true);
|
||||||
downloadBonjour();
|
downloadBonjour();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_AppConfig.setAutoConfig(false);
|
m_AppConfig->setAutoConfig(false);
|
||||||
m_pCheckBoxAutoConfig->setChecked(false);
|
m_pCheckBoxAutoConfig->setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_AppConfig.setAutoConfigPrompted(true);
|
m_AppConfig->setAutoConfigPrompted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pComboServerList_currentIndexChanged(QString )
|
void MainWindow::on_m_pComboServerList_currentIndexChanged(QString )
|
||||||
|
@ -1380,11 +1477,37 @@ void MainWindow::bonjourInstallFinished()
|
||||||
m_pCheckBoxAutoConfig->setChecked(true);
|
m_pCheckBoxAutoConfig->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MainWindow::raiseActivationDialog()
|
||||||
|
{
|
||||||
|
if (m_ActivationDialogRunning) {
|
||||||
|
return QDialog::Rejected;
|
||||||
|
}
|
||||||
|
ActivationDialog activationDialog (this, appConfig(), licenseManager());
|
||||||
|
m_ActivationDialogRunning = true;
|
||||||
|
connect (&activationDialog, SIGNAL(finished(int)),
|
||||||
|
this, SLOT(on_activationDialogFinish()), Qt::QueuedConnection);
|
||||||
|
int result = activationDialog.exec();
|
||||||
|
m_ActivationDialogRunning = false;
|
||||||
|
if (!m_PendingClientNames.empty()) {
|
||||||
|
foreach (const QString& name, m_PendingClientNames) {
|
||||||
|
autoAddScreen(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_PendingClientNames.clear();
|
||||||
|
}
|
||||||
|
if (result == QDialog::Accepted) {
|
||||||
|
restartSynergy();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_windowShown()
|
void MainWindow::on_windowShown()
|
||||||
{
|
{
|
||||||
if (!m_AppConfig.activationHasRun() && (m_AppConfig.edition() == Unregistered)) {
|
time_t currentTime = ::time(0);
|
||||||
ActivationDialog activationDialog (this, m_AppConfig);
|
if (!m_AppConfig->activationHasRun()
|
||||||
activationDialog.exec();
|
&& ((m_AppConfig->edition() == kUnregistered) ||
|
||||||
|
(m_LicenseManager->serialKey().isExpired(currentTime)))) {
|
||||||
|
raiseActivationDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ class ZeroconfService;
|
||||||
class DataDownloader;
|
class DataDownloader;
|
||||||
class CommandProcess;
|
class CommandProcess;
|
||||||
class SslCertificate;
|
class SslCertificate;
|
||||||
|
class LicenseManager;
|
||||||
|
|
||||||
class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
{
|
{
|
||||||
|
@ -94,7 +95,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QSettings& settings, AppConfig& appConfig);
|
MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||||
|
LicenseManager& licenseManager);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -116,9 +118,14 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
void updateZeroconfService();
|
void updateZeroconfService();
|
||||||
void serverDetected(const QString name);
|
void serverDetected(const QString name);
|
||||||
void updateLocalFingerprint();
|
void updateLocalFingerprint();
|
||||||
|
LicenseManager& licenseManager() const;
|
||||||
|
|
||||||
public slots:
|
int raiseActivationDialog();
|
||||||
void setEdition(int edition);
|
|
||||||
|
public slots:
|
||||||
|
void setEdition(Edition edition);
|
||||||
|
void beginTrial(bool isExpiring);
|
||||||
|
void endTrial(bool isExpired);
|
||||||
void appendLogRaw(const QString& text);
|
void appendLogRaw(const QString& text);
|
||||||
void appendLogInfo(const QString& text);
|
void appendLogInfo(const QString& text);
|
||||||
void appendLogDebug(const QString& text);
|
void appendLogDebug(const QString& text);
|
||||||
|
@ -145,7 +152,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSettings& settings() { return m_Settings; }
|
QSettings& settings() { return m_Settings; }
|
||||||
AppConfig& appConfig() { return m_AppConfig; }
|
AppConfig& appConfig() { return *m_AppConfig; }
|
||||||
QProcess* synergyProcess() { return m_pSynergy; }
|
QProcess* synergyProcess() { return m_pSynergy; }
|
||||||
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
|
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
|
||||||
void initConnections();
|
void initConnections();
|
||||||
|
@ -162,7 +169,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
void setStatus(const QString& status);
|
void setStatus(const QString& status);
|
||||||
void sendIpcMessage(qIpcMessageType type, const char* buffer, bool showErrors);
|
void sendIpcMessage(qIpcMessageType type, const char* buffer, bool showErrors);
|
||||||
void onModeChanged(bool startDesktop, bool applyService);
|
void onModeChanged(bool startDesktop, bool applyService);
|
||||||
void updateStateFromLogLine(const QString& line);
|
void updateFromLogLine(const QString& line);
|
||||||
QString getIPAddresses();
|
QString getIPAddresses();
|
||||||
void stopService();
|
void stopService();
|
||||||
void stopDesktop();
|
void stopDesktop();
|
||||||
|
@ -178,6 +185,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
void promptAutoConfig();
|
void promptAutoConfig();
|
||||||
QString getProfileRootForArg();
|
QString getProfileRootForArg();
|
||||||
void checkConnected(const QString& line);
|
void checkConnected(const QString& line);
|
||||||
|
void checkLicense(const QString& line);
|
||||||
void checkFingerprint(const QString& line);
|
void checkFingerprint(const QString& line);
|
||||||
bool autoHide();
|
bool autoHide();
|
||||||
QString getTimeStamp();
|
QString getTimeStamp();
|
||||||
|
@ -188,7 +196,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings& m_Settings;
|
QSettings& m_Settings;
|
||||||
AppConfig& m_AppConfig;
|
AppConfig* m_AppConfig;
|
||||||
|
LicenseManager* m_LicenseManager;
|
||||||
QProcess* m_pSynergy;
|
QProcess* m_pSynergy;
|
||||||
int m_SynergyState;
|
int m_SynergyState;
|
||||||
ServerConfig m_ServerConfig;
|
ServerConfig m_ServerConfig;
|
||||||
|
@ -214,6 +223,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
qRuningState m_ExpectedRunningState;
|
qRuningState m_ExpectedRunningState;
|
||||||
QMutex m_StopDesktopMutex;
|
QMutex m_StopDesktopMutex;
|
||||||
SslCertificate* m_pSslCertificate;
|
SslCertificate* m_pSslCertificate;
|
||||||
|
bool m_ActivationDialogRunning;
|
||||||
|
QStringList m_PendingClientNames;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_m_pCheckBoxAutoConfig_toggled(bool checked);
|
void on_m_pCheckBoxAutoConfig_toggled(bool checked);
|
||||||
|
|
|
@ -42,22 +42,6 @@ void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
|
||||||
getEditionName (int edition) {
|
|
||||||
if (edition == Basic) {
|
|
||||||
return "Synergy Basic";
|
|
||||||
}
|
|
||||||
else if (edition == Pro) {
|
|
||||||
return "Synergy Pro";
|
|
||||||
}
|
|
||||||
else if (edition == Trial) {
|
|
||||||
return "Synergy Trial";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return "Synergy (UNREGISTERED)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString hash(const QString& string)
|
QString hash(const QString& string)
|
||||||
{
|
{
|
||||||
QByteArray data = string.toUtf8();
|
QByteArray data = string.toUtf8();
|
||||||
|
|
|
@ -29,4 +29,3 @@ QString hash(const QString& string);
|
||||||
QString getFirstMacAddress();
|
QString getFirstMacAddress();
|
||||||
qProcessorArch getProcessorArch();
|
qProcessorArch getProcessorArch();
|
||||||
QString getOSInformation();
|
QString getOSInformation();
|
||||||
QString getEditionName (int edition);
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
|
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
|
||||||
m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == Pro);
|
m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == kPro);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::accept()
|
void SettingsDialog::accept()
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "WebClient.h"
|
#include "WebClient.h"
|
||||||
#include "ActivationNotifier.h"
|
#include "ActivationNotifier.h"
|
||||||
#include "SubscriptionManager.h"
|
#include "LicenseManager.h"
|
||||||
#include "EditionType.h"
|
#include "EditionType.h"
|
||||||
#include "QSynergyApplication.h"
|
#include "QSynergyApplication.h"
|
||||||
#include "QUtility.h"
|
#include "QUtility.h"
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* synergy -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015 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 "SubscriptionManager.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "CoreInterface.h"
|
|
||||||
#include "EditionType.h"
|
|
||||||
#include "AppConfig.h"
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QDate>
|
|
||||||
|
|
||||||
static const char purchaseURL[] = "https://symless.com/account/";
|
|
||||||
|
|
||||||
SubscriptionManager::SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition) :
|
|
||||||
m_pParent(parent),
|
|
||||||
m_AppConfig(appConfig),
|
|
||||||
m_Edition(edition)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SubscriptionManager::activateSerial(const QString& serial)
|
|
||||||
{
|
|
||||||
m_Edition = Unregistered;
|
|
||||||
persistDirectory();
|
|
||||||
CoreInterface coreInterface;
|
|
||||||
QString output;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
output = coreInterface.activateSerial(serial);
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
m_ErrorMessage = e.what();
|
|
||||||
checkError(m_ErrorMessage);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkOutput(output);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SubscriptionManager::checkSubscription()
|
|
||||||
{
|
|
||||||
m_Edition = Unregistered;
|
|
||||||
persistDirectory();
|
|
||||||
CoreInterface coreInterface;
|
|
||||||
QString output;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
output = coreInterface.checkSubscription();
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
m_ErrorMessage = e.what();
|
|
||||||
checkError(m_ErrorMessage);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkOutput(output);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SubscriptionManager::fileExists()
|
|
||||||
{
|
|
||||||
CoreInterface coreInterface;
|
|
||||||
QString subscriptionFilename = coreInterface.getSubscriptionFilename();
|
|
||||||
|
|
||||||
return QFile::exists(subscriptionFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubscriptionManager::checkError(QString& error)
|
|
||||||
{
|
|
||||||
if (error.contains("trial has expired")) {
|
|
||||||
QMessageBox::warning(m_pParent, tr("Subscription warning"),
|
|
||||||
tr("Your trial has expired. Click <a href='%1'>here</a> to purchase").arg(purchaseURL));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QMessageBox::warning(m_pParent, tr("Subscription error"),
|
|
||||||
tr("An error occurred while trying to activate Synergy using your serial key. "
|
|
||||||
"Please contact the helpdesk, and provide the "
|
|
||||||
"following details.\n\n%1").arg(error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubscriptionManager::checkOutput(QString& output)
|
|
||||||
{
|
|
||||||
getEditionType(output);
|
|
||||||
checkExpiring(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubscriptionManager::getEditionType(QString& output)
|
|
||||||
{
|
|
||||||
if (output.contains("pro subscription valid")) {
|
|
||||||
m_Edition = Pro;
|
|
||||||
}
|
|
||||||
else if (output.contains("basic subscription valid")) {
|
|
||||||
m_Edition = Basic;
|
|
||||||
}
|
|
||||||
else if (output.contains("trial subscription valid")) {
|
|
||||||
m_Edition = Trial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubscriptionManager::checkExpiring(QString& output)
|
|
||||||
{
|
|
||||||
if (output.contains("trial will end in") && shouldWarnExpiring()) {
|
|
||||||
QRegExp dayLeftRegex(".*trial will end in ([0-9]+) day.*");
|
|
||||||
if (dayLeftRegex.exactMatch(output)) {
|
|
||||||
QString dayLeft = dayLeftRegex.cap(1);
|
|
||||||
|
|
||||||
QMessageBox::warning(m_pParent, tr("Subscription warning"),
|
|
||||||
tr("Your trial will end in %1 %2. Click <a href='%3'>here</a> to purchase")
|
|
||||||
.arg(dayLeft)
|
|
||||||
.arg(dayLeft == "1" ? "day" : "days")
|
|
||||||
.arg(purchaseURL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SubscriptionManager::shouldWarnExpiring()
|
|
||||||
{
|
|
||||||
// warn users about expiring subscription once a day
|
|
||||||
int lastExpiringWarningTime = m_AppConfig.lastExpiringWarningTime();
|
|
||||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
|
||||||
int currentTime = currentDateTime.toTime_t();
|
|
||||||
const int secondPerDay = 60 * 60 * 24;
|
|
||||||
bool result = false;
|
|
||||||
if ((currentTime - lastExpiringWarningTime) > secondPerDay) {
|
|
||||||
result = true;
|
|
||||||
m_AppConfig.setLastExpiringWarningTime(currentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubscriptionManager::persistDirectory()
|
|
||||||
{
|
|
||||||
CoreInterface coreInterface;
|
|
||||||
QString profileDir = coreInterface.getProfileDir();
|
|
||||||
|
|
||||||
QDir dir(profileDir);
|
|
||||||
if (!dir.exists()) {
|
|
||||||
dir.mkpath(".");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* synergy -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015 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 <QWidget>
|
|
||||||
|
|
||||||
class AppConfig;
|
|
||||||
|
|
||||||
class SubscriptionManager : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition);
|
|
||||||
|
|
||||||
bool activateSerial(const QString& serial);
|
|
||||||
bool checkSubscription();
|
|
||||||
bool fileExists();
|
|
||||||
QString getLastError(){ return m_ErrorMessage; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void checkError(QString& error);
|
|
||||||
void checkOutput(QString& output);
|
|
||||||
void getEditionType(QString& output);
|
|
||||||
void checkExpiring(QString& output);
|
|
||||||
bool shouldWarnExpiring();
|
|
||||||
void persistDirectory();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_ErrorMessage;
|
|
||||||
QWidget* m_pParent;
|
|
||||||
AppConfig& m_AppConfig;
|
|
||||||
int& m_Edition;
|
|
||||||
};
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define TRAY_RETRY_WAIT 2000
|
#define TRAY_RETRY_WAIT 2000
|
||||||
|
|
||||||
#include "QSynergyApplication.h"
|
#include "QSynergyApplication.h"
|
||||||
|
#include "LicenseManager.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include "SetupWizard.h"
|
#include "SetupWizard.h"
|
||||||
|
@ -82,11 +83,13 @@ int main(int argc, char* argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
AppConfig appConfig(&settings);
|
AppConfig appConfig (&settings);
|
||||||
|
qRegisterMetaType<Edition>("Edition");
|
||||||
|
LicenseManager licenseManager (&appConfig);
|
||||||
|
|
||||||
app.switchTranslator(appConfig.language());
|
app.switchTranslator(appConfig.language());
|
||||||
|
|
||||||
MainWindow mainWindow(settings, appConfig);
|
MainWindow mainWindow(settings, appConfig, licenseManager);
|
||||||
SetupWizard setupWizard(mainWindow, true);
|
SetupWizard setupWizard(mainWindow, true);
|
||||||
|
|
||||||
if (appConfig.wizardShouldRun())
|
if (appConfig.wizardShouldRun())
|
||||||
|
|
|
@ -25,7 +25,7 @@ add_subdirectory(net)
|
||||||
add_subdirectory(platform)
|
add_subdirectory(platform)
|
||||||
add_subdirectory(server)
|
add_subdirectory(server)
|
||||||
add_subdirectory(synergy)
|
add_subdirectory(synergy)
|
||||||
|
add_subdirectory(shared)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_subdirectory(synwinhk)
|
add_subdirectory(synwinhk)
|
||||||
|
|
|
@ -116,7 +116,6 @@ CurlFacade::urlEncode(const String& url)
|
||||||
char* resultCStr = curl_easy_escape(m_curl, url.c_str(), 0);
|
char* resultCStr = curl_easy_escape(m_curl, url.c_str(), 0);
|
||||||
|
|
||||||
if (resultCStr == NULL) {
|
if (resultCStr == NULL) {
|
||||||
curl_free(resultCStr);
|
|
||||||
throw XArch("CURL escape failed.");
|
throw XArch("CURL escape failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,6 @@ public:
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
accept() = 0;
|
accept() = 0;
|
||||||
|
|
||||||
//! Delete connection socket
|
|
||||||
/*!
|
|
||||||
This is used when the socket was created but not adopted by a client
|
|
||||||
proxy.
|
|
||||||
*/
|
|
||||||
virtual void deleteSocket(void*) = 0;
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
// ISocket overrides
|
// ISocket overrides
|
||||||
|
|
|
@ -93,14 +93,3 @@ SecureListenSocket::accept()
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SecureListenSocket::deleteSocket(void* socket)
|
|
||||||
{
|
|
||||||
SecureSocketSet::iterator it;
|
|
||||||
it = m_secureSocketSet.find((IDataSocket*)socket);
|
|
||||||
if (it != m_secureSocketSet.end()) {
|
|
||||||
delete *it;
|
|
||||||
m_secureSocketSet.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ public:
|
||||||
// IListenSocket overrides
|
// IListenSocket overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
accept();
|
accept();
|
||||||
void deleteSocket(void*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::set<IDataSocket*> SecureSocketSet;
|
typedef std::set<IDataSocket*> SecureSocketSet;
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
// IListenSocket overrides
|
// IListenSocket overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
accept();
|
accept();
|
||||||
virtual void deleteSocket(void*) { }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setListeningJob();
|
void setListeningJob();
|
||||||
|
|
|
@ -19,7 +19,7 @@ if (WIN32)
|
||||||
file(GLOB sources "MSWindows*.cpp")
|
file(GLOB sources "MSWindows*.cpp")
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
file(GLOB headers "OSX*.h" "IOSX*.h")
|
file(GLOB headers "OSX*.h" "IOSX*.h")
|
||||||
file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m")
|
file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m" "OSX*.mm")
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
file(GLOB headers "XWindows*.h")
|
file(GLOB headers "XWindows*.h")
|
||||||
file(GLOB sources "XWindows*.cpp")
|
file(GLOB sources "XWindows*.cpp")
|
||||||
|
|
|
@ -122,7 +122,7 @@ OSXClipboard::add(EFormat format, const String & data)
|
||||||
|
|
||||||
PasteboardPutItemFlavor(
|
PasteboardPutItemFlavor(
|
||||||
m_pboard,
|
m_pboard,
|
||||||
(PasteboardItemID) 0,
|
nullptr,
|
||||||
flavorType,
|
flavorType,
|
||||||
dataRef,
|
dataRef,
|
||||||
kPasteboardFlavorNoFlags);
|
kPasteboardFlavorNoFlags);
|
||||||
|
|
|
@ -344,4 +344,6 @@ private:
|
||||||
Mutex* m_carbonLoopMutex;
|
Mutex* m_carbonLoopMutex;
|
||||||
CondVar<bool>* m_carbonLoopReady;
|
CondVar<bool>* m_carbonLoopReady;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class OSXScreenImpl* m_impl;
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,7 +101,8 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso
|
||||||
m_lastSingleClickYCursor(0),
|
m_lastSingleClickYCursor(0),
|
||||||
m_autoShowHideCursor(autoShowHideCursor),
|
m_autoShowHideCursor(autoShowHideCursor),
|
||||||
m_events(events),
|
m_events(events),
|
||||||
m_getDropTargetThread(NULL)
|
m_getDropTargetThread(NULL),
|
||||||
|
m_impl(NULL)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
m_displayID = CGMainDisplayID();
|
m_displayID = CGMainDisplayID();
|
||||||
|
@ -515,9 +516,7 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press)
|
||||||
// we define our own defaults.
|
// we define our own defaults.
|
||||||
const double maxDiff = sqrt(2) + 0.0001;
|
const double maxDiff = sqrt(2) + 0.0001;
|
||||||
|
|
||||||
|
double clickTime = [NSEvent doubleClickInterval];
|
||||||
NXEventHandle handle = NXOpenEventStatus();
|
|
||||||
double clickTime = NXClickTime(handle);
|
|
||||||
|
|
||||||
// As long as the click is within the time window and distance window
|
// As long as the click is within the time window and distance window
|
||||||
// increase clickState (double click, triple click, etc)
|
// increase clickState (double click, triple click, etc)
|
|
@ -35,6 +35,8 @@ endif()
|
||||||
|
|
||||||
add_library(server STATIC ${sources})
|
add_library(server STATIC ${sources})
|
||||||
|
|
||||||
|
target_link_libraries(server shared)
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_link_libraries(server synergy)
|
target_link_libraries(server synergy)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -106,12 +106,6 @@ ClientListener::setServer(Server* server)
|
||||||
m_server = server;
|
m_server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ClientListener::deleteSocket(void* socket)
|
|
||||||
{
|
|
||||||
m_listen->deleteSocket(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientProxy*
|
ClientProxy*
|
||||||
ClientListener::getNextClient()
|
ClientListener::getNextClient()
|
||||||
{
|
{
|
||||||
|
@ -213,10 +207,6 @@ ClientListener::handleUnknownClient(const Event&, void* vclient)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete unknownClient;
|
delete unknownClient;
|
||||||
|
|
||||||
if (m_useSecureNetwork && !handshakeOk) {
|
|
||||||
deleteSocket(socket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -48,8 +48,6 @@ public:
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
void deleteSocket(void* socket);
|
|
||||||
|
|
||||||
//! @name accessors
|
//! @name accessors
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
|
|
@ -45,11 +45,13 @@
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/TMethodEventJob.h"
|
#include "base/TMethodEventJob.h"
|
||||||
#include "common/stdexcept.h"
|
#include "common/stdexcept.h"
|
||||||
|
#include "shared/SerialKey.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Server
|
// Server
|
||||||
|
@ -60,7 +62,7 @@ Server::Server(
|
||||||
PrimaryClient* primaryClient,
|
PrimaryClient* primaryClient,
|
||||||
synergy::Screen* screen,
|
synergy::Screen* screen,
|
||||||
IEventQueue* events,
|
IEventQueue* events,
|
||||||
bool enableDragDrop) :
|
ServerArgs const& args) :
|
||||||
m_mock(false),
|
m_mock(false),
|
||||||
m_primaryClient(primaryClient),
|
m_primaryClient(primaryClient),
|
||||||
m_active(primaryClient),
|
m_active(primaryClient),
|
||||||
|
@ -91,10 +93,10 @@ Server::Server(
|
||||||
m_sendFileThread(NULL),
|
m_sendFileThread(NULL),
|
||||||
m_writeToDropDirThread(NULL),
|
m_writeToDropDirThread(NULL),
|
||||||
m_ignoreFileTransfer(false),
|
m_ignoreFileTransfer(false),
|
||||||
m_enableDragDrop(enableDragDrop),
|
|
||||||
m_enableClipboard(true),
|
m_enableClipboard(true),
|
||||||
m_sendDragInfoThread(NULL),
|
m_sendDragInfoThread(NULL),
|
||||||
m_waitDragInfoThread(true)
|
m_waitDragInfoThread(true),
|
||||||
|
m_args(args)
|
||||||
{
|
{
|
||||||
// must have a primary client and it must have a canonical name
|
// must have a primary client and it must have a canonical name
|
||||||
assert(m_primaryClient != NULL);
|
assert(m_primaryClient != NULL);
|
||||||
|
@ -184,7 +186,7 @@ Server::Server(
|
||||||
new TMethodEventJob<Server>(this,
|
new TMethodEventJob<Server>(this,
|
||||||
&Server::handleFakeInputEndEvent));
|
&Server::handleFakeInputEndEvent));
|
||||||
|
|
||||||
if (m_enableDragDrop) {
|
if (m_args.m_enableDragDrop) {
|
||||||
m_events->adoptHandler(m_events->forFile().fileChunkSending(),
|
m_events->adoptHandler(m_events->forFile().fileChunkSending(),
|
||||||
this,
|
this,
|
||||||
new TMethodEventJob<Server>(this,
|
new TMethodEventJob<Server>(this,
|
||||||
|
@ -451,6 +453,13 @@ Server::switchScreen(BaseClientProxy* dst,
|
||||||
SInt32 x, SInt32 y, bool forScreensaver)
|
SInt32 x, SInt32 y, bool forScreensaver)
|
||||||
{
|
{
|
||||||
assert(dst != NULL);
|
assert(dst != NULL);
|
||||||
|
|
||||||
|
// if trial is expired, exit the process
|
||||||
|
if (m_args.m_serial.isExpired(std::time(0))) {
|
||||||
|
LOG((CLOG_ERR "trial has expired, aborting server"));
|
||||||
|
exit(kExitSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
SInt32 dx, dy, dw, dh;
|
SInt32 dx, dy, dw, dh;
|
||||||
|
@ -884,7 +893,7 @@ Server::isSwitchOkay(BaseClientProxy* newScreen,
|
||||||
|
|
||||||
if (!preventSwitch && (
|
if (!preventSwitch && (
|
||||||
(this->m_switchNeedsShift && ((mods & KeyModifierShift) != KeyModifierShift)) ||
|
(this->m_switchNeedsShift && ((mods & KeyModifierShift) != KeyModifierShift)) ||
|
||||||
(this->m_switchNeedsControl && ((mods & KeyModifierControl) != KeyModifierControl)) ||
|
(this->m_switchNeedsControl && ((mods & KeyModifierControl) != KeyModifierControl)) ||
|
||||||
(this->m_switchNeedsAlt && ((mods & KeyModifierAlt) != KeyModifierAlt))
|
(this->m_switchNeedsAlt && ((mods & KeyModifierAlt) != KeyModifierAlt))
|
||||||
)) {
|
)) {
|
||||||
LOG((CLOG_DEBUG1 "need modifiers to switch"));
|
LOG((CLOG_DEBUG1 "need modifiers to switch"));
|
||||||
|
@ -1378,10 +1387,7 @@ Server::handleClientDisconnected(const Event&, void* vclient)
|
||||||
removeActiveClient(client);
|
removeActiveClient(client);
|
||||||
removeOldClient(client);
|
removeOldClient(client);
|
||||||
|
|
||||||
PacketStreamFilter* streamFileter = dynamic_cast<PacketStreamFilter*>(client->getStream());
|
|
||||||
TCPSocket* socket = dynamic_cast<TCPSocket*>(streamFileter->getStream());
|
|
||||||
delete client;
|
delete client;
|
||||||
m_clientListener->deleteSocket(socket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1391,10 +1397,8 @@ Server::handleClientCloseTimeout(const Event&, void* vclient)
|
||||||
BaseClientProxy* client = static_cast<BaseClientProxy*>(vclient);
|
BaseClientProxy* client = static_cast<BaseClientProxy*>(vclient);
|
||||||
LOG((CLOG_NOTE "forced disconnection of client \"%s\"", getName(client).c_str()));
|
LOG((CLOG_NOTE "forced disconnection of client \"%s\"", getName(client).c_str()));
|
||||||
removeOldClient(client);
|
removeOldClient(client);
|
||||||
PacketStreamFilter* streamFileter = dynamic_cast<PacketStreamFilter*>(client->getStream());
|
|
||||||
TCPSocket* socket = dynamic_cast<TCPSocket*>(streamFileter->getStream());
|
|
||||||
delete client;
|
delete client;
|
||||||
m_clientListener->deleteSocket(socket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1706,7 +1710,7 @@ Server::onMouseUp(ButtonID id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_enableDragDrop) {
|
if (m_args.m_enableDragDrop) {
|
||||||
if (!m_screen->isOnScreen()) {
|
if (!m_screen->isOnScreen()) {
|
||||||
String& file = m_screen->getDraggingFilename();
|
String& file = m_screen->getDraggingFilename();
|
||||||
if (!file.empty()) {
|
if (!file.empty()) {
|
||||||
|
@ -1791,7 +1795,7 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
|
||||||
|
|
||||||
// should we switch or not?
|
// should we switch or not?
|
||||||
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
|
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
|
||||||
if (m_enableDragDrop
|
if (m_args.m_enableDragDrop
|
||||||
&& m_screen->isDraggingStarted()
|
&& m_screen->isDraggingStarted()
|
||||||
&& m_active != newScreen
|
&& m_active != newScreen
|
||||||
&& m_waitDragInfoThread) {
|
&& m_waitDragInfoThread) {
|
||||||
|
@ -2059,7 +2063,7 @@ Server::onFileChunkSending(const void* data)
|
||||||
assert(m_active != NULL);
|
assert(m_active != NULL);
|
||||||
|
|
||||||
// relay
|
// relay
|
||||||
m_active->fileChunkSending(chunk->m_chunk[0], &chunk->m_chunk[1], chunk->m_dataSize);
|
m_active->fileChunkSending(chunk->m_chunk[0], &chunk->m_chunk[1], chunk->m_dataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2393,7 +2397,7 @@ Server::sendFileThread(void* data)
|
||||||
void
|
void
|
||||||
Server::dragInfoReceived(UInt32 fileNum, String content)
|
Server::dragInfoReceived(UInt32 fileNum, String content)
|
||||||
{
|
{
|
||||||
if (!m_enableDragDrop) {
|
if (!m_args.m_enableDragDrop) {
|
||||||
LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info."));
|
LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "synergy/mouse_types.h"
|
#include "synergy/mouse_types.h"
|
||||||
#include "synergy/INode.h"
|
#include "synergy/INode.h"
|
||||||
#include "synergy/DragInformation.h"
|
#include "synergy/DragInformation.h"
|
||||||
|
#include "synergy/ServerArgs.h"
|
||||||
#include "base/Event.h"
|
#include "base/Event.h"
|
||||||
#include "base/Stopwatch.h"
|
#include "base/Stopwatch.h"
|
||||||
#include "base/EventTypes.h"
|
#include "base/EventTypes.h"
|
||||||
|
@ -106,7 +107,7 @@ public:
|
||||||
ownership of \p primaryClient.
|
ownership of \p primaryClient.
|
||||||
*/
|
*/
|
||||||
Server(Config& config, PrimaryClient* primaryClient,
|
Server(Config& config, PrimaryClient* primaryClient,
|
||||||
synergy::Screen* screen, IEventQueue* events, bool enableDragDrop);
|
synergy::Screen* screen, IEventQueue* events, ServerArgs const& args);
|
||||||
~Server();
|
~Server();
|
||||||
|
|
||||||
#ifdef TEST_ENV
|
#ifdef TEST_ENV
|
||||||
|
@ -472,11 +473,11 @@ private:
|
||||||
Thread* m_writeToDropDirThread;
|
Thread* m_writeToDropDirThread;
|
||||||
String m_dragFileExt;
|
String m_dragFileExt;
|
||||||
bool m_ignoreFileTransfer;
|
bool m_ignoreFileTransfer;
|
||||||
bool m_enableDragDrop;
|
|
||||||
bool m_enableClipboard;
|
bool m_enableClipboard;
|
||||||
|
|
||||||
Thread* m_sendDragInfoThread;
|
Thread* m_sendDragInfoThread;
|
||||||
bool m_waitDragInfoThread;
|
bool m_waitDragInfoThread;
|
||||||
|
|
||||||
ClientListener* m_clientListener;
|
ClientListener* m_clientListener;
|
||||||
|
ServerArgs m_args;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# synergy -- mouse and keyboard sharing utility
|
||||||
|
# Copyright (C) 2016 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/>.
|
||||||
|
|
||||||
|
file(GLOB headers "*.h")
|
||||||
|
file(GLOB sources "*.cpp")
|
||||||
|
|
||||||
|
if (SYNERGY_ADD_HEADERS)
|
||||||
|
list(APPEND sources ${headers})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(shared STATIC ${sources})
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
../
|
||||||
|
../../../ext
|
||||||
|
../../../ext/gtest-1.6.0/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(shared arch base)
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
|
|
||||||
/* Do not reorder these! */
|
/* Do not reorder these! */
|
||||||
|
|
||||||
enum EditionType {
|
enum Edition {
|
||||||
Basic,
|
kBasic,
|
||||||
Pro,
|
kPro,
|
||||||
Trial,
|
Trial_DO_NOT_USE_OR_THERE_WILL_BE_PAIN,
|
||||||
Unregistered
|
kUnregistered
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EDITIONTYPE_H
|
#endif // EDITIONTYPE_H
|
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2016 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 "SerialKey.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <climits>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
SerialKey::SerialKey(Edition edition):
|
||||||
|
m_userLimit(1),
|
||||||
|
m_warnTime(ULLONG_MAX),
|
||||||
|
m_expireTime(ULLONG_MAX),
|
||||||
|
m_edition(edition),
|
||||||
|
m_trial(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialKey::SerialKey(std::string serial) :
|
||||||
|
m_userLimit(1),
|
||||||
|
m_warnTime(0),
|
||||||
|
m_expireTime(0),
|
||||||
|
m_edition(kBasic),
|
||||||
|
m_trial(true)
|
||||||
|
{
|
||||||
|
string plainText = decode(serial);
|
||||||
|
bool valid = false;
|
||||||
|
if (!plainText.empty()) {
|
||||||
|
valid = parse(plainText);
|
||||||
|
}
|
||||||
|
if (!valid) {
|
||||||
|
throw std::runtime_error ("Invalid serial key");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SerialKey::isExpiring(time_t currentTime) const
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (m_trial) {
|
||||||
|
if (m_warnTime <= currentTime && currentTime < m_expireTime) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SerialKey::isExpired(time_t currentTime) const
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (m_trial) {
|
||||||
|
if (m_expireTime <= currentTime) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SerialKey::isTrial() const
|
||||||
|
{
|
||||||
|
return m_trial;
|
||||||
|
}
|
||||||
|
|
||||||
|
Edition
|
||||||
|
SerialKey::edition() const
|
||||||
|
{
|
||||||
|
return m_edition;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::editionString() const
|
||||||
|
{
|
||||||
|
switch (edition()) {
|
||||||
|
case kBasic:
|
||||||
|
return "basic";
|
||||||
|
case kPro:
|
||||||
|
return "pro";
|
||||||
|
default: {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << static_cast<int>(edition());
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string
|
||||||
|
hexEncode (std::string const& str) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
|
int c = str[i];
|
||||||
|
oss << std::setfill('0') << std::hex << std::setw(2)
|
||||||
|
<< std::uppercase;
|
||||||
|
oss << c;
|
||||||
|
}
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::toString() const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "{";
|
||||||
|
if (isTrial()) {
|
||||||
|
oss << "v2;trial;";
|
||||||
|
} else {
|
||||||
|
oss << "v1;";
|
||||||
|
}
|
||||||
|
oss << editionString() << ";";
|
||||||
|
oss << m_name << ";";
|
||||||
|
oss << m_userLimit << ";";
|
||||||
|
oss << m_email << ";";
|
||||||
|
oss << m_company << ";";
|
||||||
|
oss << (isTrial() ? m_warnTime : 0) << ";";
|
||||||
|
oss << (isTrial() ? m_expireTime : 0);
|
||||||
|
oss << "}";
|
||||||
|
return hexEncode(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t
|
||||||
|
SerialKey::daysLeft(time_t currentTime) const
|
||||||
|
{
|
||||||
|
unsigned long long timeLeft = 0;
|
||||||
|
unsigned long long const day = 60 * 60 * 24;
|
||||||
|
|
||||||
|
if (currentTime < m_expireTime) {
|
||||||
|
timeLeft = m_expireTime - currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long daysLeft = 0;
|
||||||
|
daysLeft = timeLeft % day != 0 ? 1 : 0;
|
||||||
|
|
||||||
|
return timeLeft / day + daysLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::email() const
|
||||||
|
{
|
||||||
|
return m_email;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::decode(const std::string& serial)
|
||||||
|
{
|
||||||
|
static const char* const lut = "0123456789ABCDEF";
|
||||||
|
string output;
|
||||||
|
size_t len = serial.length();
|
||||||
|
if (len & 1) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.reserve(len / 2);
|
||||||
|
for (size_t i = 0; i < len; i += 2) {
|
||||||
|
|
||||||
|
char a = serial[i];
|
||||||
|
char b = serial[i + 1];
|
||||||
|
|
||||||
|
const char* p = std::lower_bound(lut, lut + 16, a);
|
||||||
|
const char* q = std::lower_bound(lut, lut + 16, b);
|
||||||
|
|
||||||
|
if (*q != b || *p != a) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push_back(static_cast<char>(((p - lut) << 4) | (q - lut)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SerialKey::parse(std::string plainSerial)
|
||||||
|
{
|
||||||
|
string parityStart = plainSerial.substr(0, 1);
|
||||||
|
string parityEnd = plainSerial.substr(plainSerial.length() - 1, 1);
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
// check for parity chars { and }, record parity result, then remove them.
|
||||||
|
if (parityStart == "{" && parityEnd == "}") {
|
||||||
|
plainSerial = plainSerial.substr(1, plainSerial.length() - 2);
|
||||||
|
|
||||||
|
// tokenize serialised subscription.
|
||||||
|
vector<string> parts;
|
||||||
|
std::string::size_type pos = 0;
|
||||||
|
bool look = true;
|
||||||
|
while (look) {
|
||||||
|
std::string::size_type start = pos;
|
||||||
|
pos = plainSerial.find(";", pos);
|
||||||
|
if (pos == string::npos) {
|
||||||
|
pos = plainSerial.length();
|
||||||
|
look = false;
|
||||||
|
}
|
||||||
|
parts.push_back(plainSerial.substr(start, pos - start));
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((parts.size() == 8)
|
||||||
|
&& (parts.at(0).find("v1") != string::npos)) {
|
||||||
|
// e.g.: {v1;basic;Bob;1;email;company name;1398297600;1398384000}
|
||||||
|
m_edition = parseEdition(parts.at(1));
|
||||||
|
m_name = parts.at(2);
|
||||||
|
m_trial = false;
|
||||||
|
sscanf(parts.at(3).c_str(), "%d", &m_userLimit);
|
||||||
|
m_email = parts.at(4);
|
||||||
|
m_company = parts.at(5);
|
||||||
|
sscanf(parts.at(6).c_str(), "%lld", &m_warnTime);
|
||||||
|
sscanf(parts.at(7).c_str(), "%lld", &m_expireTime);
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
else if ((parts.size() == 9)
|
||||||
|
&& (parts.at(0).find("v2") != string::npos)) {
|
||||||
|
// e.g.: {v2;trial;basic;Bob;1;email;company name;1398297600;1398384000}
|
||||||
|
m_trial = parts.at(1) == "trial" ? true : false;
|
||||||
|
m_edition = parseEdition(parts.at(2));
|
||||||
|
m_name = parts.at(3);
|
||||||
|
sscanf(parts.at(4).c_str(), "%d", &m_userLimit);
|
||||||
|
m_email = parts.at(5);
|
||||||
|
m_company = parts.at(6);
|
||||||
|
sscanf(parts.at(7).c_str(), "%lld", &m_warnTime);
|
||||||
|
sscanf(parts.at(8).c_str(), "%lld", &m_expireTime);
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Edition
|
||||||
|
SerialKey::parseEdition(std::string const& editionStr)
|
||||||
|
{
|
||||||
|
Edition e = kBasic;
|
||||||
|
if (editionStr == "pro") {
|
||||||
|
e = kPro;
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2016 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 <string>
|
||||||
|
#include <ctime>
|
||||||
|
#include "EditionType.h"
|
||||||
|
|
||||||
|
#ifdef TEST_ENV
|
||||||
|
#include "gtest/gtest_prod.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class SerialKey {
|
||||||
|
friend bool operator== (SerialKey const&, SerialKey const&);
|
||||||
|
public:
|
||||||
|
explicit SerialKey(Edition edition = kUnregistered);
|
||||||
|
explicit SerialKey(std::string serial);
|
||||||
|
|
||||||
|
bool isExpiring(time_t currentTime) const;
|
||||||
|
bool isExpired(time_t currentTime) const;
|
||||||
|
bool isTrial() const;
|
||||||
|
time_t daysLeft(time_t currentTime) const;
|
||||||
|
std::string email() const;
|
||||||
|
Edition edition() const;
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
static std::string decode(const std::string& serial);
|
||||||
|
static Edition parseEdition(const std::string& editionStr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool parse(std::string plainSerial);
|
||||||
|
std::string editionString() const;
|
||||||
|
|
||||||
|
#ifdef TEST_ENV
|
||||||
|
private:
|
||||||
|
FRIEND_TEST(SerialKeyTests, parse_noParty_invalid);
|
||||||
|
FRIEND_TEST(SerialKeyTests, parse_invalidPartsLenghth_invalid);
|
||||||
|
FRIEND_TEST(SerialKeyTests, parse_validV1Serial_valid);
|
||||||
|
FRIEND_TEST(SerialKeyTests, parse_validV2Serial_valid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_email;
|
||||||
|
std::string m_company;
|
||||||
|
unsigned m_userLimit;
|
||||||
|
unsigned long long m_warnTime;
|
||||||
|
unsigned long long m_expireTime;
|
||||||
|
Edition m_edition;
|
||||||
|
bool m_trial;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
operator== (SerialKey const& lhs, SerialKey const& rhs) {
|
||||||
|
return (lhs.m_name == rhs.m_name) &&
|
||||||
|
(lhs.m_email == rhs.m_email) &&
|
||||||
|
(lhs.m_company == rhs.m_company) &&
|
||||||
|
(lhs.m_userLimit == rhs.m_userLimit) &&
|
||||||
|
(lhs.m_warnTime == rhs.m_warnTime) &&
|
||||||
|
(lhs.m_expireTime == rhs.m_expireTime) &&
|
||||||
|
(lhs.m_edition == rhs.m_edition) &&
|
||||||
|
(lhs.m_trial == rhs.m_trial);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
operator!= (SerialKey const& lhs, SerialKey const& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
|
@ -74,6 +74,9 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv)
|
||||||
else if (isArg(i, argc, argv, "", "--prm-hc", 1)) {
|
else if (isArg(i, argc, argv, "", "--prm-hc", 1)) {
|
||||||
DpiHelper::s_primaryHeightCenter = synergy::string::stringToSizeType(argv[++i]);
|
DpiHelper::s_primaryHeightCenter = synergy::string::stringToSizeType(argv[++i]);
|
||||||
}
|
}
|
||||||
|
else if (isArg(i, argc, argv, "", "--serial-key", 1)) {
|
||||||
|
args.m_serial = SerialKey(argv[++i]);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
|
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
|
||||||
return false;
|
return false;
|
||||||
|
@ -193,18 +196,10 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
|
||||||
args.m_loginAuthenticate = true;
|
args.m_loginAuthenticate = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-plugin-list", 0)) {
|
|
||||||
args.m_getPluginList = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
|
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
|
||||||
args.m_getInstalledDir = true;
|
args.m_getInstalledDir = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-plugin-dir", 0)) {
|
|
||||||
args.m_getPluginDir = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) {
|
else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) {
|
||||||
args.m_getProfileDir = true;
|
args.m_getProfileDir = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -213,26 +208,14 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
|
||||||
args.m_getArch = true;
|
args.m_getArch = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (isArg(i, argc, argv, NULL, "--subscription-serial", 1)) {
|
|
||||||
args.m_subscriptionSerial = argv[++i];
|
|
||||||
if (args.m_subscriptionSerial.empty()) {
|
|
||||||
LOG((CLOG_CRIT "subscription error: serial was not provided"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-subscription-filename", 0)) {
|
|
||||||
args.m_getSubscriptionFilename = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--check-subscription", 0)) {
|
|
||||||
args.m_checkSubscription = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
|
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
|
||||||
args.m_notifyActivation = true;
|
args.m_notifyActivation = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) {
|
||||||
|
args.m_notifyUpdate = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -496,7 +479,7 @@ ArgParser::assembleCommand(std::vector<String>& argsArray, String ignoreArg, in
|
||||||
|
|
||||||
if (!result.empty()) {
|
if (!result.empty()) {
|
||||||
// remove the tail space
|
// remove the tail space
|
||||||
result = result.substr(0, result.size() - 1);
|
result = result.substr(0, result.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -647,7 +647,7 @@ ServerApp::openClientListener(const NetworkAddress& address)
|
||||||
Server*
|
Server*
|
||||||
ServerApp::openServer(Config& config, PrimaryClient* primaryClient)
|
ServerApp::openServer(Config& config, PrimaryClient* primaryClient)
|
||||||
{
|
{
|
||||||
Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args().m_enableDragDrop);
|
Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args());
|
||||||
try {
|
try {
|
||||||
m_events->adoptHandler(
|
m_events->adoptHandler(
|
||||||
m_events->forServer().disconnected(), server,
|
m_events->forServer().disconnected(), server,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
ServerArgs::ServerArgs() :
|
ServerArgs::ServerArgs() :
|
||||||
m_configFile(),
|
m_configFile(),
|
||||||
|
m_serial(),
|
||||||
m_config(NULL)
|
m_config(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "synergy/ArgsBase.h"
|
#include "synergy/ArgsBase.h"
|
||||||
|
#include "shared/SerialKey.h"
|
||||||
|
|
||||||
class NetworkAddress;
|
class NetworkAddress;
|
||||||
class Config;
|
class Config;
|
||||||
|
@ -28,5 +29,6 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
String m_configFile;
|
String m_configFile;
|
||||||
|
SerialKey m_serial;
|
||||||
Config* m_config;
|
Config* m_config;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* synergy -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015 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 "base/String.h"
|
|
||||||
|
|
||||||
struct SubscriptionKey {
|
|
||||||
String m_name;
|
|
||||||
String m_type;
|
|
||||||
String m_email;
|
|
||||||
String m_company;
|
|
||||||
int m_userLimit;
|
|
||||||
int m_warnTime;
|
|
||||||
int m_expireTime;
|
|
||||||
};
|
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* synergy -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015 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 "synergy/SubscriptionManager.h"
|
|
||||||
|
|
||||||
#include "synergy/XSynergy.h"
|
|
||||||
#include "arch/Arch.h"
|
|
||||||
#include "base/Log.h"
|
|
||||||
#include "base/String.h"
|
|
||||||
#include "common/Version.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
#include <ctime>
|
|
||||||
//#include <stdexcept>
|
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
|
||||||
const char* kFile = "Synergy.subkey";
|
|
||||||
#else
|
|
||||||
const char* kFile = ".synergy.subkey";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// SubscriptionManager
|
|
||||||
//
|
|
||||||
|
|
||||||
SubscriptionManager::SubscriptionManager() :
|
|
||||||
m_key()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SubscriptionManager::checkFile(const String& filename_)
|
|
||||||
{
|
|
||||||
String filename = filename_;
|
|
||||||
if (filename.empty()) {
|
|
||||||
filename = getFilename();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream stream(filename.c_str());
|
|
||||||
if (!stream.is_open()) {
|
|
||||||
throw XSubscription(synergy::string::sprintf(
|
|
||||||
"Could not open, path=%s", filename.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
String serial;
|
|
||||||
stream >> serial;
|
|
||||||
|
|
||||||
String plainText = decode(serial);
|
|
||||||
parsePlainSerial(plainText, m_key);
|
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "subscription is valid"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SubscriptionManager::activate(const String& serial)
|
|
||||||
{
|
|
||||||
String plainText = decode(serial);
|
|
||||||
parsePlainSerial(plainText, m_key);
|
|
||||||
|
|
||||||
String filename = getFilename();
|
|
||||||
std::ofstream stream(filename.c_str());
|
|
||||||
if (!stream.is_open()) {
|
|
||||||
throw XSubscription(synergy::string::sprintf(
|
|
||||||
"Could not open, file=%s", filename.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
stream << serial << std::endl;
|
|
||||||
LOG((CLOG_DEBUG "subscription file created, path=%s", filename.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
String
|
|
||||||
SubscriptionManager::decode(const String& input)
|
|
||||||
{
|
|
||||||
static const char* const lut = "0123456789ABCDEF";
|
|
||||||
size_t len = input.length();
|
|
||||||
if (len & 1) {
|
|
||||||
throw XSubscription("Invalid serial, wrong length.");
|
|
||||||
}
|
|
||||||
|
|
||||||
String output;
|
|
||||||
output.reserve(len / 2);
|
|
||||||
for (size_t i = 0; i < len; i += 2) {
|
|
||||||
|
|
||||||
char a = input[i];
|
|
||||||
char b = input[i + 1];
|
|
||||||
|
|
||||||
const char* p = std::lower_bound(lut, lut + 16, a);
|
|
||||||
const char* q = std::lower_bound(lut, lut + 16, b);
|
|
||||||
|
|
||||||
if (*q != b || *p != a) {
|
|
||||||
throw XSubscription("Invalid serial, unrecognized digit.");
|
|
||||||
}
|
|
||||||
|
|
||||||
output.push_back(static_cast<char>(((p - lut) << 4) | (q - lut)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SubscriptionManager::parsePlainSerial(const String& plainText, SubscriptionKey& key)
|
|
||||||
{
|
|
||||||
String serial;
|
|
||||||
String parityStart = plainText.substr(0, 1);
|
|
||||||
String parityEnd = plainText.substr(plainText.length() - 1, 1);
|
|
||||||
|
|
||||||
// check for parity chars { and }, record parity result, then remove them.
|
|
||||||
if (parityStart == "{" && parityEnd == "}") {
|
|
||||||
serial = plainText.substr(1, plainText.length() - 2);
|
|
||||||
|
|
||||||
// tokenize serialised subscription.
|
|
||||||
std::vector<String> parts;
|
|
||||||
std::string::size_type pos = 0;
|
|
||||||
bool look = true;
|
|
||||||
while (look) {
|
|
||||||
std::string::size_type start = pos;
|
|
||||||
pos = serial.find(";", pos);
|
|
||||||
if (pos == String::npos) {
|
|
||||||
pos = plainText.length();
|
|
||||||
look = false;
|
|
||||||
}
|
|
||||||
parts.push_back(serial.substr(start, pos - start));
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// e.g.: {v1;trial;Bob;1;email;company name;1398297600;1398384000}
|
|
||||||
if ((parts.size() == 8)
|
|
||||||
&& (parts.at(0).find("v1") != String::npos)) {
|
|
||||||
key.m_type = parts.at(1);
|
|
||||||
key.m_name = parts.at(2);
|
|
||||||
sscanf(parts.at(3).c_str(), "%d", &key.m_userLimit);
|
|
||||||
key.m_email = parts.at(4);
|
|
||||||
key.m_company = parts.at(5);
|
|
||||||
sscanf(parts.at(6).c_str(), "%d", &key.m_warnTime);
|
|
||||||
sscanf(parts.at(7).c_str(), "%d", &key.m_expireTime);
|
|
||||||
|
|
||||||
// only limit to trial version
|
|
||||||
if (key.m_type == "trial") {
|
|
||||||
if (time(0) > key.m_expireTime) {
|
|
||||||
throw XSubscription("trial has expired");
|
|
||||||
}
|
|
||||||
else if (time(0) > key.m_warnTime) {
|
|
||||||
int secLeft = key.m_expireTime - static_cast<int>(time(0));
|
|
||||||
const int spd = 60 * 60 * 24;
|
|
||||||
int dayLeft = secLeft / spd + 1;
|
|
||||||
LOG((CLOG_NOTE "trial will end in %d %s",
|
|
||||||
dayLeft,
|
|
||||||
dayLeft == 1 ? "day" : "days"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* userText = (key.m_userLimit == 1) ? "user" : "users";
|
|
||||||
LOG((CLOG_INFO "%s subscription valid is for %d %s, registered to %s",
|
|
||||||
key.m_type.c_str(),
|
|
||||||
key.m_userLimit,
|
|
||||||
userText,
|
|
||||||
key.m_name.c_str()));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw XSubscription(synergy::string::sprintf("Serial is invalid."));
|
|
||||||
}
|
|
||||||
|
|
||||||
String
|
|
||||||
SubscriptionManager::getFilename()
|
|
||||||
{
|
|
||||||
String path = ARCH->getProfileDirectory();
|
|
||||||
path = ARCH->concatPath(path, kFile);
|
|
||||||
if (path.empty()) {
|
|
||||||
throw XSubscription("Could not get filename.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SubscriptionManager::printFilename()
|
|
||||||
{
|
|
||||||
std::cout << getFilename() << std::endl;
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* synergy -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015 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 "SubscriptionKey.h"
|
|
||||||
#include "common/common.h"
|
|
||||||
|
|
||||||
#include "gtest/gtest_prod.h"
|
|
||||||
|
|
||||||
class SubscriptionManager {
|
|
||||||
public:
|
|
||||||
SubscriptionManager();
|
|
||||||
|
|
||||||
//! Check the subscription activation file
|
|
||||||
void checkFile(const String& filename);
|
|
||||||
|
|
||||||
//! Create a subscription activation file based on a serial
|
|
||||||
void activate(const String& serial);
|
|
||||||
|
|
||||||
//! Use standard output to return subscription filename to gui
|
|
||||||
void printFilename();
|
|
||||||
|
|
||||||
private:
|
|
||||||
FRIEND_TEST(SubscriptionTests, decode_invalidLength_throwException);
|
|
||||||
FRIEND_TEST(SubscriptionTests, decode_invalidSerial_outputPlainText);
|
|
||||||
FRIEND_TEST(SubscriptionTests, decode_unrecognizedDigit_throwException);
|
|
||||||
FRIEND_TEST(SubscriptionTests, parsePlainSerial_noParity_throwException);
|
|
||||||
FRIEND_TEST(SubscriptionTests, parsePlainSerial_invalidSerial_throwException);
|
|
||||||
FRIEND_TEST(SubscriptionTests, parsePlainSerial_validSerial_validSubscriptionKey);
|
|
||||||
FRIEND_TEST(SubscriptionTests, parsePlainSerial_expiredTrialSerial_throwException);
|
|
||||||
FRIEND_TEST(SubscriptionTests, parsePlainSerial_expiredBasicSerial_validSubscriptionKey);
|
|
||||||
FRIEND_TEST(SubscriptionTests, parsePlainSerial_validSerialWithoutCompany_validSubscriptionKey);
|
|
||||||
|
|
||||||
private:
|
|
||||||
String decode(const String& input);
|
|
||||||
void parsePlainSerial(const String& plainText, SubscriptionKey& key);
|
|
||||||
String getFilename();
|
|
||||||
|
|
||||||
SubscriptionKey m_key;
|
|
||||||
};
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "synergy/ToolApp.h"
|
#include "synergy/ToolApp.h"
|
||||||
|
|
||||||
#include "synergy/ArgParser.h"
|
#include "synergy/ArgParser.h"
|
||||||
#include "synergy/SubscriptionManager.h"
|
|
||||||
#include "arch/Arch.h"
|
#include "arch/Arch.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/String.h"
|
#include "base/String.h"
|
||||||
|
@ -72,50 +71,17 @@ ToolApp::run(int argc, char** argv)
|
||||||
else if (m_args.m_loginAuthenticate) {
|
else if (m_args.m_loginAuthenticate) {
|
||||||
loginAuth();
|
loginAuth();
|
||||||
}
|
}
|
||||||
else if (m_args.m_getPluginList) {
|
|
||||||
getPluginList();
|
|
||||||
}
|
|
||||||
else if (m_args.m_getInstalledDir) {
|
else if (m_args.m_getInstalledDir) {
|
||||||
std::cout << ARCH->getInstalledDirectory() << std::endl;
|
std::cout << ARCH->getInstalledDirectory() << std::endl;
|
||||||
}
|
}
|
||||||
else if (m_args.m_getPluginDir) {
|
|
||||||
std::cout << ARCH->getPluginDirectory() << std::endl;
|
|
||||||
}
|
|
||||||
else if (m_args.m_getProfileDir) {
|
else if (m_args.m_getProfileDir) {
|
||||||
std::cout << ARCH->getProfileDirectory() << std::endl;
|
std::cout << ARCH->getProfileDirectory() << std::endl;
|
||||||
}
|
}
|
||||||
else if (m_args.m_getArch) {
|
else if (m_args.m_getArch) {
|
||||||
std::cout << ARCH->getPlatformName() << std::endl;
|
std::cout << ARCH->getPlatformName() << std::endl;
|
||||||
}
|
}
|
||||||
else if (!m_args.m_subscriptionSerial.empty()) {
|
else if (m_args.m_notifyUpdate) {
|
||||||
try {
|
notifyUpdate();
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
subscriptionManager.activate(m_args.m_subscriptionSerial);
|
|
||||||
}
|
|
||||||
catch (XSubscription& e) {
|
|
||||||
LOG((CLOG_CRIT "subscription error: %s", e.what()));
|
|
||||||
return kExitSubscription;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_args.m_getSubscriptionFilename) {
|
|
||||||
try {
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
subscriptionManager.printFilename();
|
|
||||||
}
|
|
||||||
catch (XSubscription& e) {
|
|
||||||
LOG((CLOG_CRIT "subscription error: %s", e.what()));
|
|
||||||
return kExitSubscription;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_args.m_checkSubscription) {
|
|
||||||
try {
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
subscriptionManager.checkFile("");
|
|
||||||
}
|
|
||||||
catch (XSubscription& e) {
|
|
||||||
LOG((CLOG_CRIT "subscription error: %s", e.what()));
|
|
||||||
return kExitSubscription;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (m_args.m_notifyActivation) {
|
else if (m_args.m_notifyActivation) {
|
||||||
notifyActivation();
|
notifyActivation();
|
||||||
|
@ -172,8 +138,26 @@ ToolApp::loginAuth()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ToolApp::getPluginList()
|
ToolApp::notifyUpdate()
|
||||||
{
|
{
|
||||||
|
String data;
|
||||||
|
std::cin >> data;
|
||||||
|
|
||||||
|
std::vector<String> parts = synergy::string::splitString(data, ':');
|
||||||
|
size_t count = parts.size();
|
||||||
|
|
||||||
|
if (count == 3) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << JSON_URL << "notify/update";
|
||||||
|
ss << "?from=" << parts[0];
|
||||||
|
ss << "&to=" << parts[1];
|
||||||
|
ss << "&serial=" << parts[2];
|
||||||
|
|
||||||
|
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw XSynergy("Invalid update data.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -29,8 +29,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loginAuth();
|
void loginAuth();
|
||||||
void getPluginList();
|
|
||||||
void notifyActivation();
|
void notifyActivation();
|
||||||
|
void notifyUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ToolArgs m_args;
|
ToolArgs m_args;
|
||||||
|
|
|
@ -20,14 +20,10 @@
|
||||||
ToolArgs::ToolArgs() :
|
ToolArgs::ToolArgs() :
|
||||||
m_printActiveDesktopName(false),
|
m_printActiveDesktopName(false),
|
||||||
m_loginAuthenticate(false),
|
m_loginAuthenticate(false),
|
||||||
m_getPluginList(false),
|
|
||||||
m_getPluginDir(false),
|
|
||||||
m_getInstalledDir(false),
|
m_getInstalledDir(false),
|
||||||
m_getProfileDir(false),
|
m_getProfileDir(false),
|
||||||
m_getArch(false),
|
m_getArch(false),
|
||||||
m_getSubscriptionFilename(false),
|
|
||||||
m_checkSubscription(false),
|
|
||||||
m_notifyActivation(false),
|
m_notifyActivation(false),
|
||||||
m_subscriptionSerial()
|
m_notifyUpdate(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,9 @@ public:
|
||||||
public:
|
public:
|
||||||
bool m_printActiveDesktopName;
|
bool m_printActiveDesktopName;
|
||||||
bool m_loginAuthenticate;
|
bool m_loginAuthenticate;
|
||||||
bool m_getPluginList;
|
|
||||||
bool m_getPluginDir;
|
|
||||||
bool m_getInstalledDir;
|
bool m_getInstalledDir;
|
||||||
bool m_getProfileDir;
|
bool m_getProfileDir;
|
||||||
bool m_getArch;
|
bool m_getArch;
|
||||||
bool m_getSubscriptionFilename;
|
|
||||||
bool m_checkSubscription;
|
|
||||||
bool m_notifyActivation;
|
bool m_notifyActivation;
|
||||||
String m_subscriptionSerial;
|
bool m_notifyUpdate;
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,7 +129,9 @@ TEST_F(NetworkTests, sendToClient_mockData)
|
||||||
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
||||||
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
||||||
|
|
||||||
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
|
ServerArgs serverArgs;
|
||||||
|
serverArgs.m_enableDragDrop = true;
|
||||||
|
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
|
||||||
server.m_mock = true;
|
server.m_mock = true;
|
||||||
listener.setServer(&server);
|
listener.setServer(&server);
|
||||||
|
|
||||||
|
@ -142,10 +144,10 @@ TEST_F(NetworkTests, sendToClient_mockData)
|
||||||
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
||||||
|
|
||||||
|
|
||||||
ClientArgs args;
|
ClientArgs clientArgs;
|
||||||
args.m_enableDragDrop = true;
|
clientArgs.m_enableDragDrop = true;
|
||||||
args.m_enableCrypto = false;
|
clientArgs.m_enableCrypto = false;
|
||||||
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
|
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
|
||||||
|
|
||||||
m_events.adoptHandler(
|
m_events.adoptHandler(
|
||||||
m_events.forFile().fileRecieveCompleted(), &client,
|
m_events.forFile().fileRecieveCompleted(), &client,
|
||||||
|
@ -185,7 +187,9 @@ TEST_F(NetworkTests, sendToClient_mockFile)
|
||||||
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
||||||
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
||||||
|
|
||||||
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
|
ServerArgs serverArgs;
|
||||||
|
serverArgs.m_enableDragDrop = true;
|
||||||
|
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
|
||||||
server.m_mock = true;
|
server.m_mock = true;
|
||||||
listener.setServer(&server);
|
listener.setServer(&server);
|
||||||
|
|
||||||
|
@ -198,10 +202,10 @@ TEST_F(NetworkTests, sendToClient_mockFile)
|
||||||
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
||||||
|
|
||||||
|
|
||||||
ClientArgs args;
|
ClientArgs clientArgs;
|
||||||
args.m_enableDragDrop = true;
|
clientArgs.m_enableDragDrop = true;
|
||||||
args.m_enableCrypto = false;
|
clientArgs.m_enableCrypto = false;
|
||||||
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
|
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
|
||||||
|
|
||||||
m_events.adoptHandler(
|
m_events.adoptHandler(
|
||||||
m_events.forFile().fileRecieveCompleted(), &client,
|
m_events.forFile().fileRecieveCompleted(), &client,
|
||||||
|
@ -235,7 +239,9 @@ TEST_F(NetworkTests, sendToServer_mockData)
|
||||||
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
||||||
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
||||||
|
|
||||||
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
|
ServerArgs serverArgs;
|
||||||
|
serverArgs.m_enableDragDrop = true;
|
||||||
|
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
|
||||||
server.m_mock = true;
|
server.m_mock = true;
|
||||||
listener.setServer(&server);
|
listener.setServer(&server);
|
||||||
|
|
||||||
|
@ -247,10 +253,10 @@ TEST_F(NetworkTests, sendToServer_mockData)
|
||||||
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
|
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
|
||||||
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
||||||
|
|
||||||
ClientArgs args;
|
ClientArgs clientArgs;
|
||||||
args.m_enableDragDrop = true;
|
clientArgs.m_enableDragDrop = true;
|
||||||
args.m_enableCrypto = false;
|
clientArgs.m_enableCrypto = false;
|
||||||
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
|
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
|
||||||
|
|
||||||
m_events.adoptHandler(
|
m_events.adoptHandler(
|
||||||
m_events.forClientListener().connected(), &listener,
|
m_events.forClientListener().connected(), &listener,
|
||||||
|
@ -290,7 +296,9 @@ TEST_F(NetworkTests, sendToServer_mockFile)
|
||||||
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
|
||||||
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
|
||||||
|
|
||||||
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
|
ServerArgs serverArgs;
|
||||||
|
serverArgs.m_enableDragDrop = true;
|
||||||
|
Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
|
||||||
server.m_mock = true;
|
server.m_mock = true;
|
||||||
listener.setServer(&server);
|
listener.setServer(&server);
|
||||||
|
|
||||||
|
@ -302,10 +310,10 @@ TEST_F(NetworkTests, sendToServer_mockFile)
|
||||||
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
|
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
|
||||||
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
|
||||||
|
|
||||||
ClientArgs args;
|
ClientArgs clientArgs;
|
||||||
args.m_enableDragDrop = true;
|
clientArgs.m_enableDragDrop = true;
|
||||||
args.m_enableCrypto = false;
|
clientArgs.m_enableCrypto = false;
|
||||||
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
|
Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
|
||||||
|
|
||||||
m_events.adoptHandler(
|
m_events.adoptHandler(
|
||||||
m_events.forClientListener().connected(), &listener,
|
m_events.forClientListener().connected(), &listener,
|
||||||
|
|
|
@ -68,4 +68,4 @@ endif()
|
||||||
|
|
||||||
add_executable(unittests ${sources})
|
add_executable(unittests ${sources})
|
||||||
target_link_libraries(unittests
|
target_link_libraries(unittests
|
||||||
arch base client server common io net platform server synergy mt ipc gtest gmock ${libs} ${OPENSSL_LIBS})
|
arch base client server common io net platform server synergy mt ipc gtest gmock shared ${libs} ${OPENSSL_LIBS})
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2016 Symless 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TEST_ENV
|
||||||
|
|
||||||
|
#include "shared/SerialKey.h"
|
||||||
|
|
||||||
|
#include "test/global/gtest.h"
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, decode_empty_returnEmptyString)
|
||||||
|
{
|
||||||
|
std::string plainText = SerialKey::decode("");
|
||||||
|
EXPECT_EQ(0, plainText.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, decode_invalidDigit_returnEmptyString)
|
||||||
|
{
|
||||||
|
std::string plainText = SerialKey::decode("MOCKZ");
|
||||||
|
EXPECT_EQ(0, plainText.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, decode_validSerial_returnPlainText)
|
||||||
|
{
|
||||||
|
std::string plainText = SerialKey::decode("53796E6572677920726F636B7321");
|
||||||
|
EXPECT_EQ("Synergy rocks!", plainText);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, parse_noParty_invalid)
|
||||||
|
{
|
||||||
|
SerialKey serial;
|
||||||
|
bool r = serial.parse("MOCK");
|
||||||
|
EXPECT_FALSE(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, parse_invalidPartsLenghth_invalid)
|
||||||
|
{
|
||||||
|
SerialKey serial;
|
||||||
|
bool r = serial.parse("{Synergy;Rocks}");
|
||||||
|
EXPECT_FALSE(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, parse_validV1Serial_valid)
|
||||||
|
{
|
||||||
|
SerialKey serial;
|
||||||
|
bool r = serial.parse("{v1;basic;Bob;1;email;company name;0;86400}");
|
||||||
|
EXPECT_EQ(true, r);
|
||||||
|
EXPECT_EQ(kBasic, serial.edition());
|
||||||
|
EXPECT_FALSE(serial.isExpired(0));
|
||||||
|
EXPECT_EQ(true, serial.daysLeft(0));
|
||||||
|
EXPECT_FALSE(serial.isExpiring(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, parse_validV2Serial_valid)
|
||||||
|
{
|
||||||
|
SerialKey serial;
|
||||||
|
bool r = serial.parse("{v2;trial;pro;Bob;1;email;company name;0;86400}");
|
||||||
|
EXPECT_EQ(true, r);
|
||||||
|
EXPECT_EQ(kPro, serial.edition());
|
||||||
|
EXPECT_FALSE(serial.isExpired(0));
|
||||||
|
EXPECT_EQ(true, serial.daysLeft(0));
|
||||||
|
EXPECT_EQ(true, serial.isExpiring(1));
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;1;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B313B38363430307D");
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
EXPECT_FALSE(serial.isExpiring(0));
|
||||||
|
EXPECT_EQ(kBasic, serial.edition());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, isExpiring_expiringV2TrialBasicSerial_returnTrue)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
EXPECT_EQ(true, serial.isExpiring(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, isExpiring_expiredV2TrialBasicSerial_returnFalse)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
EXPECT_FALSE(serial.isExpiring(86401));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, isExpired_validV2TrialBasicSerial_returnFalse)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
EXPECT_FALSE(serial.isExpired(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, isExpired_expiringV2TrialBasicSerial_returnFalse)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
EXPECT_FALSE(serial.isExpired(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, isExpired_expiredV2TrialBasicSerial_returnTrue)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(true, serial.isTrial());
|
||||||
|
EXPECT_EQ(true, serial.isExpired(86401));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, daysLeft_validExactlyOneDayV2TrialBasicSerial_returnOne)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(1, serial.daysLeft(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, daysLeft_validWithinOneDayV2TrialBasicSerial_returnOne)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(1, serial.daysLeft(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SerialKeyTests, daysLeft_expiredV2TrialBasicSerial_returnZero)
|
||||||
|
{
|
||||||
|
// {v2;trial;basic;Bob;1;email;company name;0;86400}
|
||||||
|
SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
|
||||||
|
EXPECT_EQ(0, serial.daysLeft(86401));
|
||||||
|
}
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* synergy -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015 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 "synergy/SubscriptionManager.h"
|
|
||||||
#include "synergy/XSynergy.h"
|
|
||||||
|
|
||||||
#include "test/global/gtest.h"
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, decode_invalidLength_throwException)
|
|
||||||
{
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String serial("ABC");
|
|
||||||
|
|
||||||
EXPECT_THROW(subscriptionManager.decode(serial), XSubscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, decode_unrecognizedDigit_throwException)
|
|
||||||
{
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String serial("MOCK");
|
|
||||||
|
|
||||||
EXPECT_THROW(subscriptionManager.decode(serial), XSubscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, parsePlainSerial_noParity_throwException)
|
|
||||||
{
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String painText("MOCK");
|
|
||||||
SubscriptionKey key;
|
|
||||||
|
|
||||||
EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, parsePlainSerial_invalidSerial_throwException)
|
|
||||||
{
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String painText("{MOCK}");
|
|
||||||
SubscriptionKey key;
|
|
||||||
|
|
||||||
EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, parsePlainSerial_validSerial_validSubscriptionKey)
|
|
||||||
{
|
|
||||||
// valid until 2 March 2049
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String painText("{v1;trial;Bob;1;a@a.a;mock company;2147483647;2147483647}");
|
|
||||||
SubscriptionKey key;
|
|
||||||
subscriptionManager.parsePlainSerial(painText, key);
|
|
||||||
|
|
||||||
EXPECT_EQ("trial", key.m_type);
|
|
||||||
EXPECT_EQ("Bob", key.m_name);
|
|
||||||
EXPECT_EQ(1, key.m_userLimit);
|
|
||||||
EXPECT_EQ("a@a.a", key.m_email);
|
|
||||||
EXPECT_EQ("mock company", key.m_company);
|
|
||||||
EXPECT_EQ(2147483647, key.m_warnTime);
|
|
||||||
EXPECT_EQ(2147483647, key.m_expireTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, parsePlainSerial_validSerialWithoutCompany_validSubscriptionKey)
|
|
||||||
{
|
|
||||||
// valid until 2 March 2049
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String painText("{v1;trial;Bob;1;a@a.a;;2147483647;2147483647}");
|
|
||||||
SubscriptionKey key;
|
|
||||||
subscriptionManager.parsePlainSerial(painText, key);
|
|
||||||
|
|
||||||
EXPECT_EQ("trial", key.m_type);
|
|
||||||
EXPECT_EQ("Bob", key.m_name);
|
|
||||||
EXPECT_EQ(1, key.m_userLimit);
|
|
||||||
EXPECT_EQ("a@a.a", key.m_email);
|
|
||||||
EXPECT_EQ("", key.m_company);
|
|
||||||
EXPECT_EQ(2147483647, key.m_warnTime);
|
|
||||||
EXPECT_EQ(2147483647, key.m_expireTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, parsePlainSerial_expiredTrialSerial_throwException)
|
|
||||||
{
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String painText("{v1;trial;Bob;1;1398297600;1398384000}");
|
|
||||||
SubscriptionKey key;
|
|
||||||
|
|
||||||
EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SubscriptionTests, parsePlainSerial_expiredBasicSerial_validSubscriptionKey)
|
|
||||||
{
|
|
||||||
SubscriptionManager subscriptionManager;
|
|
||||||
String painText("{v1;basic;Bob;1;a@a.a;mock company;1398297600;1398384000}");
|
|
||||||
SubscriptionKey key;
|
|
||||||
subscriptionManager.parsePlainSerial(painText, key);
|
|
||||||
|
|
||||||
EXPECT_EQ("basic", key.m_type);
|
|
||||||
EXPECT_EQ("Bob", key.m_name);
|
|
||||||
EXPECT_EQ(1, key.m_userLimit);
|
|
||||||
EXPECT_EQ("a@a.a", key.m_email);
|
|
||||||
EXPECT_EQ("mock company", key.m_company);
|
|
||||||
EXPECT_EQ(1398297600, key.m_warnTime);
|
|
||||||
EXPECT_EQ(1398384000, key.m_expireTime);
|
|
||||||
}
|
|
Loading…
Reference in New Issue