Compare commits

...

36 Commits
v1.6 ... master

Author SHA1 Message Date
Skylar Ittner 6391d9261d Update jQuery to fix SNYK-JS-JQUERY-174006 4 years ago
Skylar Ittner 5dd6ec9403 Update version code 5 years ago
Skylar Ittner c617940c40 Update netsyms.com api url 5 years ago
Skylar Ittner c1ffdc7a5d Update version number 5 years ago
Skylar Ittner d006684147 Fix bug where account switching failed to actually switch accounts 5 years ago
Skylar Ittner 07614c76f6 Fix Android resource issue 6 years ago
Skylar Ittner 5c549225c7 Bump version 2.0 => 2.0.1 6 years ago
Skylar Ittner 36acd0ff06 Allow business account setup without pairing code, close #16, close #21 6 years ago
Skylar Ittner 7963613cd3 Further improve setup UX 6 years ago
Skylar Ittner 136e7fa660 Add back buttons to setup pages 6 years ago
Skylar Ittner ae9fdb2654 Improve L&F, fix bug with secure connection checkbox 6 years ago
Skylar Ittner 21479f2940 Add loading error screen 6 years ago
Skylar Ittner e808b7bbf7 Replace testing URL with actual URL 6 years ago
Skylar Ittner f48ab5e6b9 Remove old app data, rename project, update logo 6 years ago
Skylar Ittner c340976cf8 Update README.md, remove unused images 6 years ago
Skylar Ittner 177831374a Fix status bar text color 6 years ago
Skylar Ittner 35f1e10b7c Fix "Error: null" message 6 years ago
Skylar Ittner dd772dba93 Change package name and bump version to 2.0 6 years ago
Skylar Ittner 9ce6a31d18 Cleanup java 6 years ago
Skylar Ittner c5bc67a257 Rebrand to "Netsyms Apps" 6 years ago
Skylar Ittner 8b5edbd369 Add setup for personal netsyms.com accounts (close #15) 6 years ago
Skylar Ittner 4345405b78 Fix Java imports 6 years ago
Skylar Ittner b59171a0b9 Fix home screen bug, add account switcher (close #19, close #20) 6 years ago
Skylar Ittner 44a0da1f2b Make script tags work when inside pages 6 years ago
Skylar Ittner 2c3092ecb4 Add notification manager to home page 6 years ago
Skylar Ittner 6f79fb7b2a Improve settings, add OTP countdown 6 years ago
Skylar Ittner ee5e2b4a50 Add some settings and credits 6 years ago
Skylar Ittner ba185f32b3 Add pull to refresh on home screen 6 years ago
Skylar Ittner 21c5113b88 Fix back button behavior 6 years ago
Skylar Ittner 5691744543 Improve manual OTP UX 6 years ago
Skylar Ittner d7c00945a7 Add OTP feature to redesign 6 years ago
Skylar Ittner 0b85c8a7f6 Working: initial setup tool, app list, using Apps 6 years ago
Skylar Ittner d248aa5934 Use Java background task for fetching notifications, close #18 6 years ago
Skylar Ittner 9cb914512b Backup user data to NativeStorage 6 years ago
Skylar Ittner 675248dfd3 Add background notification checking and display (close #17) 6 years ago
Skylar Ittner 27a0904ec7 Fix version number 6 years ago

4
.gitignore vendored

@ -1,4 +1,6 @@
nbproject/private nbproject/private
platforms platforms
plugins plugins
node_modules node_modules
/www/old/
build.json

@ -1,23 +1,23 @@
Business Mobile Netsyms Mobile
=============== ===============
A mobile app for easy and secure access to the Business Apps on the go. A mobile app for easy and secure access to the Netsyms Apps on the go.
https://netsyms.biz/apps/bizmobile https://netsyms.biz/apps/netsymsmobile
Features Features
-------- --------
**Simple Pairing** **Simple Pairing**
Scan a QR code displayed in AccountHub with the app, enter your password, and Scan a QR code displayed in AccountHub with the app, enter your password, and
everything is setup automatically. everything is setup automatically.
**Full Access** **Full Access**
Access all features of all Business Apps from one place. Access all features of all Netsyms Apps from one place.
**Barcode Scanning** **Barcode Scanning**
Use your device camera to scan barcodes into BinStack and other apps. Use your device camera to scan barcodes into BinStack and other apps.
**Secure** **Secure**
If the device is lost, Apps access can be revoked from AccountHub by deleting the If the device is lost, Apps access can be revoked from AccountHub by deleting the
pairing code. pairing code.

@ -1,10 +1,10 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<widget id="com.netsyms.BusinessMobile" version="1.6" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <widget id="com.netsyms.apps.Mobile" version="2.0.3" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Business</name> <name>Netsyms</name>
<description> <description>
Mobile client for the Netsyms Business Apps. Securely use the Netsyms Apps from your phone or tablet.
</description> </description>
<author email="admin@netsyms.com" href="https://netsyms.com"> <author email="skylar@netsyms.com" href="https://netsyms.com">
Netsyms Technologies Netsyms Technologies
</author> </author>
<content src="index.html" /> <content src="index.html" />
@ -26,10 +26,14 @@
<preference name="SplashMaintainAspectRatio" value="true" /> <preference name="SplashMaintainAspectRatio" value="true" />
<preference name="HeaderColor" value="#2196f3" /> <preference name="HeaderColor" value="#2196f3" />
<preference name="StatusBarBackgroundColor" value="#1976d2" /> <preference name="StatusBarBackgroundColor" value="#1976d2" />
<preference name="stopOnTerminate" value="false" />
<preference name="startOnBoot" value="true" />
<preference name="forceReload" value="true" />
<preference name="minimumFetchInterval" value="1" />
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application"> <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
<application android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" /> <application android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" />
</edit-config> </edit-config>
<resource-file src="res/android/values/ic_launcher_background.xml" target="app/src/main/res/values/ic_launcher_background.xml" /> <resource-file src="res/android/drawable/ic_launcher_background.xml" target="app/src/main/res/drawable/ic_launcher_background.xml" />
<resource-file src="res/android/drawable/ic_launcher_foreground.xml" target="app/src/main/res/drawable/ic_launcher_foreground.xml" /> <resource-file src="res/android/drawable/ic_launcher_foreground.xml" target="app/src/main/res/drawable/ic_launcher_foreground.xml" />
<resource-file src="res/android/mipmap-anydpi-v26/ic_launcher.xml" target="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" /> <resource-file src="res/android/mipmap-anydpi-v26/ic_launcher.xml" target="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" />
<resource-file src="res/android/mipmap-anydpi-v26/ic_launcher_round.xml" target="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" /> <resource-file src="res/android/mipmap-anydpi-v26/ic_launcher_round.xml" target="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" />
@ -43,6 +47,11 @@
<resource-file src="res/android/mipmap-xxhdpi/ic_launcher_round.png" target="app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png" /> <resource-file src="res/android/mipmap-xxhdpi/ic_launcher_round.png" target="app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png" />
<resource-file src="res/android/mipmap-xxxhdpi/ic_launcher.png" target="app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" /> <resource-file src="res/android/mipmap-xxxhdpi/ic_launcher.png" target="app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" />
<resource-file src="res/android/mipmap-xxxhdpi/ic_launcher_round.png" target="app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png" /> <resource-file src="res/android/mipmap-xxxhdpi/ic_launcher_round.png" target="app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png" />
<resource-file src="res/android/drawable-hdpi/ic_notification.png" target="app/src/main/res/drawable-hdpi/ic_notification.png" />
<resource-file src="res/android/drawable-mdpi/ic_notification.png" target="app/src/main/res/drawable-mdpi/ic_notification.png" />
<resource-file src="res/android/drawable-xhdpi/ic_notification.png" target="app/src/main/res/drawable-xhdpi/ic_notification.png" />
<resource-file src="res/android/drawable-xxhdpi/ic_notification.png" target="app/src/main/res/drawable-xxhdpi/ic_notification.png" />
<resource-file src="src/android/BackgroundFetchHeadlessTask.java" target="app/src/main/java/com/transistorsoft/cordova/backgroundfetch/BackgroundFetchHeadlessTask.java" />
<splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" /> <splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" />
<splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" /> <splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" />
<splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" /> <splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" />
@ -57,13 +66,13 @@
<splash density="land-xxxhdpi" src="res/screen/android/splash-land-xxxhdpi.png" /> <splash density="land-xxxhdpi" src="res/screen/android/splash-land-xxxhdpi.png" />
</platform> </platform>
<preference name="AutoHideSplashScreen" value="false" /> <preference name="AutoHideSplashScreen" value="false" />
<plugin name="cordova-plugin-add-swift-support" spec="^1.7.1" /> <plugin name="cordova-plugin-whitelist" spec="^1.3.2" />
<plugin name="cordova-plugin-headercolor" spec="^1.0.0" />
<plugin name="cordova-plugin-app-version" spec="^0.1.9" /> <plugin name="cordova-plugin-app-version" spec="^0.1.9" />
<plugin name="cordova-plugin-file" spec="^6.0.1" /> <plugin name="cordova-plugin-file" spec="^6.0.1" />
<plugin name="cordova-plugin-headercolor" spec="^1.0.0" /> <plugin name="cordova-plugin-add-swift-support" spec="^1.7.1" />
<plugin name="cordova-plugin-statusbar" spec="^2.4.1" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.2" />
<plugin name="cordova-plugin-zeroconf" spec="^1.3.1" /> <plugin name="cordova-plugin-zeroconf" spec="^1.3.1" />
<plugin name="cordova-plugin-statusbar" spec="^2.4.1" />
<plugin name="phonegap-plugin-barcodescanner" spec="^7.1.0"> <plugin name="phonegap-plugin-barcodescanner" spec="^7.1.0">
<variable name="ANDROID_SUPPORT_V4_VERSION" value="27.+" /> <variable name="ANDROID_SUPPORT_V4_VERSION" value="27.+" />
</plugin> </plugin>
@ -72,5 +81,9 @@
<plugin name="cordova-plugin-dialogs" spec="^2.0.1" /> <plugin name="cordova-plugin-dialogs" spec="^2.0.1" />
<plugin name="cordova-plugin-inappbrowser" spec="^2.0.2" /> <plugin name="cordova-plugin-inappbrowser" spec="^2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="^5.0.2" /> <plugin name="cordova-plugin-splashscreen" spec="^5.0.2" />
<engine name="android" spec="^7.1.0" /> <plugin name="cordova-plugin-nativestorage" spec="^2.3.2" />
<plugin name="cordova-plugin-local-notification" spec="^0.9.0-beta.2" />
<plugin name="cordova-plugin-background-fetch" spec="^5.4.1" />
<engine name="browser" spec="^5.0.4" />
<engine name="android" spec="^7.1.2" />
</widget> </widget>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 25 KiB

@ -46,7 +46,7 @@ made subject to such option by the copyright holder.
<!-- <!--
Generated file; DO NOT EDIT. Generated file; DO NOT EDIT.
--> -->
<project name="BusinessMobile" basedir=".."> <project name="NetsymsMobile" basedir="..">
<property file="nbproject/configs/${config}.properties" /> <property file="nbproject/configs/${config}.properties" />
<scriptdef name="checkVersion" language="javascript"> <scriptdef name="checkVersion" language="javascript">
@ -59,7 +59,7 @@ made subject to such option by the copyright holder.
} }
]]> ]]>
</scriptdef> </scriptdef>
<scriptdef name="forDevice" language="javascript"> <scriptdef name="forDevice" language="javascript">
<![CDATA[ <![CDATA[
var dev = project.getProperty("device"); var dev = project.getProperty("device");
@ -77,7 +77,7 @@ made subject to such option by the copyright holder.
</or> </or>
</condition> </condition>
</target> </target>
<target name="upgrade-to-cordova-project" depends="check-cordova-project,check-cordova-version" unless="cordova.project"> <target name="upgrade-to-cordova-project" depends="check-cordova-project,check-cordova-version" unless="cordova.project">
<echo level="info" message="${cordova.command} -d create ${java.io.tmpdir}/nb_temp_project com.coolappz.${project.name} ${project.name}" /> <echo level="info" message="${cordova.command} -d create ${java.io.tmpdir}/nb_temp_project com.coolappz.${project.name} ${project.name}" />
<delete dir="${java.io.tmpdir}/nb_temp_project"/> <delete dir="${java.io.tmpdir}/nb_temp_project"/>
@ -85,8 +85,8 @@ made subject to such option by the copyright holder.
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/> <env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/> <env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/> <arg value="-d"/>
<arg value="create"/> <arg value="create"/>
<arg value="${java.io.tmpdir}/nb_temp_project"/> <arg value="${java.io.tmpdir}/nb_temp_project"/>
<arg value="com.coolappz.${project.name}"/> <arg value="com.coolappz.${project.name}"/>
<arg value="${project.name}" /> <arg value="${project.name}" />
</exec> </exec>
@ -106,8 +106,8 @@ made subject to such option by the copyright holder.
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/> <env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/> <env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/> <arg value="-d"/>
<arg value="create"/> <arg value="create"/>
<arg value="www_nb_temp"/> <arg value="www_nb_temp"/>
<arg value="com.coolappz.${project.name}"/> <arg value="com.coolappz.${project.name}"/>
<arg value="${project.name}" /> <arg value="${project.name}" />
</exec> </exec>
@ -117,26 +117,26 @@ made subject to such option by the copyright holder.
<delete dir="www_nb_temp"/> <delete dir="www_nb_temp"/>
<delete file="www/config.xml"/> <delete file="www/config.xml"/>
</target> </target>
<taskdef <taskdef
classname="org.netbeans.modules.cordova.updatetask.ReadConfigTask" classname="org.netbeans.modules.cordova.updatetask.ReadConfigTask"
classpath="${update.task.jar}" classpath="${update.task.jar}"
name="readconfig"/> name="readconfig"/>
<taskdef <taskdef
classname="org.netbeans.modules.cordova.updatetask.PluginTask" classname="org.netbeans.modules.cordova.updatetask.PluginTask"
classpath="${update.task.jar}" classpath="${update.task.jar}"
name="plugintask"/> name="plugintask"/>
<target name="check-cordova-version"> <target name="check-cordova-version">
<property environment="env"/> <property environment="env"/>
<checkVersion first="${cordova.version}" property="cordova.ver.3"/> <checkVersion first="${cordova.version}" property="cordova.ver.3"/>
<fail message="Cordova version 3 or greater required." unless="cordova.ver.3"/> <fail message="Cordova version 3 or greater required." unless="cordova.ver.3"/>
<readconfig/> <readconfig/>
<forDevice/> <forDevice/>
</target> </target>
<target name="check-android-template"> <target name="check-android-template">
<available file="platforms/android" property="android.generated.exists"/> <available file="platforms/android" property="android.generated.exists"/>
</target> </target>
@ -144,27 +144,27 @@ made subject to such option by the copyright holder.
<target name="check-ios-template"> <target name="check-ios-template">
<available file="platforms/ios" property="ios.generated.exists"/> <available file="platforms/ios" property="ios.generated.exists"/>
</target> </target>
<target name="create-android" depends="check-android-template,check-cordova-version,upgrade-to-cordova-project" unless="android.generated.exists"> <target name="create-android" depends="check-android-template,check-cordova-version,upgrade-to-cordova-project" unless="android.generated.exists">
<echo level="info" message="${cordova.command} -d platform add android"/> <echo level="info" message="${cordova.command} -d platform add android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true"> <exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/> <env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/> <env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/> <arg value="-d"/>
<arg value="platform"/> <arg value="platform"/>
<arg value="add"/> <arg value="add"/>
<arg value="android"/> <arg value="android"/>
</exec> </exec>
</target> </target>
<target name="create-ios" depends="check-ios-template,check-cordova-version,upgrade-to-cordova-project" unless="ios.generated.exists"> <target name="create-ios" depends="check-ios-template,check-cordova-version,upgrade-to-cordova-project" unless="ios.generated.exists">
<echo level="info" message="${cordova.command} -d platform add ios"/> <echo level="info" message="${cordova.command} -d platform add ios"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" dir="." failonerror="true"> <exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" dir="." failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/> <env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/> <env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/> <arg value="-d"/>
<arg value="platform"/> <arg value="platform"/>
<arg value="add"/> <arg value="add"/>
<arg value="ios"/> <arg value="ios"/>
</exec> </exec>
</target> </target>
@ -178,23 +178,23 @@ made subject to such option by the copyright holder.
<exec executable="xcodebuild" dir="platforms/ios" failonerror="true"> <exec executable="xcodebuild" dir="platforms/ios" failonerror="true">
<arg value="-project"/> <arg value="-project"/>
<arg value="${project.name}.xcodeproj"/> <arg value="${project.name}.xcodeproj"/>
<arg value="ARCHS=${ios.build.arch}"/> <arg value="ARCHS=${ios.build.arch}"/>
<arg value="-target"/> <arg value="-target"/>
<arg value="${project.name}"/> <arg value="${project.name}"/>
<arg value="-configuration"/> <arg value="-configuration"/>
<arg value="Release"/> <arg value="Release"/>
<arg value="-sdk"/> <arg value="-sdk"/>
<arg value="${ios.build.sdk}" /> <arg value="${ios.build.sdk}" />
<arg value="build"/> <arg value="build"/>
<arg value="CONFIGURATION_BUILD_DIR=${path}"/> <arg value="CONFIGURATION_BUILD_DIR=${path}"/>
</exec> </exec>
</target> </target>
<target name="build-ios-ipa" if="build.for.device"> <target name="build-ios-ipa" if="build.for.device">
<exec executable="xcrun" dir="platforms/ios/build" failonerror="true"> <exec executable="xcrun" dir="platforms/ios/build" failonerror="true">
<env key="CODESIGN_ALLOCATE" value="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate" /> <env key="CODESIGN_ALLOCATE" value="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate" />
<arg value="-sdk"/> <arg value="-sdk"/>
<arg value="${ios.build.sdk}" /> <arg value="${ios.build.sdk}" />
<arg value="PackageApplication"/> <arg value="PackageApplication"/>
<arg value="-v"/> <arg value="-v"/>
<arg value="${project.name}.app"/> <arg value="${project.name}.app"/>
@ -208,15 +208,15 @@ made subject to such option by the copyright holder.
<available file="${basedir}/platforms/ios/build/${project.name}.ipa" property="ipa.found"/> <available file="${basedir}/platforms/ios/build/${project.name}.ipa" property="ipa.found"/>
<fail unless="ipa.found" message="PackageApplication failed."/> <fail unless="ipa.found" message="PackageApplication failed."/>
</target> </target>
<target name="sim-ios" depends="build-ios,ios-run-device,ios-run-simulator"> <target name="sim-ios" depends="build-ios,ios-run-device,ios-run-simulator">
</target> </target>
<target name="ios-run-device" if="build.for.device"> <target name="ios-run-device" if="build.for.device">
<echo> <echo>
Install "${basedir}/platforms/ios/build/${project.name}.ipa" through iTunes and run it. Install "${basedir}/platforms/ios/build/${project.name}.ipa" through iTunes and run it.
</echo> </echo>
<exec executable="open" failonerror="true"> <exec executable="open" failonerror="true">
<arg value="${basedir}/platforms/ios/build/${project.name}.ipa"/> <arg value="${basedir}/platforms/ios/build/${project.name}.ipa"/>
</exec> </exec>
@ -228,13 +228,13 @@ made subject to such option by the copyright holder.
</exec> </exec>
<exec executable="${ios.sim.exec}" dir="platforms/ios/build"> <exec executable="${ios.sim.exec}" dir="platforms/ios/build">
<arg line="launch ${project.name}.app ${ios.device.args} --exit"/> <arg line="launch ${project.name}.app ${ios.device.args} --exit"/>
</exec> </exec>
</target> </target>
<target name="update-plugins"> <target name="update-plugins">
<plugintask/> <plugintask/>
</target> </target>
<target name="update-android"> <target name="update-android">
<echo level="info" message="${cordova.command} prepare android"/> <echo level="info" message="${cordova.command} prepare android"/>
@ -244,9 +244,9 @@ made subject to such option by the copyright holder.
<arg value="prepare"/> <arg value="prepare"/>
<arg value="android"/> <arg value="android"/>
</exec> </exec>
</target> </target>
<target name="update-ios"> <target name="update-ios">
<echo level="info" message="${cordova.command} prepare ios"/> <echo level="info" message="${cordova.command} prepare ios"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true"> <exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
@ -255,21 +255,21 @@ made subject to such option by the copyright holder.
<arg value="prepare"/> <arg value="prepare"/>
<arg value="ios"/> <arg value="ios"/>
</exec> </exec>
</target> </target>
<target name="rebuild-android" depends="clean-android,build-android"/> <target name="rebuild-android" depends="clean-android,build-android"/>
<target name="build-android" depends="create-android,update-plugins"> <target name="build-android" depends="create-android,update-plugins">
<echo level="info" message="${cordova.command} -d build android"/> <echo level="info" message="${cordova.command} -d build android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true"> <exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/> <env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/> <env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/> <arg value="-d"/>
<arg value="build"/> <arg value="build"/>
<arg value="android"/> <arg value="android"/>
</exec> </exec>
</target> </target>
<target name="sim-android" depends="create-android,update-plugins"> <target name="sim-android" depends="create-android,update-plugins">
<echo level="info" message="${cordova.command} -d ${android.target.device.arg} android"/> <echo level="info" message="${cordova.command} -d ${android.target.device.arg} android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true"> <exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
@ -277,16 +277,16 @@ made subject to such option by the copyright holder.
<env key="JAVA_HOME" path="${jdk.home}"/> <env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/> <arg value="-d"/>
<arg value="${android.target.device.arg}"/> <arg value="${android.target.device.arg}"/>
<arg value="android"/> <arg value="android"/>
</exec> </exec>
</target> </target>
<target name="clean-android" depends="check-android-template" if="android.generated.exists"> <target name="clean-android" depends="check-android-template" if="android.generated.exists">
<exec executable="./gradlew" dir="platforms/android"> <exec executable="./gradlew" dir="platforms/android">
<arg value="clean" /> <arg value="clean" />
</exec> </exec>
</target> </target>
<target name="clean-ios" depends="check-ios-template" if="ios.generated.exists"> <target name="clean-ios" depends="check-ios-template" if="ios.generated.exists">
<exec executable="platforms/ios/cordova/clean" /> <exec executable="platforms/ios/cordova/clean" />
</target> </target>

@ -9,4 +9,7 @@ cordova-plugin-headercolor=https://github.com/tomloprod/cordova-plugin-headercol
cordova-plugin-inappbrowser=https://github.com/apache/cordova-plugin-inappbrowser.git cordova-plugin-inappbrowser=https://github.com/apache/cordova-plugin-inappbrowser.git
cordova-plugin-app-version=https://github.com/whiteoctober/cordova-plugin-app-version.git cordova-plugin-app-version=https://github.com/whiteoctober/cordova-plugin-app-version.git
cordova-plugin-zeroconf=https://github.com/becvert/cordova-plugin-zeroconf.git cordova-plugin-zeroconf=https://github.com/becvert/cordova-plugin-zeroconf.git
cordova-plugin-file=https://github.com/apache/cordova-plugin-file.git cordova-plugin-file=https://github.com/apache/cordova-plugin-file.git
cordova-plugin-local-notification=https://github.com/katzer/cordova-plugin-local-notifications.git
cordova-plugin-background-fetch=https://github.com/transistorsoft/cordova-plugin-background-fetch.git
cordova-plugin-nativestorage=https://github.com/TheCocoaProject/cordova-plugin-nativestorage.git

@ -1,8 +1,8 @@
auxiliary.org-netbeans-modules-cordova.cordova_5f_build_5f_script_5f_version=52 auxiliary.org-netbeans-modules-cordova.cordova_5f_build_5f_script_5f_version=52
auxiliary.org-netbeans-modules-cordova.phonegap=false auxiliary.org-netbeans-modules-cordova.phonegap=false
file.reference.BusinessMobile-test=test file.reference.NetsymsMobile-test=test
file.reference.BusinessMobile-www=www file.reference.NetsymsMobile-www=www
files.encoding=UTF-8 files.encoding=UTF-8
project.licensePath=./nbproject/mplheader.txt project.licensePath=nbproject/mplheader.txt
site.root.folder=${file.reference.BusinessMobile-www} site.root.folder=${file.reference.NetsymsMobile-www}
test.folder=${file.reference.BusinessMobile-test} test.folder=${file.reference.NetsymsMobile-test}

@ -3,7 +3,7 @@
<type>org.netbeans.modules.web.clientproject</type> <type>org.netbeans.modules.web.clientproject</type>
<configuration> <configuration>
<data xmlns="http://www.netbeans.org/ns/clientside-project/1"> <data xmlns="http://www.netbeans.org/ns/clientside-project/1">
<name>BusinessMobile</name> <name>NetsymsMobile</name>
</data> </data>
</configuration> </configuration>
</project> </project>

@ -1,15 +1,18 @@
{ {
"name": "com.netsyms.BusinessMobile", "name": "com.netsyms.apps.Mobile",
"displayName": "Business for Mobile", "displayName": "Netsyms Apps for Mobile",
"version": "1.5.0", "version": "2.0.1",
"description": "Mobile client for the Netsyms Business Apps.", "description": "Securely use the Netsyms Apps from your phone or tablet.",
"main": "index.html", "main": "index.html",
"author": "Netsyms Technologies", "author": "Netsyms Technologies",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"cordova-android": "^7.1.0", "cordova-android": "^7.1.2",
"cordova-browser": "^5.0.4",
"cordova-plugin-add-swift-support": "^1.7.1", "cordova-plugin-add-swift-support": "^1.7.1",
"cordova-plugin-app-version": "^0.1.9", "cordova-plugin-app-version": "^0.1.9",
"cordova-plugin-background-fetch": "^5.4.1",
"cordova-plugin-badge": "^0.8.7",
"cordova-plugin-console": "^1.1.0", "cordova-plugin-console": "^1.1.0",
"cordova-plugin-device": "^2.0.1", "cordova-plugin-device": "^2.0.1",
"cordova-plugin-dialog": "0.0.1", "cordova-plugin-dialog": "0.0.1",
@ -17,6 +20,8 @@
"cordova-plugin-file": "^6.0.1", "cordova-plugin-file": "^6.0.1",
"cordova-plugin-headercolor": "^1.0.0", "cordova-plugin-headercolor": "^1.0.0",
"cordova-plugin-inappbrowser": "^2.0.2", "cordova-plugin-inappbrowser": "^2.0.2",
"cordova-plugin-local-notification": "^0.9.0-beta.2",
"cordova-plugin-nativestorage": "^2.3.2",
"cordova-plugin-splashscreen": "^5.0.2", "cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-statusbar": "^2.4.1", "cordova-plugin-statusbar": "^2.4.1",
"cordova-plugin-whitelist": "^1.3.2", "cordova-plugin-whitelist": "^1.3.2",
@ -39,9 +44,13 @@
"cordova-plugin-device": {}, "cordova-plugin-device": {},
"cordova-plugin-dialogs": {}, "cordova-plugin-dialogs": {},
"cordova-plugin-inappbrowser": {}, "cordova-plugin-inappbrowser": {},
"cordova-plugin-splashscreen": {} "cordova-plugin-splashscreen": {},
"cordova-plugin-nativestorage": {},
"cordova-plugin-local-notification": {},
"cordova-plugin-background-fetch": {}
}, },
"platforms": [ "platforms": [
"browser",
"android" "android"
] ]
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="60"
android:viewportHeight="60">
<group android:translateX="6"
android:translateY="6">
<path
android:pathData="M0,0h48v48h-48z"
android:strokeAlpha="0"
android:strokeWidth="8.06694221"
android:fillColor="#0d87f6"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="m18.9031,9.2872c-0.1596,0.014 -0.3055,0.044 -0.4348,0.093 -2.0694,0.7831 -4.1011,7.8462 -5.0107,9.8633 -0.9096,2.017 -4.8582,8.2167 -4.0752,10.2861 0.7831,2.0694 7.8463,4.1011 9.8633,5.0106 2.0171,0.9097 8.2167,4.8583 10.2861,4.0752 2.0694,-0.7831 4.1011,-7.8462 5.0107,-9.8632 0.9096,-2.0171 4.8583,-8.2168 4.0752,-10.2862 -0.7831,-2.0694 -7.8462,-4.1011 -9.8633,-5.0106 -1.8909,-0.8528 -7.4577,-4.3768 -9.8513,-4.1686z"
android:strokeAlpha="1"
android:strokeWidth="0.61330891"
android:fillColor="#0d87f6"
android:strokeColor="#ffffff"
android:fillAlpha="1"/>
</group>
</vector>

@ -1,44 +1,44 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp" android:width="108dp"
android:height="108dp" android:height="108dp"
android:viewportWidth="798.444" android:viewportWidth="1163.6364"
android:viewportHeight="792.0944"> android:viewportHeight="1163.6364">
<group android:translateX="206.33473" <group android:translateX="325.81818"
android:translateY="194.06314"> android:translateY="325.81818">
<path <path
android:pathData="M111.7,150.1L172,150.1A12.9,12.9 60.8,0 1,184.8 162.9L184.8,391.1A12.9,12.9 0,0 1,172 404L111.7,404A12.9,12.9 130.2,0 1,98.9 391.1L98.9,162.9A12.9,12.9 52.1,0 1,111.7 150.1z" android:pathData="m198.563,65.838c-0.615,0 -1.144,-0 -1.572,0.158 -3.427,1.296 -6.794,12.993 -8.3,16.335 -1.506,3.341 -8.046,13.593 -6.749,17.021 1.297,3.426 12.995,6.793 16.335,8.3 3.341,1.506 13.615,8.046 17.042,6.749 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.342 8.046,-13.614 6.749,-17.042 -1.297,-3.427 -12.992,-6.794 -16.332,-8.3 -2.923,-1.318 -11.166,-6.475 -15.473,-6.883zM151.95,146.228c-0.615,0 -1.144,-0 -1.572,0.158 -3.427,1.296 -6.794,12.991 -8.3,16.332 -1.506,3.34 -8.046,13.594 -6.749,17.021 1.297,3.428 12.995,6.794 16.335,8.3 3.341,1.506 13.593,8.049 17.021,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.046,-13.614 6.749,-17.042 -1.297,-3.428 -12.995,-6.794 -16.335,-8.3 -2.923,-1.318 -11.142,-6.475 -15.448,-6.883zM237.163,147.843c-0.615,0 -1.141,0.013 -1.569,0.137 -3.427,1.296 -6.794,12.991 -8.3,16.332 -1.506,3.34 -8.049,13.617 -6.752,17.045 1.297,3.427 12.995,6.79 16.335,8.297 3.341,1.506 13.593,8.049 17.021,6.752 3.427,-1.296 6.794,-12.993 8.3,-16.335 1.506,-3.341 8.046,-13.614 6.749,-17.042 -1.297,-3.427 -12.992,-6.794 -16.332,-8.3 -2.923,-1.319 -11.145,-6.487 -15.452,-6.883zM422.045,160.701c-0.615,0 -1.144,0.013 -1.572,0.137 -3.427,1.298 -6.794,12.992 -8.3,16.332 -1.506,3.341 -8.046,13.618 -6.749,17.045 1.297,3.427 12.995,6.794 16.335,8.3 3.341,1.507 13.615,8.046 17.042,6.749 3.427,-1.296 6.794,-12.992 8.3,-16.332 1.506,-3.341 8.049,-13.618 6.752,-17.045 -1.297,-3.427 -12.995,-6.793 -16.335,-8.3 -2.923,-1.318 -11.166,-6.475 -15.473,-6.883zM240.757,227.406c-0.615,0 -1.141,0.01 -1.569,0.134 -3.427,1.298 -6.794,12.996 -8.3,16.338 -1.506,3.34 -8.049,13.614 -6.752,17.042 1.297,3.426 12.995,6.794 16.335,8.3 3.341,1.506 13.615,8.047 17.042,6.749 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.341 8.049,-13.616 6.752,-17.042 -1.297,-3.428 -12.995,-6.793 -16.335,-8.3 -2.923,-1.318 -11.166,-6.475 -15.473,-6.883zM113.407,226.65c-0.615,0 -1.165,-0 -1.594,0.158 -3.427,1.296 -6.794,12.993 -8.3,16.335 -1.506,3.341 -8.025,13.594 -6.728,17.021 1.297,3.427 12.992,6.792 16.332,8.3 3.341,1.506 13.593,8.046 17.021,6.749 3.427,-1.296 6.794,-12.991 8.3,-16.332 1.506,-3.341 8.049,-13.596 6.752,-17.024 -1.297,-3.427 -12.995,-6.79 -16.335,-8.297 -2.923,-1.317 -11.142,-6.511 -15.448,-6.908zM385.081,239.476c-0.615,0 -1.165,-0 -1.594,0.158 -3.427,1.298 -6.794,12.991 -8.3,16.332 -1.506,3.34 -8.025,13.593 -6.728,17.021 1.297,3.427 12.995,6.794 16.335,8.3 3.341,1.507 13.593,8.05 17.021,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.046,-13.594 6.749,-17.021 -1.297,-3.428 -12.992,-6.794 -16.332,-8.3 -2.923,-1.319 -11.145,-6.508 -15.451,-6.905zM74.772,311.831c-0.615,0 -1.144,0.01 -1.572,0.134 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.34 -8.049,13.614 -6.752,17.042 1.297,3.428 12.995,6.794 16.335,8.3 3.341,1.506 13.618,8.049 17.045,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.025,-13.615 6.728,-17.042 -1.297,-3.428 -12.995,-6.794 -16.335,-8.3 -2.923,-1.319 -11.142,-6.475 -15.448,-6.883zM253.233,311.831c-0.615,0 -1.144,0.01 -1.572,0.134 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.34 -8.046,13.614 -6.749,17.042 1.297,3.428 12.995,6.794 16.335,8.3 3.341,1.506 13.615,8.049 17.042,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.046,-13.615 6.749,-17.042 -1.297,-3.428 -12.992,-6.794 -16.332,-8.3 -2.923,-1.319 -11.166,-6.475 -15.473,-6.883zM338.482,317.478c-0.615,0 -1.144,0.013 -1.572,0.137 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.341 -8.046,13.614 -6.749,17.042 1.297,3.426 12.995,6.794 16.335,8.3 3.341,1.506 13.615,8.05 17.042,6.752 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.341 8.046,-13.616 6.749,-17.042 -1.297,-3.428 -12.992,-6.792 -16.332,-8.3 -2.923,-1.317 -11.166,-6.475 -15.473,-6.883zM298.975,397.426c-0.615,0 -1.165,-0 -1.594,0.158 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.341 -8.049,13.594 -6.752,17.021 1.297,3.427 12.995,6.794 16.335,8.3 3.341,1.506 13.618,8.05 17.045,6.752 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.341 8.046,-13.594 6.749,-17.021 -1.297,-3.428 -12.995,-6.794 -16.335,-8.3 -2.923,-1.318 -11.142,-6.511 -15.448,-6.908z"
android:strokeColor="#00000000" android:strokeAlpha="1"
android:fillAlpha="0.39215686" android:strokeWidth="11.33235741"
android:fillColor="#ffffff" android:fillColor="#ffffff"
android:strokeWidth="5" android:strokeColor="#00000000"
android:strokeAlpha="1"/> android:fillAlpha="1"/>
<path <path
android:pathData="M212.8,211.2L273,211.2A12.9,12.9 60.8,0 1,285.8 224L285.8,391.1A12.9,12.9 0,0 1,273 404L212.8,404A12.9,12.9 119.2,0 1,199.9 391.1L199.9,224A12.9,12.9 0,0 1,212.8 211.2z" android:pathData="M-2521.377,-590.781l531.981,230.764l-141.472,326.136l-531.981,-230.764z"
android:strokeColor="#00000000" android:strokeAlpha="1"
android:fillAlpha="0.39215686" android:strokeWidth="11.87444973"
android:fillColor="#ffffff" android:fillColor="#78bff8"
android:strokeWidth="5" android:strokeColor="#00000000"
android:strokeAlpha="1"/> android:fillAlpha="1"/>
<path <path
android:pathData="M12.9,262.7L73.1,262.7A12.9,12.9 128.5,0 1,85.9 275.5L85.9,391.1A12.9,12.9 128.5,0 1,73.1 404L12.9,404A12.9,12.9 129.4,0 1,-0 391.1L-0,275.5A12.9,12.9 129.4,0 1,12.9 262.7z" android:pathData="M-1810.385,-660.711l-531.981,-230.764l141.472,-326.136l531.981,230.764z"
android:strokeColor="#00000000" android:strokeAlpha="1"
android:fillAlpha="0.39215686" android:strokeWidth="11.87444973"
android:fillColor="#ffffff" android:fillColor="#78bff8"
android:strokeWidth="5" android:strokeColor="#00000000"
android:strokeAlpha="1"/> android:fillAlpha="1"/>
<path <path
android:pathData="M312.7,-0L372.9,-0A12.9,12.9 53.5,0 1,385.8 12.9L385.8,391.1A12.9,12.9 0,0 1,372.9 404L312.7,404A12.9,12.9 0,0 1,299.9 391.1L299.9,12.9A12.9,12.9 53.5,0 1,312.7 -0z" android:pathData="M-2146.024,-292.892l230.764,-531.981l326.136,141.472l-230.764,531.981z"
android:strokeColor="#00000000" android:strokeAlpha="1"
android:fillAlpha="0.39215686" android:strokeWidth="11.87444973"
android:fillColor="#ffffff" android:fillColor="#78bff8"
android:strokeWidth="5" android:strokeColor="#00000000"
android:strokeAlpha="1"/> android:fillAlpha="1"/>
<path <path
android:pathData="m147.8,51.5a18.8,18.8 108.7,0 0,-18.8 18.7,18.8 18.8,58.3 0,0 2.3,9L57.3,263.8a18.8,18.8 59.3,0 0,-15.9 18.5,18.8 18.8,0 0,0 18.7,18.8 18.8,18.8 78.9,0 0,18.8 -18.7,18.8 18.8,59.3 0,0 -4,-11.6l71.6,-179 76,230a18.8,18.8 110.6,0 0,-4.3 11.9,18.8 18.8,122.9 0,0 18.7,18.8 18.8,18.8 74.2,0 0,18.8 -18.7,18.8 18.8,60.9 0,0 -6,-13.7L327,146.7a18.8,18.8 0,0 0,17.4 -18.7,18.8 18.8,61.1 0,0 -18.7,-18.8 18.8,18.8 61.1,0 0,-18.8 18.7,18.8 18.8,108.7 0,0 3.1,10.4L236.5,303.5 163,81.1a18.8,18.8 104.1,0 0,3.5 -10.8,18.8 18.8,108.7 0,0 -18.7,-18.8z" android:pathData="M-2786.024,-572.892l230.764,-531.981l326.136,141.472l-230.764,531.981z"
android:fillAlpha="1" android:strokeAlpha="1"
android:strokeColor="#d8edff" android:strokeWidth="11.87444973"
android:fillColor="#d8edff" android:fillColor="#78bff8"
android:strokeWidth="6.59239769" android:strokeColor="#00000000"
android:strokeAlpha="1"/> android:fillAlpha="1"/>
</group> </group>
</vector> </vector>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#2196F3</color>
</resources>

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="app_name">Netsyms</string>
<string name="launcher_name">@string/app_name</string>
<string name="activity_name">@string/launcher_name</string>
</resources>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 57 KiB

@ -0,0 +1,171 @@
package com.transistorsoft.cordova.backgroundfetch;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.netsyms.apps.Mobile.MainActivity;
import com.netsyms.apps.Mobile.R;
import com.transistorsoft.tsbackgroundfetch.BackgroundFetch;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class BackgroundFetchHeadlessTask implements HeadlessTask {
private static final String PREFS_NAME = "NativeStorage";
private static final String KEY = "accounts";
private static String shownNotifications = "";
public final String NOTIFICATION_CHANNEL_ID = "background-channel-id";
public static String getValue(Context context, String key, String defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE);
return settings.getString(key, defaultValue);
}
/**
* https://stackoverflow.com/a/34691486
*
* @param urlString
* @return
* @throws IOException
*/
public static String getStringFromURL(String urlString) throws IOException {
HttpURLConnection urlConnection = null;
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
String jsonString = sb.toString();
return jsonString;
}
@Override
public void onFetch(Context context) {
Log.d(BackgroundFetch.TAG, "Notification Poller: onFetch");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
String accountjson = getValue(context, KEY, null).replaceAll("\\\\", "");
accountjson = accountjson.substring(1, accountjson.length() - 1);
//Log.d(BackgroundFetch.TAG, "Notification Poller: Account JSON: " + accountjson);
try {
JSONArray accounts = new JSONArray(accountjson);
for (int i = 0; i < accounts.length(); i++) {
try {
JSONObject acct = accounts.getJSONObject(i);
Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " URL: " + acct.getString("syncurl"));
String notificationString = getStringFromURL(acct.getString("syncurl") + "?key=" + acct.getString("key") + "&username=" + acct.getString("username") + "&action=checknotifications");
//Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON: " + notificationString);
JSONArray notifications = new JSONObject(notificationString).getJSONArray("notifications");
Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON parsed: " + notifications.length() + " notifications");
for (int j = 0; j < notifications.length(); j++) {
JSONObject notif = notifications.getJSONObject(j);
Log.d(BackgroundFetch.TAG, "Notification Poller: Procesing notification ID " + notif.getString("id") + " with title " + notif.getString("title"));
if (notif.getBoolean("seen") || shownNotifications.contains("|" + i + ":" + notif.getString("id") + "|")) {
continue;
}
Intent intent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder b = new NotificationCompat.Builder(context);
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(notif.getString("title"))
.setContentText(notif.getString("content"))
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setContentIntent(contentIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVisibility(Notification.VISIBILITY_PRIVATE);
// Create alternate notification for lockscreen
NotificationCompat.Builder lockb = new NotificationCompat.Builder(context);
if (notif.getBoolean("sensitive") == true) {
lockb
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Contents hidden")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
} else {
lockb
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(notif.getString("title"))
.setContentText(notif.getString("content"))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
}
b.setPublicVersion(lockb.build());
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Background Notifications";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
channel.enableLights(true);
channel.enableVibration(true);
channel.setLightColor(Color.rgb(33, 150, 243));
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
b.setChannelId(NOTIFICATION_CHANNEL_ID);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(Integer.parseInt(notif.getString("id")), b.build());
Log.d(BackgroundFetch.TAG, "Notification Poller: Shown notification " + notif.getString("id"));
shownNotifications += "|" + i + ":" + notif.getString("id") + "|";
}
} catch (Exception e) {
Log.d(BackgroundFetch.TAG, "Notification Poller: Exception: " + e.getMessage());
Log.d(BackgroundFetch.TAG, "Notification Poller: Stack trace: " + Log.getStackTraceString(e));
}
}
} catch (Exception e) {
Log.d(BackgroundFetch.TAG, "Notification Poller: Exception: " + e.getMessage());
Log.d(BackgroundFetch.TAG, "Notification Poller: Stack trace: " + Log.getStackTraceString(e));
} finally {
BackgroundFetch.getInstance(context).finish();
}
}
}
);
thread.start();
}
}

