Skip to content

Commit

Permalink
Merge branch 'master' of github.com:freescout-helpdesk/freescout into…
Browse files Browse the repository at this point in the history
… dist
  • Loading branch information
freescout-help-desk committed Mar 8, 2024
2 parents 49af472 + 4021f07 commit 33639a8
Show file tree
Hide file tree
Showing 19 changed files with 512 additions and 268 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ If you want to support the project feel free to **star this repository**. It hel
* Multilingual: English, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, German, Italian, Japanese, Korean, Norwegian, Persian, Polish, Portuguese, Russian, Spanish, Slovak, Swedish, Turkish.
* Seamless email integration.
* Supports modern Microsoft Exchange authentication.
* Fully supports screen readers (for visually impaired).
* Built with strong focus on [security](https://freescout.net/security).
* Web installer & updater.
* Starred conversations.
* Forwarding conversations.
Expand Down
64 changes: 63 additions & 1 deletion app/Console/Commands/ModuleUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,74 @@ public function handle()
if (trim($update_result['output'])) {
$this->line(preg_replace("#\n#", "\n> ", '> '.trim($update_result['output'])));
}

$counter++;
}
}
}

// Loop through each installed module
foreach ($installed_modules as $module) {
// Skip if the module is an official one
if (\App\Module::isOfficial($module->get('authorUrl'))) {
continue;
}

// Get the URL for the latest version of the module
$latest_version_number_url = $module->get('latestVersionUrl');
if (! $latest_version_number_url) {
continue;
}

// Create a new Guzzle HTTP client
$client = new \GuzzleHttp\Client();

try {
// Send a GET request to the latest version URL
$response = $client->request('GET', $latest_version_number_url, \Helper::setGuzzleDefaultOptions());

// Get the latest version number from the response body
$latest_version = trim((string) $response->getBody());

if (empty($latest_version)) {
continue;
} else {
// Get the current version of the module
$current_version = $module->get('version');
}
} catch (\Exception $e) {
// If there's an exception, skip to the next iteration
continue;
}

// If the latest version is greater than the current version
if (version_compare($latest_version, $current_version, '>')) {
// Update the module
$update_result = \App\Module::updateModule($module->getAlias());

// Print the module name and status
$this->info('[' . $update_result['module_name'] . ' Module' . ']');
if ($update_result['status'] == 'success') {
// If the update was successful, print the success message
$this->line($update_result['msg_success']);
} else {
// If the update failed, print the error message
$msg = $update_result['msg'];
if ($update_result['download_msg']) {
$msg .= ' (' . $update_result['download_msg'] . ')';
}
$this->error('ERROR: ' . $msg);
}
// If there's any output from the update, print it
if (trim($update_result['output'])) {
$this->line(preg_replace("#\n#", "\n> ", '> ' . trim($update_result['output'])));
}

// Increment the counter
$counter ++;
}
}

if ($module_alias && !$found) {
$this->error('Module with the following alias not found: '.$module_alias);
} elseif (!$counter) {
Expand Down
16 changes: 13 additions & 3 deletions app/Conversation.php
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,12 @@ public static function getQueryByFolder($folder, $user_id)
if ($user->id == $user_id
&& $user->hasManageMailboxPermission($folder->mailbox_id, Mailbox::ACCESS_PERM_ASSIGNED)
) {
$query_conversations->where('user_id', '=', $user_id);
if ($folder->type != Folder::TYPE_DRAFTS) {
$query_conversations->where('user_id', '=', $user_id);
} else {
$query_conversations->where('user_id', '=', $user_id)
->orWhere('created_by_user_id', '=', $user_id);
}
}
}

