diff --git a/cache/timer.yaml b/cache/timer.yaml
index b69662f..89a2f7f 100644
--- a/cache/timer.yaml
+++ b/cache/timer.yaml
@@ -1 +1 @@
-licenseupdate: 1740428318
+licenseupdate: 1743303388
diff --git a/system/typemill/Models/ApiCalls.php b/system/typemill/Models/ApiCalls.php
index 815bc61..eb58354 100644
--- a/system/typemill/Models/ApiCalls.php
+++ b/system/typemill/Models/ApiCalls.php
@@ -45,7 +45,12 @@ class ApiCalls
}
$curl = curl_init($url);
+ if (defined('CURLSSLOPT_NATIVE_CA') && version_compare(curl_version()['version'], '7.71', '>='))
+ {
+ curl_setopt($curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
+ }
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 5);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if ($method === 'POST' && $data)
{
@@ -58,17 +63,19 @@ class ApiCalls
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($curl, CURLOPT_POST, true);
}
- curl_setopt($curl, CURLOPT_FAILONERROR, true);
+# curl_setopt($curl, CURLOPT_FAILONERROR, true);
$response = curl_exec($curl);
if ($response === false)
{
$this->error = curl_error($curl);
+ curl_close($curl);
+ return false;
}
- curl_close($curl);
- return $response !== false ? $response : false;
+ curl_close($curl);
+ return $response;
}
private function makeFileGetContentsCall($url, $method, $data = null, $authHeader = '')
@@ -108,9 +115,22 @@ class ApiCalls
if ($response === false)
{
- $this->error = 'file_get_contents failed for ' . $method . ' request.';
+ if (!empty($http_response_header) && isset($http_response_header[0]))
+ {
+ $parts = explode(' ', $http_response_header[0], 3);
+ $status_code = $parts[1] ?? 'Unknown';
+ $msg = $parts[2] ?? 'No status message';
+
+ $this->error = Translations::translate('We got an error from file_get_contents: ') . $status_code . ' ' . $msg;
+ }
+ else
+ {
+ $this->error = Translations::translate('No HTTP response received or file_get_contents is blocked.');
+ }
+
+ return false;
}
- return $response !== false ? $response : false;
+ return $response;
}
}
diff --git a/system/typemill/Models/License.php b/system/typemill/Models/License.php
index 9d1c74f..213a917 100644
--- a/system/typemill/Models/License.php
+++ b/system/typemill/Models/License.php
@@ -3,6 +3,7 @@
namespace Typemill\Models;
use Typemill\Models\StorageWrapper;
+use Typemill\Models\ApiCalls;
use Typemill\Static\Translations;
class License
@@ -108,7 +109,31 @@ class License
if(!$subscriptionPaid)
{
$storage = new StorageWrapper('\Typemill\Models\Storage');
- if(!$forceUpdateCheck && !$storage->timeoutIsOver('licenseupdate', 3600))
+ $timeoutIsOver = $storage->timeoutIsOver('licenseupdate', 3600);
+ $storageError = $storage->getError();
+
+ if($storageError)
+ {
+ $this->message = Translations::translate($storageError) . $this->message;
+
+ return false;
+ }
+
+ $backtrace = debug_backtrace();
+ $callingMethod = isset($backtrace[1]['function']) ? $backtrace[1]['function'] : 'Unknown';
+
+/*
+ echo '
method: ';
+ echo $callingMethod;
+ echo '
force: ';
+ var_dump($forceUpdateCheck);
+ echo '
timer: ';
+ var_dump($timeoutIsOver);
+
+ $forceUpdateCheck = false;
+*/
+
+ if(!$forceUpdateCheck && $timeoutIsOver === false)
{
$this->message = Translations::translate('The subscription period has not been paid yet. We will check it every 60 minutes.') . $this->message;
@@ -246,7 +271,7 @@ class License
# make remote check on the license server
$url = 'https://service.typemill.net/api/v1/licensecheck';
- $remoteCheck = $this->callLicenseServer($licensedata, $url);
+ $remoteCheck = $this->callLicenseServer($licensedata, $url, 'remoteCheck');
if(isset($remoteCheck['status']) && $remoteCheck['status'])
{
@@ -287,7 +312,7 @@ class License
ksort($licensedata);
# test manipulate data
- # $licensedata['plan'] = 'wrong';
+# $licensedata['plan'] = 'wrong';
# Check signature
$public_key_pem = $this->getPublicKeyPem();
@@ -331,7 +356,7 @@ class License
{
# make the call to the license server
$url = 'https://service.typemill.net/api/v1/testcall';
- $testcall = $this->callLicenseServer(['test' => 'test'], $url);
+ $testcall = $this->callLicenseServer(['test' => 'test'], $url, 'testLicensecall');
if(!$testcall)
{
@@ -354,7 +379,7 @@ class License
# make the call to the license server
$url = 'https://service.typemill.net/api/v1/activate';
- $signedLicense = $this->callLicenseServer($licensedata, $url);
+ $signedLicense = $this->callLicenseServer($licensedata, $url, 'activateLicense');
if(!$signedLicense)
{
@@ -391,7 +416,7 @@ class License
# make the call to the license server
$url = 'https://service.typemill.net/api/v1/update';
- $signedLicense = $this->callLicenseServer($licensedata, $url);
+ $signedLicense = $this->callLicenseServer($licensedata, $url, 'updateLicense');
if(!$signedLicense)
{
@@ -461,7 +486,7 @@ class License
$url = 'https://service.typemill.net/api/v1/gettoken';
- $tokenresponse = $this->callLicenseServer($licensedata, $url);
+ $tokenresponse = $this->callLicenseServer($licensedata, $url, 'getToken');
if($tokenresponse && isset($tokenresponse['token']) && $tokenresponse['token'])
{
@@ -473,14 +498,53 @@ class License
return false;
}
- private function callLicenseServer( $licensedata, $url )
+ private function callLicenseServer( $licensedata, $url, $from )
+ {
+ $authstring = $this->getPublicKeyPem();
+
+# echo '
license server call from: ' . $from;
+
+ if(!$authstring)
+ {
+ $this->message = Translations::translate('Please check if there is a readable file public_key.pem in your settings folder.');
+
+ return false;
+ }
+
+ $authstring = hash('sha256', substr($authstring, 0, 50));
+ $authHeader = "Authorization: " . $authstring;
+
+ $apiservice = new ApiCalls();
+ $apiResponse = $apiservice->makePostCall($url, $licensedata, $authHeader);
+
+ if (!$apiResponse)
+ {
+ $error = $apiservice->getError();
+ $this->message = 'ApiCallError: ' . Translations::translate($error);
+
+ return false;
+ }
+
+ $responseJson = json_decode($apiResponse, true);
+
+ if(isset($responseJson['code']))
+ {
+ $this->message = 'LicenseServerError: ' . $responseJson['code'];
+
+ return false;
+ }
+
+ return $responseJson;
+ }
+
+ private function callLicenseServerOld( $licensedata, $url )
{
$authstring = $this->getPublicKeyPem();
if(!$authstring)
{
$this->message = Translations::translate('Please check if there is a readable file public_key.pem in your settings folder.');
-
+
return false;
}
@@ -499,7 +563,8 @@ class License
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
- "Content-Type: application/x-www-form-urlencoded",
+# "Content-Type: application/x-www-form-urlencoded",
+ "Content-Type: application/json",
"Accept: application/json",
"Authorization: $authstring",
"Connection: close"
diff --git a/system/typemill/Models/Storage.php b/system/typemill/Models/Storage.php
index 63bcb26..54cf2e1 100644
--- a/system/typemill/Models/Storage.php
+++ b/system/typemill/Models/Storage.php
@@ -496,11 +496,15 @@ class Storage
$folder = '';
$filename = 'timer.yaml';
- // Get current timers from the YAML file, if it exists
- $timers = $this->getYaml($location, $folder, $filename) ?: [];
+ if(!$this->checkFolder('cacheFolder'))
+ {
+ return false;
+ }
- $currentTime = time();
- $timeThreshold = $currentTime - $timespan;
+ // Get current timers from the YAML file, if it exists
+ $currentTime = time();
+ $timeThreshold = $currentTime - $timespan;
+ $timers = $this->getYaml($location, $folder, $filename) ?: [];
# Check if the name exists and if the timestamp is older than the current time minus the timespan
if (!isset($timers[$name]) || !is_numeric($timers[$name]) || $timers[$name] <= $timeThreshold)
@@ -511,6 +515,11 @@ class Storage
# Update the YAML file with the new or updated timer
$this->updateYaml($location, $folder, $filename, $timers);
+ if($this->error)
+ {
+ return false;
+ }
+
return true;
}
diff --git a/system/typemill/author/js/vue-license.js b/system/typemill/author/js/vue-license.js
index 9294924..af4eb9e 100644
--- a/system/typemill/author/js/vue-license.js
+++ b/system/typemill/author/js/vue-license.js
@@ -111,7 +111,7 @@ const app = Vue.createApp({
self.disabled = false;
self.message = handleErrorMessage(error);
self.messageClass = 'bg-rose-500';
- self.licensemessage = error.response.data.message;
+ self.licensemessage = self.licensemessage + ' ' + error.response.data.message;
if(error.response.data.errors !== undefined)
{
self.errors = error.response.data.errors;