@ -15,6 +15,12 @@
display: initial; display: initial;
} }
@media screen and (max-width: 767px) {
#navbar-collapse {
display: none;
}
}
#swipe-nav { #swipe-nav {
display: none; display: none;
visibility: visible; visibility: visible;
@ -72,4 +78,42 @@
left: 0; left: 0;
background-color: rgba(0,0,0,0.5); background-color: rgba(0,0,0,0.5);
z-index: 9999998; z-index: 9999998;
}
#swipe-nav .swipe-list {
margin-top: 5px;
margin-bottom: 10px;
padding-left: 0px;
list-style-type: none;
padding: 3px;
}
#swipe-nav .swipe-list .nav-item {
color: #424242;
padding-top: 5px;
padding-bottom: 5px;
}
#swipe-nav .swipe-list .nav-item a:focus,a:active {
background-color: #e0e0e0;
}
#swipe-nav .swipe-list .nav-item i.fa {
font-size: 120%;
margin-right: 10px;
margin-left: 5px;
}
#swipe-nav .swipe-list .nav-item a {
display: inline-block;
color: #424242;
font-size: 110%;
text-decoration: none;
width: 100%;
padding-top: 15px;
padding-bottom: 15px;
}
#swipe-nav .swipe-list .nav-item a:hover {
text-decoration: none;
} }