Expand Down Expand Up @@ -2226,10 +2231,15 @@ public static function search($q, $filters, $user = null, $query_conversations =

if ($q) {
$query_conversations->where(function ($query) use ($like, $filters, $q, $like_op) {

// It needs to be sanitized to avoid "Numeric value out of range" on PostgreSQL.
$q_int = (int)$q;
$q_int = $q_int > \Helper::DB_INT_MAX ? \Helper::DB_INT_MAX : $q_int;

$query->where('conversations.subject', $like_op, $like)
->orWhere('conversations.customer_email', $like_op, $like)
->orWhere('conversations.'.self::numberFieldName(), (int)$q)
->orWhere('conversations.id', (int)$q)
->orWhere('conversations.'.self::numberFieldName(), $q_int)
->orWhere('conversations.id', $q_int)
->orWhere('customers.first_name', $like_op, $like)
->orWhere('customers.last_name', $like_op, $like)
->orWhere('threads.body', $like_op, $like)
Expand Down
11 changes: 7 additions & 4 deletions app/Http/Controllers/ConversationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,9 @@ public function ajax(Request $request)
$now = date('Y-m-d H:i:s');
$status_changed = false;
$user_changed = false;

$request_status = (int)$request->status;

if ($new) {
// New conversation
$conversation = new Conversation();
Expand All @@ -861,7 +864,7 @@ public function ajax(Request $request)
$conversation->source_type = Conversation::SOURCE_TYPE_WEB;
} else {
// Reply or note
if ((int) $request->status != (int) $conversation->status) {
if ($request_status && $request_status != (int)$conversation->status) {
$status_changed = true;
}
if (!empty($request->subject)) {
Expand Down Expand Up @@ -928,7 +931,7 @@ public function ajax(Request $request)

$prev_status = $conversation->status;

$conversation->status = $request->status;
$conversation->status = $request_status ?: $conversation->status;

if (($prev_status != $conversation->status || $is_create)
&& $conversation->status == Conversation::STATUS_CLOSED
Expand Down Expand Up @@ -1052,7 +1055,7 @@ public function ajax(Request $request)
$thread->first = true;
}
$thread->user_id = $conversation->user_id;
$thread->status = $request->status;
$thread->status = $request_status ?? $conversation->status;
$thread->state = Thread::STATE_PUBLISHED;
$thread->customer_id = $customer->id;
$thread->created_by_user_id = auth()->user()->id;
Expand Down Expand Up @@ -1346,7 +1349,7 @@ public function ajax(Request $request)
$new = true;
if (!$response['msg'] && !empty($request->conversation_id)) {
$conversation = Conversation::find($request->conversation_id);
if ($conversation && !$user->can('view', $conversation)) {
if ($conversation && !$user->can('view', $conversation) && !$user->hasManageMailboxPermission($request->mailbox_id, Mailbox::ACCESS_PERM_ASSIGNED)) {
$response['msg'] = __('Not enough permissions');
} else {
$new = false;
Expand Down
49 changes: 47 additions & 2 deletions app/Http/Controllers/ModulesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public function modules(Request $request)
'installed' => true,
'activated' => \App\Module::isLicenseActivated($module->getAlias(), $module->get('authorUrl')),
'license' => \App\Module::getLicense($module->getAlias()),
// Update configuration for third party modules
'latestVersionNumberUrl' => $module->get('latestVersionUrl'),
'latestVersionZipUrl' => $module->get('latestVersionZipUrl'),
// Determined later
'new_version' => '',
];
Expand Down Expand Up @@ -128,7 +131,7 @@ public function modules(Request $request)
$modules_directory[$i_dir]['active'] = \App\Module::isActive($dir_module['alias']);
$modules_directory[$i_dir]['activated'] = false;

// Do not show third-party modules in Modules Derectory.
// Do not show third-party modules in Modules Directory.
if (\App\Module::isThirdParty($dir_module)) {
$third_party_modules[] = $modules_directory[$i_dir];
unset($modules_directory[$i_dir]);
Expand All @@ -138,8 +141,50 @@ public function modules(Request $request)
$modules_directory = [];
}

// Loop through each installed module
foreach ($installed_modules as $i_installed => $module) {
// Check if the module is an official one
if (\App\Module::isOfficial($module['authorUrl'])) {
continue;
}

// Get the URL for the latest version of the module
$latest_version_number_url = $module['latestVersionNumberUrl'] ?? null;
if (! $latest_version_number_url) {
continue;
}

// Create a new Guzzle HTTP client
$client = new \GuzzleHttp\Client();

try {
// Send a GET request to the latest version URL
$response = $client->request('GET', $latest_version_number_url, \Helper::setGuzzleDefaultOptions());

// Get the latest version number from the response body
$latest_version = trim((string) $response->getBody());

if (empty($latest_version)) {
continue;
} else {
// Get the current version of the module
$current_version = $module['version'];
}
} catch (\Exception $e) {
// If there's an exception, skip to the next iteration
continue;
}

// If the latest version is greater than the current version
if (version_compare($latest_version, $current_version, '>')) {
// Update the installed module's version
$installed_modules[ $i_installed ]['new_version'] = $latest_version;
// Set the flag to indicate that updates are available
$updates_available = true;
}
}

// Check modules symlinks. Somestimes instead of symlinks folders with files appear.

$invalid_symlinks = \App\Module::checkSymlinks(
collect($installed_modules)->where('active', true)->pluck('alias')->toArray()
);
Expand Down
18 changes: 11 additions & 7 deletions app/Misc/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class Helper
*/
const DIR_PERMISSIONS = 0755;

const DB_INT_MAX = 2147483647;

public static $csp_nonce = null;

/**
Expand Down Expand Up @@ -518,19 +520,21 @@ public static function stripTags($text)
{
// Remove all kinds of spaces after tags.
// https://stackoverflow.com/questions/3230623/filter-all-types-of-whitespace-in-php
//
// Keep in mind that preg_replace() may return NULL if "u" flag is used.
$text = preg_replace("/^(.*)>[\r\n]*\s+/mu", '$1>', $text ?? '');

// Remove <script> and <style> blocks.
$text = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $text);
$text = preg_replace('#<style(.*?)>(.*?)</style>#is', '', $text);
$text = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $text ?? '');
$text = preg_replace('#<style(.*?)>(.*?)</style>#is', '', $text ?? '');

// Remove tags.
$text = strip_tags($text);
$text = preg_replace('/\s+/mu', ' ', $text);
$text = strip_tags($text ?? '');
$text = preg_replace('/\s+/mu', ' ', $text ?? '');

// Trim
$text = trim($text);
$text = preg_replace('/^\s+/mu', '', $text);
$text = trim($text ?? '');
$text = preg_replace('/^\s+/mu', '', $text ?? '');

// Causes "General error: 1366 Incorrect string value"
// Remove "undetectable" whitespaces
Expand All @@ -541,7 +545,7 @@ public static function stripTags($text)
// }
// $text = urldecode($text);

$text = trim(preg_replace('/[ ]+/', ' ', $text));
$text = trim(preg_replace('/[ ]+/', ' ', $text ?? ''));

return $text;
}
Expand Down
8 changes: 8 additions & 0 deletions app/Misc/Mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,14 @@ public static function getHashedReplySeparator($message_id) {
return $separator;
}

// Sanitize status message - remove SMTP username and password.
public static function sanitizeSmtpStatusMessage($status_message) {
$status_message = preg_replace('#(username ")[^"]+(")#', '$1***$2', $status_message ?? '');
$status_message = preg_replace("#(Swift_Transport_Esmtp_Auth_LoginAuthenticator\->authenticate\(Object\(Swift_SmtpTransport\), ')[^\']+(', ')[^\']+('\))#", '$1***$2***$3', $status_message ?? '');

return $status_message;
}

// public static function oauthGetProvider($provider_code, $params)
// {
// $provider = null;
Expand Down
Loading

0 comments on commit 33639a8

Please sign in to comment.