@ -1,148 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html, body {
height: 100%;
}
.app-dock-container {
display: flex;
height: 100%;
}
.app-dock {
margin: 0 auto 10px auto;
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
align-items: center;
justify-content: center;
height: 100%;
}
.app-icon {
border: 1px solid grey;
border-radius: 20%;
}
.app-dock-item {
padding: 0px 10px 2px 10px;
min-width: 100px;
max-width: 50%;
width: 120px;
margin: 15px;
}
.app-dock-item p {
margin-bottom: 0px;
font-size: 120%;
color: #555;
}
.app-dock-item p img {
width: 80px;
height: 80px;
display: block;
background: url(../img/app-icon-bg.svg) no-repeat;
background-size: 90%;
background-position: 50%;
margin: 0 auto;
}
.app-dock-item p span {
display: block;
text-align: center;
}
/* https://stackoverflow.com/a/23536146 */
.navbar-collapse.collapse {
display: block!important;
}
.navbar-nav>li, .navbar-nav {
float: left !important;
}
.navbar-nav.navbar-right:last-child {
margin-right: -15px !important;
}
.navbar-right {
float: right!important;
}
/* /stackoverflow */
.nav {
color: white;
margin-right: 0px;
height: 30px;
margin-top: -4px;
font-size: 20px;
margin-left: 5px;
}
.navbar-right span {
color: white;
font-size: 18px;
margin-top: -4px;
}
.navbar-brand img {
margin-right: 15px;
height: 30px;
margin-top: -4px;
margin-left: -10px;
display: inline-block;
}
.navbar-right li a img {
height: 30px;
margin-top: 6px;
display: inline-block;
}
@media (min-width: 768px) {
.navbar-right {
margin-top: -6px;
}
.navbar-right li a img {
margin-top: -1px;
}
}
#manual_setup {
margin-top: 15px;
}
#navbar {
min-height: 56px;
}
.loading-text {
font-size: 18px;
}
.circle-btn {
display: flex;
align-items: center;
justify-content: center;
align-content: center;
border-radius: 50%;
height: 5rem;
width: 5rem;
position: fixed;
bottom: 0;
right: 0;
margin: 2rem;
z-index: 99999;
}
.circle-btn img {
height: 3rem;
width: 3rem;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,14 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
A tiny bit of CSS to inject into apps even if injectcode = false.
This hides items in the app with the class mobile-app-hide.
*/
.mobile-app-hide {
display: none;
visibility: hidden;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -1,29 +0,0 @@
/*
Roboto font family
Downloaded from Google Web Fonts
Apache 2.0 License
*/
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/Roboto-Light.ttf) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/Roboto-Regular.ttf) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 500;
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/Roboto-Medium.ttf) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/Roboto-Bold.ttf) format('truetype');
}

@ -1,76 +0,0 @@
/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
@media screen and (max-width: 767px) {
.navbar, .navbar-brand {
min-height: 56px;
height: 56px;
}
.navbar-brand {
font-size: 20px;
margin-top: -4px;
}
.navbar-toggle {
border: 0px solid white;
margin-top: 11px;
margin-bottom: 11px;
}
#navbar-collapse {
display: none;
}
button.navbar-toggle[data-toggle="collapse"] {
float: left;
margin-left: 15px;
}
.navbar-header .navbar-brand {
margin-left: -20px;
}
.navbar-header .navbar-brand img {
display: none;
}
}
#swipe-nav ul {
margin-bottom: 10px;
padding-left: 2px;
list-style-type: none;
padding: 3px;
}
#swipe-nav ul li {
color: #424242;
padding-top: 5px;
padding-bottom: 5px;
}
#swipe-nav ul li a:focus,a:active {
background-color: #e0e0e0;
}
#swipe-nav ul li i.fa {
font-size: 120%;
margin-right: 10px;
margin-left: 5px;
}
#swipe-nav ul li a {
display: inline-block;
color: #424242;
font-size: 110%;
text-decoration: none;
width: 100%;
padding-top: 10px;
padding-bottom: 10px;
}
#swipe-nav ul li a:hover {
text-decoration: none;
}

@ -1,48 +0,0 @@
/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
@media screen and (max-width: 767px) {
#navbar-collapse {
display: none;
}
}
#swipe-nav .swipe-list {
margin-top: 5px;
margin-bottom: 10px;
padding-left: 0px;
list-style-type: none;
padding: 3px;
}
#swipe-nav .swipe-list .nav-item {
color: #424242;
padding-top: 5px;
padding-bottom: 5px;
}
#swipe-nav .swipe-list .nav-item a:focus,a:active {
background-color: #e0e0e0;
}
#swipe-nav .swipe-list .nav-item i.fa {
font-size: 120%;
margin-right: 10px;
margin-left: 5px;
}
#swipe-nav .swipe-list .nav-item a {
display: inline-block;
color: #424242;
font-size: 110%;
text-decoration: none;
width: 100%;
padding-top: 15px;
padding-bottom: 15px;
}
#swipe-nav .swipe-list .nav-item a:hover {
text-decoration: none;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,31 @@
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: local('Material Icons'),
local('MaterialIcons-Regular'),
url(./MaterialIcons-Regular.woff2) format('woff2'),
url(./MaterialIcons-Regular.woff) format('woff');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
}

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>

Before

Width:  |  Height:  |  Size: 199 B

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="ic_arrow-back.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="10.125"
inkscape:cx="-6.0246914"
inkscape:cy="11.802469"
inkscape:current-layer="svg2" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path4" />
<path
d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"
id="path6"
style="fill:#ffffff;fill-opacity:1" />
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v2H8v2h8v-2h-2v-2h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H3V4h18v12z"/>
</svg>

Before

Width:  |  Height:  |  Size: 274 B

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 389 B

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
id="svg3421"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="ic_settings.svg">
<metadata
id="metadata3431">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3429" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview3427"
showgrid="false"
inkscape:zoom="33.083333"
inkscape:cx="11.969773"
inkscape:cy="12"
inkscape:current-layer="svg3421" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path3423" />
<path
d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"
id="path3425"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12.65 10C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 320 B

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -540.36)"><rect y="540.36" width="512" height="512" rx="50" ry="50" fill="#fff"/><g transform="translate(.61385 9.1477)"><g><rect x="145.69" y="726.61" width="100.27" height="296.34" rx="15" ry="15" fill="#1976d2"/><rect x="263.58" y="797.95" width="100.27" height="225" rx="15" ry="15" fill="#9e9e9e"/><rect x="30.27" y="858.02" width="100.27" height="164.93" rx="15" ry="15" fill="#9e9e9e"/><rect x="380.23" y="551.48" width="100.27" height="471.47" rx="15" ry="15" fill="#64b5f6"/></g><path transform="translate(0 540.36)" d="m195.89 55.102a24.749 24.749 0 0 0-24.816 24.682 24.749 24.749 0 0 0 3.0234 11.867l-97.42 243.43a24.749 24.749 0 0 0-21.021 24.383 24.749 24.749 0 0 0 24.68 24.816 24.749 24.749 0 0 0 24.816-24.682 24.749 24.749 0 0 0-5.2422-15.287l94.438-235.97 100.25 303.25a24.749 24.749 0 0 0-5.6309 15.625 24.749 24.749 0 0 0 24.68 24.816 24.749 24.749 0 0 0 24.816-24.68 24.749 24.749 0 0 0-7.8633-18.119l101.57-228.59a24.749 24.749 0 0 0 22.949-24.609 24.749 24.749 0 0 0-24.682-24.816 24.749 24.749 0 0 0-24.816 24.68 24.749 24.749 0 0 0 4.1055 13.689l-96.789 217.83-96.938-293.25a24.749 24.749 0 0 0 4.5781-14.248 24.749 24.749 0 0 0-24.682-24.816z" fill="#2196f3" stroke="#fff" stroke-width="7"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><rect y="-7.3828e-6" width="512" height="512" rx="70" ry="70" fill="#2196f3"/><path d="m198.56 65.838c-0.61516 0-1.1439-2.09e-4 -1.5723 0.15846-3.4273 1.2964-6.7936 12.993-8.3001 16.335-1.5064 3.3408-8.046 13.593-6.7492 17.021 1.2969 3.4258 12.995 6.7929 16.335 8.3001 3.3406 1.5061 13.615 8.0456 17.042 6.7492 3.4273-1.2964 6.7938-12.996 8.3001-16.335 1.5065-3.3419 8.0461-13.614 6.7492-17.042-1.297-3.4269-12.992-6.794-16.332-8.3001-2.9229-1.318-11.166-6.4753-15.473-6.8833zm-46.614 80.39c-0.61524 0-1.1438-1.9e-4 -1.5723 0.15845-3.4273 1.2964-6.7936 12.991-8.3001 16.332-1.5064 3.3397-8.046 13.594-6.7492 17.021 1.2969 3.428 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.593 8.0486 17.021 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5065-3.3396 8.0461-13.614 6.7492-17.042-1.2969-3.428-12.995-6.794-16.335-8.3001-2.9229-1.318-11.142-6.4753-15.448-6.8832zm85.213 1.6149c-0.61515 0-1.1409 0.0125-1.5692 0.13713-3.4273 1.2964-6.7936 12.991-8.3001 16.332-1.5064 3.3396-8.049 13.617-6.7522 17.045 1.2969 3.4269 12.995 6.7898 16.335 8.2971 3.3405 1.5061 13.593 8.0486 17.021 6.7522 3.4272-1.2964 6.7937-12.993 8.3001-16.335 1.5065-3.3408 8.0461-13.614 6.7492-17.042-1.2969-3.4269-12.992-6.794-16.332-8.3001-2.9229-1.3191-11.145-6.4866-15.452-6.8832zm184.88 12.858c-0.61527 0-1.1439 0.0125-1.5723 0.13712-3.4273 1.2976-6.7936 12.992-8.3001 16.332-1.5064 3.3408-8.046 13.618-6.7492 17.045 1.2969 3.4269 12.995 6.794 16.335 8.3001 3.3406 1.5072 13.615 8.0456 17.042 6.7492 3.4273-1.2964 6.7937-12.992 8.3001-16.332 1.5065-3.3408 8.0492-13.618 6.7522-17.045-1.2969-3.4269-12.995-6.7929-16.335-8.3001-2.9229-1.318-11.166-6.4753-15.473-6.8832zm-181.29 66.705c-0.61513 0-1.1408 0.01-1.5692 0.13401-3.4273 1.2976-6.7937 12.996-8.3001 16.338-1.5064 3.3397-8.0491 13.614-6.7522 17.042 1.2969 3.4258 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.615 8.0467 17.042 6.7492 3.4273-1.2964 6.7938-12.995 8.3001-16.335 1.5065-3.3408 8.0492-13.616 6.7522-17.042-1.2969-3.428-12.995-6.7929-16.335-8.3001-2.9229-1.318-11.166-6.4753-15.473-6.8832zm-127.35-0.75646c-0.61517 0-1.1652-2e-4 -1.5936 0.15845-3.4273 1.2964-6.7936 12.993-8.3001 16.335-1.5063 3.3408-8.0247 13.594-6.7279 17.021 1.297 3.4269 12.992 6.7918 16.332 8.3001 3.3405 1.5061 13.593 8.0456 17.021 6.7492 3.4273-1.2964 6.7937-12.991 8.3001-16.332 1.5065-3.3408 8.0492-13.596 6.7522-17.024-1.2969-3.4269-12.995-6.7899-16.335-8.2971-2.9229-1.3168-11.142-6.511-15.448-6.9076zm271.67 12.826c-0.61515 0-1.1652-2e-4 -1.5936 0.15845-3.4273 1.2976-6.7936 12.991-8.3001 16.332-1.5064 3.3396-8.0247 13.593-6.7278 17.021 1.297 3.4269 12.995 6.794 16.335 8.3001 3.3406 1.5072 13.593 8.0498 17.021 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5064-3.3397 8.0461-13.594 6.7492-17.021-1.2969-3.428-12.992-6.794-16.332-8.3001-2.9229-1.3191-11.145-6.5079-15.451-6.9046zm-310.31 72.355c-0.61524 0-1.1439 0.01-1.5723 0.13402-3.4273 1.2976-6.7936 12.994-8.3001 16.335-1.5064 3.3396-8.049 13.614-6.7522 17.042 1.297 3.428 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.618 8.0486 17.045 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5065-3.3396 8.0248-13.615 6.7279-17.042-1.2969-3.428-12.995-6.794-16.335-8.3001-2.9229-1.3191-11.142-6.4753-15.448-6.8833zm178.46 0c-0.61524 0-1.1439 0.01-1.5723 0.13402-3.4273 1.2976-6.7936 12.994-8.3001 16.335-1.5064 3.3396-8.046 13.614-6.7492 17.042 1.2969 3.428 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.615 8.0486 17.042 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5064-3.3396 8.0461-13.615 6.7492-17.042-1.2969-3.428-12.992-6.794-16.332-8.3001-2.9229-1.3191-11.166-6.4753-15.473-6.8833zm85.248 5.6469c-0.61526 0-1.1439 0.0125-1.5723 0.13712-3.4273 1.2976-6.7937 12.994-8.3001 16.335-1.5064 3.3408-8.046 13.614-6.7492 17.042 1.297 3.4258 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.615 8.0498 17.042 6.7522 3.4273-1.2964 6.7937-12.996 8.3001-16.335 1.5064-3.3408 8.0461-13.616 6.7492-17.042-1.2969-3.428-12.992-6.7918-16.332-8.3001-2.9229-1.3168-11.166-6.4753-15.473-6.8832zm-39.507 79.948c-0.61519 0-1.1652-2.1e-4 -1.5936 0.15843-3.4273 1.2976-6.7936 12.994-8.3001 16.335-1.5063 3.3408-8.0491 13.594-6.7522 17.021 1.2969 3.4269 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.618 8.0498 17.045 6.7522 3.4272-1.2964 6.7938-12.995 8.3001-16.335 1.5064-3.3408 8.0461-13.594 6.7492-17.021-1.2969-3.428-12.995-6.794-16.335-8.3001-2.9229-1.318-11.142-6.511-15.448-6.9076z" fill="#fff"/><g transform="translate(-2442.8 -889.49)" fill="#78bff8"><rect transform="rotate(23.45)" x="46.829" y="305.29" width="579.88" height="355.5"/><rect transform="rotate(203.45)" x="-671.27" y="41.806" width="579.88" height="355.5"/><rect transform="rotate(-66.55)" x="-429.2" y="509.73" width="579.88" height="355.5"/><rect transform="rotate(-66.55)" x="-427.02" y="-188.84" width="579.88" height="355.5"/></g></svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 135.47 135.47" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -161.53)"><g transform="translate(1.7769 -4.861)"><rect x="13.04" y="181.84" width="105.83" height="19.844" rx="5" ry="5" fill="#9e9e9e"/><circle cx="27.253" cy="191.77" r="4.8315" fill="#4caf50" stroke="#fff" stroke-width=".86719"/></g><g transform="translate(3.9123 -4.861)"><rect x="63.821" y="207.04" width="52.917" height="79.375" rx="5" ry="5" fill="#9e9e9e"/><circle cx="90.279" cy="254.57" r="4.8315" fill="#4caf50" stroke="#fff" stroke-width=".86719"/><path d="m77.311 224.06c9.4913 0.0175 18.983-0.0368 28.474 0.03 0.59908 0.13588-1.5556 0.0589-2.076 0.0891-9.0779 0.0278-18.156 0.0138-27.234 2e-3 -0.39246-0.0403-2.0443 0.0493-1.7494-0.0873 0.86063-0.0421 1.7242-0.0232 2.5851-0.0342zm0-9.2876h25.937c1.662 0 3 1.338 3 3v12.708c0 1.662-1.338 3-3 3h-25.937c-1.662 0-3-1.338-3-3v-12.708c0-1.662 1.338-3 3-3z" fill="none" stroke="#fff" stroke-width="1.1361"/><rect x="63.821" y="207.04" width="52.917" height="79.375" rx="5" ry="5" fill="#9e9e9e"/><circle cx="90.279" cy="254.57" r="4.8315" fill="#4caf50" stroke="#fff" stroke-width=".86719"/><path d="m77.311 224.06c9.4913 0.0175 18.983-0.0368 28.474 0.03 0.59908 0.13588-1.5556 0.0589-2.076 0.0891-9.0779 0.0278-18.156 0.0138-27.234 2e-3 -0.39246-0.0403-2.0443 0.0493-1.7494-0.0873 0.86063-0.0421 1.7242-0.0232 2.5851-0.0342zm0-9.2876h25.937c1.662 0 3 1.338 3 3v12.708c0 1.662-1.338 3-3 3h-25.937c-1.662 0-3-1.338-3-3v-12.708c0-1.662 1.338-3 3-3z" fill="none" stroke="#fff" stroke-width="1.1361"/></g><g><rect x="14.817" y="202.18" width="46.302" height="26.458" rx="5" ry="5" fill="#9e9e9e"/><circle cx="22.225" cy="221.06" r="2.3746" fill="#4caf50" stroke="#fff" stroke-width=".86719"/></g><g><rect x="14.817" y="233.68" width="46.302" height="47.869" rx="5" ry="5" fill="#9e9e9e"/><g transform="translate(-.0063038 -7.6294e-6)" fill="#4caf50" stroke="#fff" stroke-width=".86719"><circle cx="50.321" cy="257.62" r="2.3746"/><circle cx="37.974" cy="257.62" r="2.3746"/><circle cx="25.627" cy="257.62" r="2.3746"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="512"
height="512"
viewBox="0 0 512.00001 512.00001"
id="svg2"
version="1.1">
<defs
id="defs4">
<pattern
height="8.15625"
patternTransform="translate(201.25 133.47)"
patternUnits="userSpaceOnUse"
width="8.6875"
id="pattern6179">
<path
d="m1.9375 0.5c-0.8781 0.7454-1.4375 1.8526-1.4375 3.0938 0 2.2424 1.82 4.0624 4.0625 4.0624 1.5819 0 2.9541-0.9292 3.625-2.25-0.7084 0.6014-1.6237 1-2.625 1-2.2425 0-4.0625-1.82-4.0625-4.0624 0-0.6607 0.1573-1.2922 0.4375-1.8438z"
style="opacity:.32394;stroke-opacity:0;fill:#eeeeec"
id="path6174" />
</pattern>
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(0,-540.36216)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.74509804"
id="rect4726"
width="512"
height="512"
x="0"
y="540.36218"
rx="50"
ry="50" />
<g
transform="translate(0,-2.2617187e-5)"
id="layer1-9">
<g
transform="translate(0.61384869,9.1476514)"
id="g4610">
<g
style="fill:#dcdcdc;fill-opacity:1"
id="g4528">
<rect
y="726.60608"
x="145.6884"
height="296.34189"
width="100.27342"
id="rect4194-3"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
<rect
y="797.948"
x="263.57608"
height="225"
width="100.27342"
id="rect4194-6"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
<rect
y="858.0174"
x="30.26951"
height="164.93059"
width="100.27342"
id="rect4194-6-7"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
<rect
y="551.48108"
x="380.22937"
height="471.46692"
width="100.27342"
id="rect4194"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
</g>
<g
id="g4568">
<path
style="fill:#bce0fc;fill-opacity:1;stroke:#ffffff;stroke-width:7;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 195.89258,55.101562 a 24.748737,24.748737 0 0 0 -24.81641,24.681641 24.748737,24.748737 0 0 0 3.02344,11.867188 L 76.679688,335.07617 a 24.748737,24.748737 0 0 0 -21.021485,24.38281 24.748737,24.748737 0 0 0 24.679688,24.81641 24.748737,24.748737 0 0 0 24.816409,-24.68164 24.748737,24.748737 0 0 0 -5.242191,-15.28711 l 94.437501,-235.9707 100.24609,303.2539 a 24.748737,24.748737 0 0 0 -5.63086,15.625 24.748737,24.748737 0 0 0 24.67969,24.81641 24.748737,24.748737 0 0 0 24.81641,-24.67969 24.748737,24.748737 0 0 0 -7.86328,-18.11914 L 432.16602,180.64453 a 24.748737,24.748737 0 0 0 22.94921,-24.60937 24.748737,24.748737 0 0 0 -24.68164,-24.81641 24.748737,24.748737 0 0 0 -24.8164,24.67969 24.748737,24.748737 0 0 0 4.10547,13.68945 L 312.93359,387.41602 215.99609,94.166016 a 24.748737,24.748737 0 0 0 4.57813,-14.248047 24.748737,24.748737 0 0 0 -24.68164,-24.816407 z"
transform="translate(0,540.36219)"
id="circle4572" />
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
id="svg2"
viewBox="0 0 403.11311 352.57208"
height="352.57208"
width="403.11313">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-146.20776,-255.22513)"
id="layer1">
<path
id="rect4361"
d="m 347.66381,255.22727 c -2.39231,-0.0413 -4.73078,0.51333 -6.84028,1.73125 -0.17129,0.0989 -0.33632,0.20489 -0.50152,0.31068 -3.46803,1.83238 -6.64163,4.83846 -8.9265,8.79597 L 149.3802,581.32449 c -1.6698,2.89218 -2.66186,5.942 -3.01901,8.90436 -0.0972,0.63442 -0.15343,1.27896 -0.15343,1.93506 0,0.0717 0.006,0.14227 0.007,0.21374 -0.0963,5.80318 2.31129,11.01809 6.93341,13.68667 2.80598,1.62003 6.01719,2.06551 9.22115,1.49768 1.09798,0.15203 2.22613,0.23511 3.38007,0.23511 l 364.02986,0 c 1.15394,0 2.28208,-0.0831 3.38006,-0.23511 3.20397,0.56784 6.41517,0.12236 9.22115,-1.49768 4.62213,-2.66858 7.02968,-7.88349 6.93342,-13.68667 10e-4,-0.0715 0.007,-0.14204 0.007,-0.21374 0,-0.65241 -0.0551,-1.29339 -0.15114,-1.92438 -0.35605,-2.9657 -1.34949,-6.01938 -3.0213,-8.91504 L 364.13287,266.06517 c -2.28487,-3.95751 -5.45847,-6.96359 -8.9265,-8.79597 -0.1652,-0.10579 -0.33023,-0.21179 -0.50151,-0.31068 -2.13906,-1.23499 -4.51373,-1.78539 -6.94105,-1.72667 -0.0333,-8.1e-4 -0.0667,-0.004 -0.1,-0.005 z m 0.1,45.01872 159.51359,276.28473 -319.0264,0 159.51281,-276.28473 z"
style="opacity:0.5;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
id="text4409"
style="font-style:normal;font-weight:normal;font-size:278.96676636px;line-height:125%;font-family:sans-serif;letter-spacing:-54.46826553px;word-spacing:0px;opacity:0.5;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
id="path4414"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:278.96676636px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;letter-spacing:-54.46826553px;word-spacing:0px;opacity:0.5;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 360.21586,429.25521 q 0,20.10017 -1.49418,36.61102 -1.49418,16.27157 -3.73546,32.54313 l -14.4438,0 q -2.24128,-16.27156 -3.73546,-32.54313 -1.49419,-16.51085 -1.49419,-36.61102 l 0,-44.98609 24.90309,0 0,44.98609 z m 4.23352,107.91877 q 0,6.46077 -4.48255,11.24653 -4.48255,4.78575 -12.20252,4.78575 -7.71995,0 -12.20251,-4.78575 -4.48255,-4.78576 -4.48255,-11.24653 0,-6.46076 4.48255,-11.24652 4.48256,-4.78576 12.20251,-4.78576 7.71997,0 12.20252,4.78576 4.48255,4.78576 4.48255,11.24652 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
viewBox="0 0 512.00001 512.00001"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="logo.svg"
inkscape:export-filename="/home/skylar/Documents/Projects/Sources/WebAppTemplate/static/img/logo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="-493.3276 : 245.89848 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="464.45088 : 245.89848 : 1"
inkscape:persp3d-origin="-14.438371 : 160.56515 : 1"
id="perspective4236" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="-135.9681"
inkscape:cy="352.66131"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-540.36216)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.74509804"
id="rect4726"
width="512"
height="512"
x="0"
y="540.36218"
rx="50"
ry="50" />
<path
id="path4348"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:9.87128067;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 132.93564,682.51771 213.96788,-43.14304 0,313.97496 -213.96788,-37.9643 z m 213.96788,-43.14304 0,313.97496 32.16084,-45.18373 0,-217.44396 z m -213.96788,43.14304 213.96788,-43.14304 32.16084,51.34727 -167.21823,22.47784 z m 78.91049,30.68207 167.21823,-22.47784 0,217.44396 -167.21823,-19.77968 z m -78.91049,-30.68207 0,232.86762 78.91049,-26.99911 0,-175.18644 z m 0,232.86762 213.96788,37.9643 32.16084,-45.18373 -167.21823,-19.77968 z"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
viewBox="0 0 403.11274 163.29169"
height="163.29169"
width="403.11276"
inkscape:version="0.91 r13725"
sodipodi:docname="noaccounts.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="842"
id="namedview4274"
showgrid="false"
inkscape:zoom="1.1913066"
inkscape:cx="111.56795"
inkscape:cy="18.120005"
inkscape:window-x="1024"
inkscape:window-y="156"
inkscape:window-maximized="1"
inkscape:current-layer="g4375"
fit-margin-top="20"
fit-margin-bottom="20"
fit-margin-left="88.539"
fit-margin-right="88.539" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="fill:#ffffff"
id="g4375"
transform="matrix(10.274307,0,0,10.274307,94.587448,-48.471738)">
<path
id="path4365"
d="M 0,0 24,0 24,24 0,24 Z"
inkscape:connector-curvature="0"
style="fill:none" />
<path
id="path4467"
d="m 7.9464545,12.664364 q -1.242192,0 -2.121099,-0.878908 -0.878907,-0.878908 -0.878907,-2.1210988 0,-1.24219 0.878907,-2.121099 0.878907,-0.878909 2.121099,-0.878909 1.242191,0 2.1210985,0.878909 0.878907,0.878909 0.878907,2.121099 0,1.2421908 -0.878907,2.1210988 -0.8789075,0.878908 -2.1210985,0.878908 z m 8.4140785,2.500007 1.945322,1.945316 q 0.07031,0.07032 0.07031,0.179689 0,0.101563 -0.07031,0.171875 l -1.062505,1.062503 q -0.07031,0.07032 -0.171874,0.07032 -0.109379,0 -0.179687,-0.07032 l -1.945322,-1.945317 -1.945313,1.945317 q -0.07031,0.07032 -0.179688,0.07032 -0.101566,0 -0.171874,-0.07032 l -1.062504,-1.062503 q -0.07031,-0.07032 -0.07031,-0.171875 0,-0.109375 0.07031,-0.179689 l 1.945314,-1.945316 -1.945314,-1.945318 q -0.07031,-0.07032 -0.07031,-0.179687 0,-0.101563 0.07031,-0.171876 l 1.062504,-1.062502 q 0.07031,-0.07032 0.171874,-0.07032 0.109372,0 0.179688,0.07032 l 1.945313,1.945316 1.945322,-1.945316 q 0.07031,-0.07032 0.179687,-0.07032 0.101559,0 0.171874,0.07032 l 1.062505,1.062502 q 0.07031,0.07032 0.07031,0.171876 0,0.109374 -0.07031,0.179687 z m -3.890628,0 -1.414073,1.414066 q -0.289059,0.289063 -0.289059,0.710939 0,0.414064 0.289059,0.703126 l 0.64844,0.64844 q -0.164061,0.02344 -0.343748,0.02344 l -6.8281395,0 q -0.94532,0 -1.515632,-0.539064 -0.570313,-0.539064 -0.570313,-1.484378 0,-0.414064 0.02737,-0.808596 0.02737,-0.394533 0.10938,-0.851565 0.08203,-0.457032 0.207028,-0.847658 0.125005,-0.390626 0.335943,-0.761721 0.210938,-0.371094 0.484372,-0.632814 0.27344,-0.261719 0.667968,-0.41797 0.394536,-0.15625 0.871102,-0.15625 0.148436,0 0.304685,0.132812 1.203127,0.953128 2.492196,0.953128 1.289061,0 2.4921955,-0.953128 0.156248,-0.132812 0.304684,-0.132812 0.218751,0 0.445315,0.04688 -0.218751,0.210937 -0.320317,0.390625 -0.101559,0.179688 -0.101559,0.437502 0,0.421876 0.289059,0.710938 z"
inkscape:connector-curvature="0"
style="opacity:0.5;fill:#000000;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
viewBox="0 0 403.11274 163.29169"
height="163.29169"
width="403.11276"
inkscape:version="0.91 r13725"
sodipodi:docname="nokeys.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="842"
id="namedview4274"
showgrid="false"
inkscape:zoom="1.6847619"
inkscape:cx="193.17345"
inkscape:cy="81.645645"
inkscape:window-x="1024"
inkscape:window-y="1024"
inkscape:window-maximized="1"
inkscape:current-layer="g4375"
fit-margin-top="20"
fit-margin-bottom="20"
fit-margin-left="88.539"
fit-margin-right="88.539" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="fill:#ffffff"
id="g4375"
transform="matrix(10.274307,0,0,10.274307,94.587448,-48.471738)">
<path
id="path4365"
d="M 0,0 24,0 24,24 0,24 Z"
inkscape:connector-curvature="0"
style="fill:none" />
<path
id="path4367"
d="m 11.061302,10.664366 c -0.82,-2.3300004 -3.0399999,-4.0000004 -5.6499999,-4.0000004 -3.31,0 -6,2.69 -6,6.0000004 0,3.31 2.69,6 6,6 2.61,0 4.8299999,-1.67 5.6499999,-4 l 4.35,0 0,4 4,0 0,-4 2,0 0,-4 -10.35,0 z m -5.6499999,4 c -1.1,0 -2,-0.9 -2,-2 0,-1.1 0.9,-2 2,-2 1.1,0 2,0.9 2,2 0,1.1 -0.9,2 -2,2 z"
inkscape:connector-curvature="0"
style="opacity:0.5;fill:#000000;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

@ -2,50 +2,40 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public <!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this - License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html> <meta charset="utf-8">
<head> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
<title>Netsyms Business for Mobile</title> <meta name="apple-mobile-web-app-capable" content="yes">
<meta charset="UTF-8"> <meta name="theme-color" content="#2196f3">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="vendor/css/framework7.min.css">
<link rel="stylesheet" href="fonts/material.css">
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/font-awesome.min.css" /> <title>Netsyms Apps for Mobile</title>
<link rel="stylesheet" href="css/material-color.min.css" />
<link rel="stylesheet" href="css/app.css" /> <div id="app">
<script src="cordova.js"></script> <!-- <div class="statusbar"></div> -->
<script src="js/polyfills.js"></script>
<script src="js/jquery-3.2.1.min.js"></script> <div class="view view-main"></div>
<script src="js/bootstrap.min.js"></script>
<script src="js/accounts.js"></script> </div>
<script src="js/app.js"></script>
</head> <script src="cordova.js"></script>
<body>
<div id="modal-load-box" class="container" style='z-index: 1000;'> <script src="vendor/js/jquery-3.4.1.min.js"></script>
<script src="vendor/js/framework7.min.js"></script>
</div> <script src="vendor/js/fontawesome/fontawesome.min.js"></script>
<script src="vendor/js/fontawesome/solid.min.js"></script>
<nav class="navbar navbar-inverse navbar-fixed-top" id="navbar"> <script src="vendor/js/fontawesome/regular.min.js"></script>
<div class="container-fluid"> <script src="vendor/js/jsOTP.min.js"></script>
<div class="nav navbar-nav navbar-left" id="navbar-header"> <script src="js/polyfills.js"></script>
<span class="navbar-brand" id="navbar-title" style="color: white;">Business</span> <script src="js/material-palette.js"></script>
</div>
<ul class="nav navbar-nav navbar-right" id="navbar-buttons"> <script src="js/notifications.js"></script>
<script src="js/accounts.js"></script>
</ul> <script src="js/home.js"></script>
</div> <script src="js/otp.js"></script>
</nav> <script src="js/app.js"></script>
<script src="js/settings.js"></script>
<div id="content-zone" class="container" style="margin-top: 75px;">
<div class="app-dock-container"> <script src="routes.js"></script>
<div class="app-dock" id="app-dock"> <script src="js/main.js"></script>
<div style="margin-top: 50px;">
<img src="img/loader.gif" style="width: 65px; height: 65px;" alt=""/>
</div>
<div style="width: 100%;"></div>
<p class="loading-text">Loading...</p>
</div>
</div>
</div>
</body>
</html>

@ -30,15 +30,33 @@ function getaccounts() {
function saveaccounts(accounts) { function saveaccounts(accounts) {
localStorage.setItem("accounts", JSON.stringify(accounts)); localStorage.setItem("accounts", JSON.stringify(accounts));
NativeStorage.setItem("accounts", JSON.stringify(accounts));
}
function recoveraccounts(callback) {
NativeStorage.getItem("accounts", function (data) {
if (data == null || data == "" || data == "[]") {
callback(false);
return;
}
localStorage.setItem("accounts", data);
callback(true);
}, function () {
callback(false);
});
} }
/** /**
* Switch to a different account. * Switch to a different account.
* @param {int} account The selected account index from localStorage.getItem('accounts') * @param {int} account The selected account index from localStorage.getItem('accounts')
* @param {boolean} showmsg [HAS NO EFFECT] Whether to show the "switched accounts" alert dialog. Default True.
* @returns {undefined} * @returns {undefined}
*/ */
function switchaccount(account) { function switchaccount(account, showmsg) {
// If there isn't an accounts list yet, this shouldi take us back to the setup if (typeof showmsg != 'boolean') {
showmsg = true;
}
// If there isn't an accounts list yet, this should take us back to the setup
if (!isconfigvalid()) { if (!isconfigvalid()) {
restartApplication(); restartApplication();
} }
@ -53,10 +71,15 @@ function switchaccount(account) {
localStorage.setItem("syncurl", accountinfo['syncurl']); localStorage.setItem("syncurl", accountinfo['syncurl']);
localStorage.setItem("key", accountinfo['key']); localStorage.setItem("key", accountinfo['key']);
accountid = account; accountid = account;
restartApplication();
if (showmsg == true) {
//navigator.notification.alert("Successfully switched accounts.", null, "Switched", 'OK');
}
} }
/** /**
* Add a Business Apps account. * Add an Apps account.
* @param {String} username * @param {String} username
* @param {String} password * @param {String} password
* @param {String} url * @param {String} url
@ -71,7 +94,7 @@ function addaccount(username, password, url, key) {
} }
/** /**
* Remove a Business Apps account. * Remove an Apps account.
* @param {Number} Account index * @param {Number} Account index
*/ */
function rmaccount(id) { function rmaccount(id) {
@ -90,7 +113,6 @@ function rmaccount(id) {
* succeeds. * succeeds.
*/ */
function getuserinfo(callback) { function getuserinfo(callback) {
$(".loading-text").text("Loading account...");
if (localStorage.getItem("username") === null if (localStorage.getItem("username") === null
|| localStorage.getItem("password") === null || localStorage.getItem("password") === null
|| localStorage.getItem("syncurl") === null || localStorage.getItem("syncurl") === null
@ -104,18 +126,17 @@ function getuserinfo(callback) {
action: "user_info" action: "user_info"
}, function (data) { }, function (data) {
if (data.status === 'OK') { if (data.status === 'OK') {
$(".loading-text").text("Loading...");
userinfo = data.info; userinfo = data.info;
if (typeof callback == 'function') { if (typeof callback == 'function') {
callback(); callback();
} }
} else { } else {
router.navigate("/loaderror");
navigator.notification.alert(data.msg, null, "Error", 'Dismiss'); navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
openscreen("homeloaderror");
} }
}, "json").fail(function () { }, "json").fail(function () {
navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss'); navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss');
openscreen("homeloaderror"); router.navigate("/loaderror");
}); });
} }
@ -128,4 +149,51 @@ function passwd(newpass) {
var accounts = getaccounts(); var accounts = getaccounts();
accounts[accountid]["password"] = newpass; accounts[accountid]["password"] = newpass;
saveaccounts(accounts); saveaccounts(accounts);
}
function openAccountSwitcher(reload) {
if (typeof reload == 'undefined') {
reload = false;
}
var accounts = getaccounts();
var noaccounts = (accounts.length == 0);
for (var i = 0; i < accounts.length; i++) {
accounts[i]["id"] = i;
// Escape HTML characters
accounts[i]["username"] = $('<div/>').html(accounts[i]["username"]).html();
var synckey = accounts[i]["key"];
var stars = "";
for (var j = 0; j < synckey.length - 6; j++) {
stars += "*";
}
accounts[i]["synckey"] = $('<div/>').html(synckey.slice(0, 3) + stars + synckey.slice(-3)).html();
accounts[i]["syncurl"] = $('<div/>').html(accounts[i]["syncurl"].replace("/mobile/index.php", "")).html();
accounts[i]["showsyncurl"] = false;
accounts[i]["showtypestring"] = true;
if (accounts[i]["syncurl"].includes(".netsyms.biz")) {
accounts[i]["type"] = "Business";
accounts[i]["icon"] = "business";
} else if (accounts[i]["syncurl"].includes(".netsyms.com")) {
accounts[i]["type"] = "Personal";
accounts[i]["icon"] = "personal";
} else {
accounts[i]["type"] = "Self-hosted";
accounts[i]["icon"] = "selfhosted";
accounts[i]["showsyncurl"] = true;
accounts[i]["showtypestring"] = false;
}
if (localStorage.getItem("username") == accounts[i]['username']) {
accounts[i]["active"] = true;
}
}
router.navigate("/settings/accounts", {
context: {
accounts: accounts,
noaccounts: noaccounts
},
reloadCurrent: reload
});
} }

@ -27,7 +27,6 @@ $.cssHooks.backgroundColor = {
} }
} }
function openmenu() { function openmenu() {
if ($('#swipe-nav').css('display') == 'none') { if ($('#swipe-nav').css('display') == 'none') {
$('#swipe-shader').show("fade", {}, 300); $('#swipe-shader').show("fade", {}, 300);
@ -50,9 +49,8 @@ function togglemenu() {
} }
} }
$(document).ready(function () { $(document).ready(function () {
$.fx.off = __JQUERYFXOFF__;
var bootstrap_version = $.fn.tooltip.Constructor.VERSION;
if (typeof navbar_breakpoint != "undefined") { if (typeof navbar_breakpoint != "undefined") {
var nav_breakpoint = navbar_breakpoint; var nav_breakpoint = navbar_breakpoint;
} else { } else {
@ -66,15 +64,11 @@ $(document).ready(function () {
var logo = "__LOGO__"; var logo = "__LOGO__";
parent.postMessage("setcolor " + menucolor, "*"); parent.postMessage("setcolor " + menucolor, "*");
parent.postMessage('load_bs_version ' + bootstrap_version + ' ' + nav_breakpoint, '*'); parent.postMessage("load_css " + nav_breakpoint, "*");
if (bootstrap_version.startsWith("4")) { pages = pages.replace(/\s?py-[a-z]{2}-0/g, ""); // Issue #12
pages = pages.replace(/\s?py-[a-z]{2}-0/g, ""); // Issue #12 $('#navbar-right').html("<span class='nav-item py-" + nav_breakpoint + "-0'><a class='nav-link py-" + nav_breakpoint + "-0' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span>");
$('#navbar-right').html("<span class='nav-item py-" + nav_breakpoint + "-0'><a class='nav-link py-" + nav_breakpoint + "-0' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span>"); body.append("<div id='swipe-nav'><div id='swipe-header' style='background-color: " + menucolor + "; color: " + textcolor + "'><a href='./app.php'><img id='swipe-appicon' src='" + logo + "' /></a> <div id='swipe-username'><i class='fa fa-user fa-fw'></i> " + username + "</div></div>\n<div id='swipe-pages' class='swipe-list'>" + pages + "</div><div class='swipe-list'><span class='nav-item'><a class='nav-link' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span></div></div>");
body.append("<div id='swipe-nav'><div id='swipe-header' style='background-color: " + menucolor + "; color: " + textcolor + "'><a href='./app.php'><img id='swipe-appicon' src='" + logo + "' /></a> <div id='swipe-username'><i class='fa fa-user fa-fw'></i> " + username + "</div></div>\n<div id='swipe-pages' class='swipe-list'>" + pages + "</div><div class='swipe-list'><span class='nav-item'><a class='nav-link' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span></div></div>");
} else {
body.append("<div id='swipe-nav'><div id='swipe-header' style='background-color: " + menucolor + "; color: " + textcolor + "'><a href='./app.php'><img id='swipe-appicon' src='" + logo + "' /></a> <div id='swipe-username'><i class='fa fa-user fa-fw'></i> " + username + "</div></div>\n<ul id='swipe-pages'>" + pages + "</ul><ul><li><a onclick='quitapp()'><i class='fa fa-sign-out fa-fw'></i> Back to Menu</a></li></ul></div>");
}
body.append("<div id='swipe-shader'></div>"); body.append("<div id='swipe-shader'></div>");
$(".navbar-brand").attr("href", "#"); $(".navbar-brand").attr("href", "#");
@ -97,6 +91,7 @@ $(document).ready(function () {
closemenu(); closemenu();
}); });
window.addEventListener('message', function (event) { window.addEventListener('message', function (event) {
if (event.data.startsWith("coderesult~|~")) { if (event.data.startsWith("coderesult~|~")) {
var data = event.data.split("~|~"); var data = event.data.split("~|~");
@ -118,6 +113,8 @@ $(document).ready(function () {
console.log("app: keepalive ping " + d.status); console.log("app: keepalive ping " + d.status);
}); });
}, 1000 * 60); }, 1000 * 60);
parent.postMessage('done_loading', '*');
}); });
function quitapp() { function quitapp() {

@ -1,244 +1,154 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
/**
* Switches the app to the given screen.
* @param {String} screenname The name of the screen to show.
* @param {String} effect FADE, SLIDE, or nothing
* @returns {undefined}
*/ */
function openscreen(screenname, effect) {
if (effect === 'FADE') {
$('#content-zone').fadeOut(300, function () {
$('#content-zone').load("views/" + screenname + ".html", function () {
$('#content-zone').fadeIn(300);
});
});
} else if (effect === 'SLIDE') {
$('#content-zone').slideToggle('400', function () {
$('#content-zone').load("views/" + screenname + ".html", function () {
$('#content-zone').slideToggle('400');
});
});
} else {
$('#content-zone').load("views/" + screenname + ".html");
}
currentscreen = screenname;
}
function openfragment(fragment, target, effect) {
if (effect === 'FADE') {
$(target).fadeOut('slow', function () {
$(target).load("views/" + fragment + ".html", function () {
$(target).fadeIn('slow');
});
});
} else if (effect === 'SLIDE') {
$(target).slideToggle('400', function () {
$(target).load("views/" + fragment + ".html", function () {
$(target).slideToggle('400');
});
});
} else {
$(target).load("views/" + fragment + ".html");
}
}
/**
* Add button to the top navbar.
* @param String screenid openscreen(screenid)
* @param String icon The filename of the icon to show: <img src="icons/icon"...
* @param String title Text to show next to the icon on large screens.
* @returns {undefined}
*/
function addnavbarbtn(screenid, icon, title) {
$('#navbar-buttons').append('<li><a onclick="openscreen(\'' + screenid + '\', \'FADE\')"><img src="icons/' + icon + '" alt="" /> <span class="hidden-xs">' + title + '</span></a></li>');
}
/**
* Set the navbar options.
*
* @param String title Text to display
* @param boolean showarrow True if the back arrow should be visible
* @param Stringn backscreen The screen to open when the title is pressed, false or null for none
* @returns {undefined}
*/
function setnavbartitle(title, showarrow, backscreen) {
var arrow = "";
if (showarrow === true) {
arrow = '<img src="icons/ic_arrow-back.svg" />';
}
var onclick = "";
if (backscreen !== null && backscreen !== false) {
onclick = ' onclick=\'openscreen("' + backscreen + '", "FADE");\'';
}
$("#navbar-header").html('<span class="navbar-brand" id="navbar-title" style="color: white;"' + onclick + '>' + arrow + title + '</span>');
}
/**
* Set the navbar.
* @param {String,boolean} type false if no navbar, "home" for the home screen,
* "settings" for settings, "app" for a custom title, or anything else for
* a simple one.
* @param {String} screentitle The title to show if type == "app"
* @param {String} returnscreen Where to go back to. Defaults to "home".
* @returns {undefined}
*/
function setnavbar(type, screentitle, returnscreen) {
var navbar = $('#navbar-header');
var btns = $('#navbar-buttons');
if (type == false) {
$('#navbar').css('display', 'none');
$('#content-zone').css('margin-top', '0px');
} else {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
window.plugins.headerColor.tint("#2196f3");
} else {
StatusBar.backgroundColorByHexString("#2196f3");
}
$('#navbar').css('display', 'initial');
$('#content-zone').css('margin-top', '75px');
if (returnscreen === undefined) {
returnscreen = "home";
_returnscreen = null;
} else {
_returnscreen = returnscreen;
}
btns.html("");
switch (type) {
case "home":
setnavbartitle("Business", false, false);
addnavbarbtn("mobilecode", "ic_desktop_windows.svg", "Code Login");
addnavbarbtn("otp", "ic_vpn_key.svg", "2-factor Auth");
addnavbarbtn("settings", "ic_settings.svg", "Settings");
break;
case "setup":
setnavbartitle("Business", false, false);
addnavbarbtn("otp", "ic_vpn_key.svg", "2-factor Auth");
addnavbarbtn("settings", "ic_settings.svg", "Settings");
break;
case "settings":
setnavbartitle("Settings", true, "home");
break;
case "otp":
setnavbartitle("Auth Keys", true, "home");
break;
case "app":
setnavbartitle(screentitle, true, returnscreen);
break;
default:
setnavbartitle("Business", false, false);
break;
}
}
}
/**
* Thanks to https://stackoverflow.com/a/13542669
* @param {type} color
* @param {type} percent
* @returns {String}
*/
function shadeColor2(color, percent) {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
}
var historyctr = -1;
/** /**
* Load the app.html view and open an app with native Android UI elements * Open an app with native Android UI elements
* @param String id Application ID
* @param String api Path to the mobile API * @param String api Path to the mobile API
* @param String url Base URL of the app * @param String url Base URL of the app
* @param String icon URL to the app icon * @param String icon URL to the app icon
* @param String title Friendly app name * @param String title Friendly app name
* @param boolean injectcode (optional, default true) Whether or not to inject UI modification code into the app
* @param boolean shownavbar (optional, default false) Whether or not to show the navbar at the top of the screen.
* @returns {undefined} * @returns {undefined}
*/ */
function openapp(id, api, url, icon, title, injectcode, shownavbar) { function launchapp(api, url, icon, title) {
$('#content-zone').fadeOut(300, function () { app.dialog.progress("Loading...").setText(title);
$('#content-zone').load("views/app.html", function () {
$('#content-zone').fadeIn(300, function () { router.navigate({
launchapp(id, api, url, icon, title, injectcode, shownavbar); name: 'app'
});
$.post(url + api, {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "start_session"
}, function (data) {
if (data.status === 'OK') {
$('#appframe').on("load", function () {
app.dialog.close();
historyctr++;
// Do this right away so it's a bit harder to glitch
$('#appframe').contents().find('.navbar-right').html("<li><a onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></li>");
$.get("js/polyfills.js", function (script) {
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
$.get("vendor/js/jquery-ui.min.js", function (script) {
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
$.get("vendor/js/hammer.min.js", function (script) {
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
$.get("js/app-inject.js", function (script) {
script = script.replace("__USERNAME__", userinfo.realname);
script = script.replace("__LOGO__", icon);
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
});
});
});
});
}); });
}); $('#appframe').attr('src', url);
} else {
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
router.back();
}
}, "json").fail(function () {
navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss');
router.back();
}); });
} }
/** function navigateApp(src) {
* Opens a modal dialog over the top of everything else. $('#appframe').attr('src', './' + src);
* @param {String} filename views/[filename].html
* @param {String} modalselector [#id-of-the-modal]
* @returns {undefined}
*/
function openmodal(filename, modalselector) {
$('#modal-load-box').load("views/" + filename + ".html", null, function (x) {
$(modalselector).css('z-index', 9999999);
$(modalselector).modal('show');
});
} }
/** var scanningactive = false;
* Close a modal (see openmodal) var dedup = [];
* @param {String} modalselector window.addEventListener('message', function (event) {
* @returns {undefined} console.log("app event: " + event.data);
*/
function closemodal(modalselector) {
$(modalselector).modal('hide');
}
function restartApplication() {
navigator.splashscreen.show();
// We're doing the timeout so we don't run afoul of server-side rate limiting
setTimeout(function () { setTimeout(function () {
window.location = "index.html"; dedup = [];
}, 3000); }, 500);
} if (dedup.includes(event.data)) {
return;
// Handle back button to close things }
document.addEventListener("backbutton", function (event) { dedup.push(event.data);
if (isconfigvalid()) { if (event.data == "quit") {
if ($("#appframe").length && historyctr > 0) { router.back();
console.log("going back"); if (cordova.platformId == 'android') {
var iframe = document.getElementById("appframe"); StatusBar.backgroundColorByHexString("#1976d2");
iframe.contentWindow.postMessage("goback", "*");
historyctr--;
} else if (_returnscreen != null) {
openscreen(_returnscreen, "FADE");
_returnscreen = null;
} else { } else {
openscreen("home", "FADE"); StatusBar.backgroundColorByHexString("#2196f3");
}
} else {
if (_returnscreen != null) {
openscreen(_returnscreen, "FADE");
_returnscreen = null;
} }
} } else if (event.data == "done_loading") {
}, false); app.dialog.close();
} else if (event.data == "goneback") {
document.addEventListener("deviceready", function () { historyctr -= 1;
if (cordova.platformId == 'android') { } else if (event.data.startsWith("load_css ")) {
StatusBar.backgroundColorByHexString("#1976d2"); var nav_breakpoint = event.data.split(" ", 2)[1];
} $.get("css/app-inject.css", function (style) {
var break_px = "767";
// Enable/disable jQuery animations depending on user preference switch (nav_breakpoint) {
$.fx.off = !(localStorage.getItem("animations") === null || localStorage.getItem("animations") === "true"); case "sm":
break_px = "575";
/* Fade out alerts */ break;
$(".alert .close").click(function (e) { case "md":
$(this).parent().fadeOut("slow"); break_px = "767";
}); break;
case "lg":
if (isconfigvalid()) { break_px = "991";
getuserinfo(function () { break;
openscreen("home"); case "xl":
break_px = "1199";
break;
}
style = style.replace("max-width: 767px", "max-width: " + break_px + "px");
$('#appframe').contents().find('head').append("<style>" + style + "</style>");
}); });
} else { } else if (event.data.startsWith("setcolor ")) {
openscreen("setup1"); var color = event.data.split(" ", 2)[1];
if (cordova.platformId == 'android') {
window.plugins.headerColor.tint(color);
for (var swatch in _PALETTE) {
if (color == _PALETTE[swatch]["shade_500"]) {
StatusBar.backgroundColorByHexString(_PALETTE[swatch]["shade_700"]);
return;
}
}
StatusBar.backgroundColorByHexString(shadeColor2(color, -0.1));
} else {
StatusBar.backgroundColorByHexString(color);
}
} else if (event.data.startsWith("scancode ")) {
var callbackcode = event.data.split(" ").slice(1).join(" ");
console.log("got scancode " + callbackcode);
try {
if (scanningactive) {
console.log("Scanner already active, ignoring request.");
return;
}
scanningactive = true;
cordova.plugins.barcodeScanner.scan(
function (result) {
scanningactive = false;
if (!result.cancelled) {
var iframe = document.getElementById("appframe");
iframe.contentWindow.postMessage("coderesult~|~" + callbackcode + "~|~" + result.text, "*");
}
},
function (error) {
scanningactive = false;
navigator.notification.alert("Scanning failed: " + error, null, "Error", 'Dismiss');
},
{
"showFlipCameraButton": true,
"prompt": "Scan Code"
}
);
} catch (ex) {
scanningactive = false;
navigator.notification.alert(ex.message, null, "Error", 'Dismiss');
}
} }
setTimeout(navigator.splashscreen.hide, 500);
}, false); }, false);

File diff suppressed because one or more lines are too long

@ -0,0 +1,116 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function loadHomePage(reload) {
if (typeof reload == 'undefined') {
reload = false;
}
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
action: "listapps"
}, function (data) {
if (data.status === 'OK') {
if (!reload) {
loadingProgressDialog.setProgress(70);
}
var appcards = [];
Object.keys(data.apps).forEach(function (k) {
var app = data.apps[k];
var iconurl = app.icon;
if (!app.icon.startsWith("http")) {
iconurl = app.url + app.icon;
}
if (!app.card) {
return;
}
appcards.push({
api: app.mobileapi,
url: app.url,
icon: iconurl,
title: app.title,
text: app.card.string,
color: app.card.color
});
});
if (!reload) {
loadingProgressDialog.setProgress(80);
loadingProgressDialog.setText('Notifications');
}
getNotifications(function (notifs) {
notifications = [];
if (notifs != false) {
Object.keys(notifs).forEach(function (k) {
var notif = notifs[k];
if (!notif.seen) {
notifications.push(notif);
}
});
}
if (notifications == []) {
notifications = false;
}
if (reload) {
// Make it seem like it's doing something on fast connections
setTimeout(function () {
app.ptr.done();
router.navigate("/home", {
context: {
appcards: appcards,
notifications: notifications,
unreadnotifications: (notifications != false && notifications != []),
homeloaded: true
},
reloadCurrent: true
});
}, 500);
} else {
loadingProgressDialog.setText('Home');
loadingProgressDialog.setProgress(90);
router.navigate("/home", {
context: {
appcards: appcards,
notifications: notifications,
unreadnotifications: (notifications != false && notifications != []),
homeloaded: true
}
});
$(".view-main").on("click", "#applist .applist-item", function () {
launchapp($(this).data("api"), $(this).data("url"), $(this).data("icon"), $(this).data("title"));
});
loadingProgressDialog.setProgress(100);
loadingProgressDialog.close();
}
});
} else {
if (reload) {
app.ptr.done();
return;
}
loadingProgressDialog.close();
app.dialog.alert(data.msg, "Error", function () {
restartApplication();
});
}
}, "json").fail(function () {
loadingProgressDialog.close();
app.dialog.alert("Could not connect to the server. Try again later.", "Error", function () {
restartApplication();
});
});
}
$(".view-main").on("ptr:refresh", ".ptr-content", function () {
loadHomePage(true);
});
$(".view-main").on("swipeout:deleted", ".notificationlist-item", function () {
var id = $(this).data("id");
deleteNotification(id);
});

File diff suppressed because one or more lines are too long

@ -0,0 +1,148 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var $$ = Dom7;
var shown_notifications = [];
var app = new Framework7({
root: "#app",
name: "Netsyms",
id: "com.netsyms.BusinessMobile",
routes: routes,
dialog: {
buttonOK: "Dismiss"
}
});
var mainView = app.views.create('.view-main', {
url: "/"
});
var router = mainView.router;
var loadingProgressDialog;
/**
* Thanks to https://stackoverflow.com/a/13542669
* @param {type} color
* @param {type} percent
* @returns {String}
*/
function shadeColor2(color, percent) {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
}
/**
* Load the app.html view and open an app with nativeish Android UI elements
* @param String id Application ID
* @param String api Path to the mobile API
* @param String url Base URL of the app
* @param String icon URL to the app icon
* @param String title Friendly app name
* @param boolean injectcode (optional, default true) Whether or not to inject UI modification code into the app
* @param boolean shownavbar (optional, default false) Whether or not to show the navbar at the top of the screen.
* @returns {undefined}
*/
function openapp(id, api, url, icon, title, injectcode, shownavbar) {
$('#content-zone').fadeOut(300, function () {
$('#content-zone').load("views/app.html", function () {
$('#content-zone').fadeIn(300, function () {
launchapp(id, api, url, icon, title, injectcode, shownavbar);
});
});
});
}
function restartApplication() {
navigator.splashscreen.show();
// We're doing the timeout so we don't run afoul of server-side rate limiting
setTimeout(function () {
window.location = "index.html";
}, 3000);
}
// Handle back button to close things
document.addEventListener("backbutton", function (event) {
if (isconfigvalid()) {
if ($("#appframe").length && historyctr > 0) {
console.log("going back");
var iframe = document.getElementById("appframe");
iframe.contentWindow.postMessage("goback", "*");
historyctr--;
} else {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
} else {
StatusBar.backgroundColorByHexString("#2196f3");
}
router.back();
}
} else {
router.back();
}
}, false);
document.addEventListener("deviceready", function () {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
StatusBar.styleLightContent();
}
if (isconfigvalid()) {
loadingProgressDialog = app.dialog.progress('Loading...', 0);
loadingProgressDialog.setText('');
loadingProgressDialog.setProgress(20);
loadingProgressDialog.setText('Account');
getuserinfo(function () {
loadingProgressDialog.setProgress(50);
loadingProgressDialog.setText('Notifications');
// Setup notification sync
initNotifications();
loadingProgressDialog.setProgress(60);
// Load homepage/dashboard
loadingProgressDialog.setText('Apps');
loadHomePage(false);
});
} else {
// Try to recover data from NativeStorage back to localStorage
recoveraccounts(function (ok) {
if (ok) {
// Success, restart app to reload from localStorage
restartApplication();
} else {
// No account data found, open setup
router.navigate({
name: 'setup0'
});
}
})
}
setTimeout(navigator.splashscreen.hide, 500);
}, false);
router.on("pageBeforeIn", function (pagedata) {
app.progressbar.hide();
});
router.on("pageInit", function (pagedata) {
pagedata.$el.find('script').each(function (el) {
if ($$(this).attr('src')) {
var s = document.createElement('script');
s.src = $$(this).attr('src');
$$('head').append(s);
} else {
eval($$(this).text());
}
});
app.progressbar.hide();
switch (pagedata.name) {
case "settings":
updateSettingsData();
break;
}
});

@ -0,0 +1,140 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function getNotifications(callback) {
var notifications = [];
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
action: "checknotifications"
}, function (data) {
if (data.status === 'OK') {
for (var i = 0; i < data.notifications.length; i++) {
var n = data.notifications[i];
notifications.push({
id: n.id,
title: n.title,
text: n.content,
sensitive: n.sensitive,
seen: n.seen
});
}
callback(notifications);
return;
}
if (typeof callback == 'function') {
callback(false);
}
}, "json").fail(function () {
if (typeof callback == 'function') {
callback(false);
}
});
}
function displayNotifications(callback) {
getNotifications(function (notifications) {
if (notifications != false) {
for (var i = 0; i < notifications.length; i++) {
var n = notifications[i];
if (n.seen || shown_notifications.includes(n.id)) {
continue;
}
cordova.plugins.notification.local.schedule([{
title: n.title,
text: n.text,
// actions: [
// {id: 'mark_read', title: "Mark Read"}
// ],
id: n.id,
lockscreen: !n.sensitive
}]);
shown_notifications.push(n.id);
}
if (typeof callback == 'function') {
callback();
}
return;
}
if (typeof callback == 'function') {
callback();
}
});
}
function deleteNotification(id) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "deletenotification",
id: id
});
}
function readNotification(id) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "readnotification",
id: id
});
}
function initForegroundNotifications() {
cordova.plugins.notification.local.setDefaults({
led: true,
color: '#2196F3',
vibrate: true,
smallIcon: "res://ic_notification"
});
cordova.plugins.notification.local.on("mark_read", function (notification) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "readnotification",
id: notification.id
});
});
setInterval(displayNotifications, 30 * 1000);
if (typeof cordova.plugins.notification.local.launchDetails === 'undefined') {
displayNotifications();
}
}
function initBackgroundNotifications() {
var BackgroundFetch = window.BackgroundFetch;
// Your background-fetch handler.
var fetchCallback = function () {
console.log('[js] BackgroundFetch event received');
displayNotifications(function () {
BackgroundFetch.finish();
});
};
var failureCallback = function (error) {
console.log('- BackgroundFetch failed', error);
};
BackgroundFetch.configure(fetchCallback, failureCallback, {
minimumFetchInterval: 1,
stopOnTerminate: false,
startOnBoot: true,
forceReload: false,
enableHeadless: true
});
}
function initNotifications() {
initForegroundNotifications();
initBackgroundNotifications();
}

@ -0,0 +1,196 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var totp = new jsOTP.totp();
function parseOTP(jsontext, reload) {
var keys = [];
if (jsontext !== null && jsontext != "") {
var keys = JSON.parse(jsontext || "[]");
if (keys.length > 0) {
//$("#nokeys").css("display", "none");
}
var tmpldata = [];
for (var i = 0; i < keys.length; i++) {
var code = totp.getOtp(keys[i]["secret"]);
// Escape HTML characters
var label = $('<div/>').html(keys[i]["label"]).html();
var issuer = $('<div/>').text(keys[i]["issuer"]).html();
tmpldata.push({
code: code,
secret: keys[i]["secret"],
label: label,
issuer: issuer,
index: i
});
}
router.navigate("/otp", {
context: {
otpcodes: tmpldata
},
reloadCurrent: (reload == true ? true : false)
});
setInterval(function () {
refreshCountdown();
refreshCodes();
}, 1000);
refreshCountdown();
}
}
function setProgressBar(percent) {
if (mainView.router.currentRoute.name == "otp") {
app.progressbar.show(percent, app.theme === 'md' ? 'yellow' : 'blue');
} else {
app.progressbar.hide();
}
}
function loadOTPPage(reload) {
var ls_text = localStorage.getItem("otp");
if (ls_text === null || ls_text == "") {
// Recover from NativeStorage
NativeStorage.getItem("otp", function (data) {
localStorage.setItem("otp");
parseOTP(data, reload);
}, function (error) {
parseOTP("[]", reload);
});
} else {
parseOTP(ls_text, reload);
}
}
function refreshCountdown() {
var percent = ((30 - ((new Date).getSeconds() % 30)) / 30) * 100;
setProgressBar(percent);
}
function refreshCodes() {
$(".otpcard").each(function () {
var code = totp.getOtp($(this).data("secret"));
$(".otpcode", this).text(code);
});
}
function deleteOTPCode(index) {
var label = $(".otpcard[data-index=" + index + "] .otplabel").text();
navigator.notification.confirm("Delete auth key? This cannot be undone, so make sure you don't need this key to login anymore!", function (result) {
if (result != 1) {
return;
}
var keys = JSON.parse(localStorage.getItem("otp"));
keys.splice(index, 1);
localStorage.setItem("otp", JSON.stringify(keys));
NativeStorage.setItem("otp", JSON.stringify(keys));
loadOTPPage(true);
}, "Delete " + label + "?");
}
function addOTPCode(key, label, issuer) {
if (key == "") {
navigator.notification.alert("Missing secret key.", null, "Error", 'Dismiss');
return;
}
key = key.toUpperCase();
/* Thanks to https://stackoverflow.com/a/27362880 for the regex */
if (!key.match(/^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?$/)) {
navigator.notification.alert("Secret key is not valid base32.", null, "Error", 'Dismiss');
return;
}
if (label == "") {
navigator.notification.alert("Missing label.", null, "Error", 'Dismiss');
return;
}
var ls_text = localStorage.getItem("otp");
var keys = [];
if (ls_text != null && ls_text != "") {
keys = JSON.parse(ls_text || "[]");
}
keys.push({"secret": key, "label": label, "issuer": issuer});
localStorage.setItem("otp", JSON.stringify(keys));
NativeStorage.setItem("otp", JSON.stringify(keys));
app.toast.create({
text: '2-factor key saved.',
closeButton: true,
}).open();
loadOTPPage(true);
}
function scanOTPCode() {
try {
cordova.plugins.barcodeScanner.scan(
function (result) {
if (!result.cancelled) {
try {
var url = decodeURI(result.text);
} catch (e) {
navigator.notification.alert("Could not decode OTP URI.", null, "Error", 'Dismiss');
return;
}
if (!url.startsWith("otpauth://")) {
navigator.notification.alert("Invalid OTP code. Try again.", null, "Error", 'Dismiss');
return;
}
if (!url.startsWith("otpauth://totp/")) {
navigator.notification.alert("Unsupported key type.", null, "Error", 'Dismiss');
return;
}
var stripped = url.replace("otpauth://totp/", "");
var params = stripped.split("?")[1].split("&");
var label = stripped.split("?")[0];
var secret = "";
var issuer = "";
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
if (param[0] == "secret") {
secret = param[1].toUpperCase();
} else if (param[0] == "issuer") {
issuer = param[1];
} else if (param[0] == "algorithm" && param[1].toLowerCase() != "sha1") {
navigator.notification.alert("Unsupported hash algorithm.", null, "Error", 'Dismiss');
return;
} else if (param[0] == "digits" && param[1] != "6") {
navigator.notification.alert("Unsupported digit count.", null, "Error", 'Dismiss');
return;
} else if (param[0] == "period" && param[1] != "30") {
navigator.notification.alert("Unsupported period.", null, "Error", 'Dismiss');
return;
}
}
try {
secret = decodeURIComponent(secret);
issuer = decodeURIComponent(issuer);
label = decodeURIComponent(label);
} catch (e) {
navigator.notification.alert("Could not decode OTP URI.", null, "Error", 'Dismiss');
return;
}
addOTPCode(secret, label, issuer);
}
},
function (error) {
navigator.notification.alert("Scanning failed: " + error, null, "Error", 'Dismiss');
},
{
"showFlipCameraButton": false,
"prompt": "Scan OTP QR code."
}
);
} catch (ex) {
navigator.notification.alert(ex.message, null, "Error", 'Dismiss');
}
}
function addManualOTP() {
var label = $("#addotp_sheetmodal #label").val();
var secret = $("#addotp_sheetmodal #secret").val().replace(/\s+/g, '');
app.sheet.close("#addotp_sheetmodal");
addOTPCode(secret, label, "");
}

@ -0,0 +1,138 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function deleteAllSettings() {
navigator.notification.confirm("Really wipe user data? You will need to resync the app with AccountHub to use it again. This will not delete 2-factor auth keys.", function (result) {
if (result != 1) {
return;
}
// Wipe localStorage
localStorage.removeItem("username");
localStorage.removeItem("password");
localStorage.removeItem("syncurl");
localStorage.removeItem("key");
localStorage.removeItem("accounts");
NativeStorage.remove("accounts", function () {
// force-reload app
navigator.notification.alert("All connection data and credentials erased.", function () {
restartApplication();
}, "App Reset", 'Continue');
});
}, "Are you sure?");
}
/**
* Prompts the user to enter their password, then checks the password and
* saves or displays an error.
* @returns {undefined}
*/
function updatePassword() {
navigator.notification.prompt("Re-enter your password.", function (results) {
if (results.buttonIndex == 1) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: results.input1,
action: "check_password"
}, function (data) {
if (data.status === 'OK') {
localStorage.setItem("password", results.input1);
passwd(results.input1);
navigator.notification.alert("Saved password updated.", function () {
// Reload app just to be safe
restartApplication();
}, "Success", 'Continue');
} else {
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
}
}, "json").fail(function () {
navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss');
});
}
}, "Update Password", ["Save", "Cancel"]);
}
function updateSettingsData() {
cordova.getAppVersion.getVersionNumber(function (version) {
$('#app_version').text(version);
});
cordova.getAppVersion.getPackageName(function (package) {
$('#app_package').text(package);
});
cordova.getAppVersion.getVersionCode(function (version) {
$('#app_version_code').text(version);
});
if (localStorage.getItem("username")) {
$("#username").text(localStorage.getItem("username"));
}
if (localStorage.getItem("key")) {
var key = localStorage.getItem("key");
var stars = "";
for (var i = 0; i < key.length - 6; i++) {
stars += "*";
}
$("#pairingkey").text(key.slice(0, 3) + stars + key.slice(-3));
}
if (localStorage.getItem("syncurl")) {
$("#syncurl").text(localStorage.getItem("syncurl").replace("/mobile/index.php", ""));
}
}
function getSettingsTemplateData() {
return [
{
setting: "userinfo",
title: '<i class="fa fa-user"></i> <span id="username">Not logged in</span>',
text: '<i class="fa fa-key"></i> Pairing Code: <span id="pairingkey">None</span><br /><i class="fa fa-server"></i> Server: <span id="syncurl">None</span>',
onclick: ""
},
{
setting: "accounts",
title: "Manage and switch accounts",
onclick: "openAccountSwitcher(false)"
},
{
setting: "updatepassword",
title: "Update Password",
text: "Enter your new password if you changed it from AccountHub.",
onclick: "updatePassword()"
},
{
setting: "deleteall",
title: "Disconnect All Accounts",
text: "Forget all account data for all connected accounts and open the setup tool.",
onclick: "deleteAllSettings()"
},
{
setting: "versions",
title: "Netsyms Apps for Mobile</span> v<span id=\"app_version\">2.x</span>",
text: "Copyright &copy; 2018 Netsyms Technologies. License: <span style=\"text-decoration: underline;\" onclick=\"window.open('https://source.netsyms.com/Business/MobileApp?pk_campaign=NetsymsMobile-SystemBrowser', '_system', '');\">Mozilla Public License 2.0</span>.",
onclick: ""
},
{
setting: "opensource",
title: "Open Source Information",
text: "",
onclick: "router.navigate('/credits')"
},
{
setting: "privacy",
title: "Privacy Policy",
text: "",
onclick: "cordova.InAppBrowser.open('https://netsyms.com/legal?pk_campaign=NetsymsMobile-SystemBrowser', '_blank', 'location=yes')"
}
];
}
function loadSettingsPage() {
router.navigate("/settings", {
context: {
settings: getSettingsTemplateData()
},
});
updateSettingsData();
}

@ -0,0 +1,196 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
setupusername = "";
setuppassword = "";
setupsynckey = "";
setupsyncurl = "";
netsymscomurl = "https://apps.netsyms.com/account/mobile/index.php";
netsymsbizurl = "https://BIZID.netsyms.biz/accounthub/mobile/index.php";
if (localStorage.getItem("firstrun") === null) {
$("#setuptitle").text("Setup");
$(".firstrun-only").css("display", "");
}
$('#use-security-checkbox-li').click(function () {
// Event fires before the checkbox is changed, so we need to do the opposite
if ($("#use-security").prop("checked")) {
$('#protocol-select').text("http://");
} else {
$('#protocol-select').text("https://");
}
});
/* Detect if the user typed "http[s]://" into the URL box and correct for it */
$("#syncurl").blur(function () {
if ($('#syncurl').val().toLowerCase().startsWith("https://")) {
$('#syncurl').val($('#syncurl').val().replace(/https\:\/\//ig, ""));
$('#protocol-select').text("https://");
$('#use-security').prop('checked', true);
} else if ($('#syncurl').val().toLowerCase().startsWith("http://")) {
$('#syncurl').val($('#syncurl').val().replace(/http\:\/\//ig, ""));
$('#protocol-select').text("http://");
$('#use-security').prop('checked', false);
}
});
$("#key").on("keyup", function () {
if (window.getSelection().toString() !== '') {
return;
}
var text = $('#key').val().replace(/\s+/g, '');
var formatted = "";
for (var i = 1; i <= text.length; i++) {
formatted = formatted + text[i - 1];
if (i % 5 == 0 && i > 1 && i < text.length) {
// add a space every 5 characters,
// unless it's the first character
// or the last character
formatted = formatted + " ";
}
}
$('#key').val(formatted.toUpperCase());
});
$('#username').on("keyup", function () {
$('#username').val($('#username').val().toLowerCase());
});
function manualsetup() {
if ($('#syncurl').val().toLowerCase().startsWith("http")) {
var syncurl = $('#syncurl').val();
} else {
var syncurl = $('#protocol-select').text() + $('#syncurl').val();
}
var username = $('#username').val();
var key = $('#key').val().replace(/\s+/g, '');
checkAndSave(syncurl, username, key);
}
function manualshow() {
$('#manual_setup').css('display', 'block');
}
function checkAndSave(syncurl, username, key) {
app.preloader.show();
$.post(syncurl, {
username: username,
key: key,
action: "check_key"
}, function (data) {
app.preloader.hide();
if (data.status === 'OK') {
setupusername = username;
setupsyncurl = syncurl;
setupsynckey = key;
router.navigate({
name: 'setup2'
});
} else {
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
}
}, "json").fail(function () {
app.preloader.hide();
navigator.notification.alert("Could not connect to the server. Try again.", null, "Error", 'Dismiss');
});
}
function personalsetup() {
app.preloader.show();
var username = $("#personal_username").val();
var password = $("#personal_password").val();
$.post(netsymscomurl, {
username: username,
password: password,
key: "NOKEY",
desc: device.platform + " " + device.model + " " + device.serial,
action: "generatesynccode"
}, function (result) {
app.preloader.hide();
if (result.status == "OK") {
var code = result.code;
var accid = addaccount(username, password, netsymscomurl, code);
switchaccount(accid, false);
localStorage.setItem("firstrun", "1");
navigator.notification.alert("Account connected!", null, "Success", 'Continue');
restartApplication();
} else if (result.status == "ERROR") {
navigator.notification.alert(result.msg, null, "Error", 'Dismiss');
} else {
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
}
}, "json").fail(function () {
app.preloader.hide();
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
});
}
function businesssetup() {
app.preloader.show();
var username = $("#personal_username").val();
var password = $("#personal_password").val();
var url = netsymsbizurl.replace("BIZID", $("#bizid").val());
$.post(url, {
username: username,
password: password,
key: "NOKEY",
desc: device.platform + " " + device.model + " " + device.serial,
action: "generatesynccode"
}, function (result) {
app.preloader.hide();
if (result.status == "OK") {
var code = result.code;
var accid = addaccount(username, password, url, code);
switchaccount(accid, false);
localStorage.setItem("firstrun", "1");
navigator.notification.alert("Account connected!", null, "Success", 'Continue');
restartApplication();
} else if (result.status == "ERROR") {
navigator.notification.alert(result.msg, null, "Error", 'Dismiss');
} else {
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
}
}, "json").fail(function () {
app.preloader.hide();
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
});
}
function scanCode() {
try {
cordova.plugins.barcodeScanner.scan(
function (result) {
if (!result.cancelled) {
if (!result.text.startsWith("bizsync://")) {
navigator.notification.alert("Invalid sync code. Try again.", null, "Error", 'Dismiss');
return;
}
var url = result.text.replace("bizsync://", "");
var parts = url.split("/");
var syncurl = parts[0].replace(/\\/g, "/");
var username = parts[1];
var key = parts[2];
checkAndSave(syncurl, username, key);
}
},
function (error) {
navigator.notification.alert("Scanning failed: " + error, null, "Error", 'Dismiss');
},
{
"showFlipCameraButton": false,
"prompt": "Scan mobile sync QR code."
}
);
} catch (ex) {
navigator.notification.alert(ex.message, null, "Error", 'Dismiss');
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save